Convert specs to RSpec 2.99.2 syntax with Transpec
[puppet_vcsrepo.git] / spec / acceptance / clone_repo_spec.rb
1 require 'spec_helper_acceptance'
2
3 tmpdir = default.tmpdir('vcsrepo')
4
5 describe 'clones a remote repo' do
6   before(:all) do
7     my_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
8     shell("mkdir -p #{tmpdir}") # win test
9     scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir)
10     shell("cd #{tmpdir} && ./create_git_repo.sh")
11   end
12
13   after(:all) do
14     shell("rm -rf #{tmpdir}/testrepo.git")
15   end
16
17   context 'get the current master HEAD' do
18     it 'clones a repo' do
19       pp = <<-EOS
20       vcsrepo { "#{tmpdir}/testrepo":
21         ensure => present,
22         provider => git,
23         source => "file://#{tmpdir}/testrepo.git",
24       }
25       EOS
26
27       # Run it twice and test for idempotency
28       apply_manifest(pp, :catch_failures => true)
29       apply_manifest(pp, :catch_changes => true)
30     end
31
32     describe file("#{tmpdir}/testrepo/.git") do
33       it { is_expected.to be_directory }
34     end
35
36     describe file("#{tmpdir}/testrepo/.git/HEAD") do
37       it { is_expected.to contain 'ref: refs/heads/master' }
38     end
39   end
40
41   context 'using a commit SHA' do
42     let (:sha) do
43       shell("git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1").stdout.chomp
44     end
45
46     after(:all) do
47       shell("rm -rf #{tmpdir}/testrepo_sha")
48     end
49
50     it 'clones a repo' do
51       pp = <<-EOS
52       vcsrepo { "#{tmpdir}/testrepo_sha":
53         ensure => present,
54         provider => git,
55         source => "file://#{tmpdir}/testrepo.git",
56         revision => "#{sha}",
57       }
58       EOS
59
60       # Run it twice and test for idempotency
61       apply_manifest(pp, :catch_failures => true)
62       apply_manifest(pp, :catch_changes => true)
63     end
64
65     describe file("#{tmpdir}/testrepo_sha/.git") do
66       it { is_expected.to be_directory }
67     end
68
69     describe file("#{tmpdir}/testrepo_sha/.git/HEAD") do
70       it { is_expected.to contain sha }
71     end
72   end
73
74   context 'using a tag' do
75     it 'clones a repo' do
76       pp = <<-EOS
77       vcsrepo { "#{tmpdir}/testrepo_tag":
78         ensure => present,
79         provider => git,
80         source => "file://#{tmpdir}/testrepo.git",
81         revision => '0.0.2',
82       }
83       EOS
84
85       # Run it twice and test for idempotency
86       apply_manifest(pp, :catch_failures => true)
87       apply_manifest(pp, :catch_changes => true)
88     end
89
90     describe file("#{tmpdir}/testrepo_tag/.git") do
91       it { is_expected.to be_directory }
92     end
93
94     it 'should have the tag as the HEAD' do
95       shell("git --git-dir=#{tmpdir}/testrepo_tag/.git name-rev HEAD | grep '0.0.2'")
96     end
97   end
98
99   context 'using a branch name' do
100     it 'clones a repo' do
101       pp = <<-EOS
102       vcsrepo { "#{tmpdir}/testrepo_branch":
103         ensure => present,
104         provider => git,
105         source => "file://#{tmpdir}/testrepo.git",
106         revision => 'a_branch',
107       }
108       EOS
109
110       # Run it twice and test for idempotency
111       apply_manifest(pp, :catch_failures => true)
112       apply_manifest(pp, :catch_changes => true)
113     end
114
115     describe file("#{tmpdir}/testrepo_branch/.git") do
116       it { is_expected.to be_directory }
117     end
118
119     describe file("#{tmpdir}/testrepo_branch/.git/HEAD") do
120       it { is_expected.to contain 'ref: refs/heads/a_branch' }
121     end
122   end
123
124   context 'ensure latest with branch specified' do
125     it 'clones a repo' do
126       pp = <<-EOS
127       vcsrepo { "#{tmpdir}/testrepo_latest":
128         ensure => latest,
129         provider => git,
130         source => "file://#{tmpdir}/testrepo.git",
131         revision => 'a_branch',
132       }
133       EOS
134
135       # Run it twice and test for idempotency
136       apply_manifest(pp, :catch_failures => true)
137       apply_manifest(pp, :catch_changes => true)
138     end
139
140     it 'verifies the HEAD commit SHA on remote and local match' do
141       remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout
142       local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp
143       expect(remote_commit).to include(local_commit)
144     end
145   end
146
147   context 'ensure latest with branch unspecified' do
148     it 'clones a repo' do
149       pp = <<-EOS
150       vcsrepo { "#{tmpdir}/testrepo_latest":
151         ensure => latest,
152         provider => git,
153         source => "file://#{tmpdir}/testrepo.git",
154       }
155       EOS
156
157       # Run it twice and test for idempotency
158       apply_manifest(pp, :catch_failures => true)
159       apply_manifest(pp, :catch_changes => true)
160     end
161
162     it 'verifies the HEAD commit SHA on remote and local match' do
163       remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout
164       local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp
165       expect(remote_commit).to include(local_commit)
166     end
167   end
168
169   context 'with shallow clone' do
170     it 'does a shallow clone' do
171       pp = <<-EOS
172       vcsrepo { "#{tmpdir}/testrepo_shallow":
173         ensure => present,
174         provider => git,
175         source => "file://#{tmpdir}/testrepo.git",
176         depth => '1',
177       }
178       EOS
179
180       # Run it twice and test for idempotency
181       apply_manifest(pp, :catch_failures => true)
182       apply_manifest(pp, :catch_changes => true)
183     end
184
185     describe file("#{tmpdir}/testrepo_shallow/.git/shallow") do
186       it { is_expected.to be_file }
187     end
188   end
189
190   context 'path is not empty and not a repository' do
191     before(:all) do
192       shell("mkdir #{tmpdir}/not_a_repo", :acceptable_exit_codes => [0,1])
193       shell("touch #{tmpdir}/not_a_repo/file1.txt", :acceptable_exit_codes => [0,1])
194     end
195
196     it 'should raise an exception' do
197       pp = <<-EOS
198       vcsrepo { "#{tmpdir}/not_a_repo":
199         ensure => present,
200         provider => git
201         source => "file://#{tmpdir}/testrepo.git",
202       }
203       EOS
204       apply_manifest(pp, :expect_failures => true)
205     end
206   end
207
208   context 'with an owner' do
209     pp = <<-EOS
210     user { 'vagrant':
211       ensure => present,
212     }
213     EOS
214
215     apply_manifest(pp, :catch_failures => true)
216     it 'clones a repo' do
217       pp = <<-EOS
218       vcsrepo { "#{tmpdir}/testrepo_owner":
219         ensure => present,
220         provider => git,
221         source => "file://#{tmpdir}/testrepo.git",
222         owner => 'vagrant',
223       }
224       EOS
225
226       # Run it twice and test for idempotency
227       apply_manifest(pp, :catch_failures => true)
228       apply_manifest(pp, :catch_changes => true)
229     end
230
231     describe file("#{tmpdir}/testrepo_owner") do
232       it { is_expected.to be_directory }
233       it { is_expected.to be_owned_by 'vagrant' }
234     end
235   end
236
237   context 'with a group' do
238     pp = <<-EOS
239     group { 'vagrant':
240       ensure => present,
241     }
242     EOS
243
244     apply_manifest(pp, :catch_failures => true)
245
246     it 'clones a repo' do
247       pp = <<-EOS
248       vcsrepo { "/#{tmpdir}/testrepo_group":
249         ensure => present,
250         provider => git,
251         source => "file://#{tmpdir}/testrepo.git",
252         group => 'vagrant',
253       }
254       EOS
255
256       # Run it twice and test for idempotency
257       apply_manifest(pp, :catch_failures => true)
258       apply_manifest(pp, :catch_changes => true)
259     end
260
261     describe file("#{tmpdir}/testrepo_group") do
262       it { is_expected.to be_directory }
263       it { is_expected.to be_grouped_into 'vagrant' }
264     end
265   end
266
267   context 'with excludes' do
268     it 'clones a repo' do
269       pp = <<-EOS
270       vcsrepo { "#{tmpdir}/testrepo_excludes":
271         ensure => present,
272         provider => git,
273         source => "file://#{tmpdir}/testrepo.git",
274         excludes => ['exclude1.txt', 'exclude2.txt'],
275       }
276       EOS
277
278       # Run it twice and test for idempotency
279       apply_manifest(pp, :catch_failures => true)
280       apply_manifest(pp, :catch_changes => true)
281     end
282
283     describe file("#{tmpdir}/testrepo_excludes/.git/info/exclude") do
284       describe '#content' do
285         subject { super().content }
286         it { is_expected.to match /exclude1.txt/ }
287       end
288
289       describe '#content' do
290         subject { super().content }
291         it { is_expected.to match /exclude2.txt/ }
292       end
293     end
294   end
295
296   context 'with force' do
297     before(:all) do
298       shell("mkdir -p #{tmpdir}/testrepo_force/folder")
299       shell("touch #{tmpdir}/testrepo_force/temp.txt")
300     end
301
302     it 'applies the manifest' do
303       pp = <<-EOS
304       vcsrepo { "#{tmpdir}/testrepo_force":
305         ensure => present,
306         provider => git,
307         source => "file://#{tmpdir}/testrepo.git",
308         force => true,
309       }
310       EOS
311
312       # Run it twice and test for idempotency
313       apply_manifest(pp, :catch_failures => true)
314       apply_manifest(pp, :catch_changes => true)
315     end
316
317     describe file("#{tmpdir}/testrepo_force/folder") do
318       it { is_expected.not_to be_directory }
319     end
320
321     describe file("#{tmpdir}/testrepo_force/temp.txt") do
322       it { is_expected.not_to be_file }
323     end
324
325     describe file("#{tmpdir}/testrepo_force/.git") do
326       it { is_expected.to be_directory }
327     end
328
329     context 'and noop' do
330       let(:repo_name) do
331         'testrepo_already_exists'
332       end
333       before(:all) do
334         shell("mkdir #{tmpdir}/#{repo_name}")
335         shell("cd #{tmpdir}/#{repo_name} && git init")
336         shell("cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'")
337       end
338       after(:all) do
339         shell("rm -rf #{tmpdir}/#{repo_name}")
340       end
341
342       it 'applies the manifest' do
343         pp = <<-EOS
344         vcsrepo { "#{tmpdir}/#{repo_name}":
345           ensure   => present,
346           source   => "file://#{tmpdir}/testrepo.git",
347           provider => git,
348           force    => true,
349           noop     => true,
350         }
351         EOS
352
353         apply_manifest(pp, :catch_changes => true) do |r|
354           expect(r.stdout).to match(/Noop Mode/)
355         end
356       end
357     end
358   end
359
360   context 'as a user' do
361     before(:all) do
362       shell("chmod 707 #{tmpdir}")
363       pp = <<-EOS
364       group { 'testuser':
365         ensure => present,
366       }
367       user { 'testuser':
368         ensure => present,
369         groups => 'testuser',
370       }
371       EOS
372
373       apply_manifest(pp, :catch_failures => true)
374     end
375
376     it 'applies the manifest' do
377       pp = <<-EOS
378       vcsrepo { "#{tmpdir}/testrepo_user":
379         ensure => present,
380         provider => git,
381         source => "file://#{tmpdir}/testrepo.git",
382         user => 'testuser',
383       }
384       EOS
385
386       # Run it twice and test for idempotency
387       apply_manifest(pp, :catch_failures => true)
388       apply_manifest(pp, :catch_changes => true)
389     end
390
391     describe file("#{tmpdir}/testrepo_user") do
392       it { is_expected.to be_directory }
393       it { is_expected.to be_owned_by 'testuser' }
394     end
395
396     describe file("#{tmpdir}/testrepo_user") do
397       it { is_expected.to be_directory }
398       it { is_expected.to be_grouped_into 'testuser' }
399     end
400   end
401
402   context 'non-origin remote name' do
403     it 'applies the manifest' do
404       pp = <<-EOS
405       vcsrepo { "#{tmpdir}/testrepo_remote":
406         ensure => present,
407         provider => git,
408         source => "file://#{tmpdir}/testrepo.git",
409         remote => 'testorigin',
410       }
411       EOS
412
413       # Run it twice and test for idempotency
414       apply_manifest(pp, :catch_failures => true)
415       apply_manifest(pp, :catch_changes => true)
416     end
417
418     it 'remote name is "testorigin"' do
419       shell("git --git-dir=#{tmpdir}/testrepo_remote/.git remote | grep 'testorigin'")
420     end
421
422     after(:all) do
423       pp = 'user { "testuser": ensure => absent }'
424       apply_manifest(pp, :catch_failures => true)
425     end
426   end
427
428   context 'as a user with ssh' do
429     before(:all) do
430       # create user
431       pp = <<-EOS
432       group { 'testuser-ssh':
433         ensure => present,
434       }
435       user { 'testuser-ssh':
436         ensure => present,
437         groups => 'testuser-ssh',
438         managehome => true,
439       }
440       EOS
441       apply_manifest(pp, :catch_failures => true)
442
443       # create ssh keys
444       shell('mkdir -p /home/testuser-ssh/.ssh')
445       shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""')
446
447       # copy public key to authorized_keys
448       shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys')
449       shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config')
450       shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh')
451     end
452
453     it 'applies the manifest' do
454       pp = <<-EOS
455       vcsrepo { "#{tmpdir}/testrepo_user_ssh":
456         ensure => present,
457         provider => git,
458         source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git",
459         user => 'testuser-ssh',
460       }
461       EOS
462
463       # Run it twice and test for idempotency
464       apply_manifest(pp, :catch_failures => true)
465       apply_manifest(pp, :catch_changes => true)
466     end
467
468     after(:all) do
469       pp = <<-EOS
470       user { 'testuser-ssh':
471         ensure => absent,
472         managehome => true,
473       }
474       EOS
475       apply_manifest(pp, :catch_failures => true)
476     end
477   end
478
479   context 'using an identity file' do
480     before(:all) do
481       # create user
482       pp = <<-EOS
483       user { 'testuser-ssh':
484         ensure => present,
485         managehome => true,
486       }
487       EOS
488       apply_manifest(pp, :catch_failures => true)
489
490       # create ssh keys
491       shell('mkdir -p /home/testuser-ssh/.ssh')
492       shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""')
493
494       # copy public key to authorized_keys
495       shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys')
496       shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config')
497       shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh')
498     end
499
500     it 'applies the manifest' do
501       pp = <<-EOS
502       vcsrepo { "#{tmpdir}/testrepo_user_ssh_id":
503         ensure => present,
504         provider => git,
505         source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git",
506         identity => '/home/testuser-ssh/.ssh/id_rsa',
507       }
508       EOS
509
510       # Run it twice and test for idempotency
511       apply_manifest(pp, :catch_failures => true)
512       apply_manifest(pp, :catch_changes => true)
513     end
514   end
515 end