Add test for ensure latest with branch specified
[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 { should be_directory }
34     end
35
36     describe file("#{tmpdir}/testrepo/.git/HEAD") do
37       it { should 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 { should be_directory }
67     end
68
69     describe file("#{tmpdir}/testrepo_sha/.git/HEAD") do
70       it { should 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 { should 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 { should be_directory }
117     end
118
119     describe file("#{tmpdir}/testrepo_branch/.git/HEAD") do
120       it { should 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 { should 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     it 'clones a repo' do
210       pp = <<-EOS
211       vcsrepo { "#{tmpdir}/testrepo_owner":
212         ensure => present,
213         provider => git,
214         source => "file://#{tmpdir}/testrepo.git",
215         owner => 'vagrant',
216       }
217       EOS
218
219       # Run it twice and test for idempotency
220       apply_manifest(pp, :catch_failures => true)
221       apply_manifest(pp, :catch_changes => true)
222     end
223
224     describe file("#{tmpdir}/testrepo_owner") do
225       it { should be_directory }
226       it { should be_owned_by 'vagrant' }
227     end
228   end
229
230   context 'with a group' do
231     it 'clones a repo' do
232       pp = <<-EOS
233       vcsrepo { "/#{tmpdir}/testrepo_group":
234         ensure => present,
235         provider => git,
236         source => "file://#{tmpdir}/testrepo.git",
237         group => 'vagrant',
238       }
239       EOS
240
241       # Run it twice and test for idempotency
242       apply_manifest(pp, :catch_failures => true)
243       apply_manifest(pp, :catch_changes => true)
244     end
245
246     describe file("#{tmpdir}/testrepo_group") do
247       it { should be_directory }
248       it { should be_grouped_into 'vagrant' }
249     end
250   end
251
252   context 'with excludes' do
253     it 'clones a repo' do
254       pp = <<-EOS
255       vcsrepo { "#{tmpdir}/testrepo_excludes":
256         ensure => present,
257         provider => git,
258         source => "file://#{tmpdir}/testrepo.git",
259         excludes => ['exclude1.txt', 'exclude2.txt'],
260       }
261       EOS
262
263       # Run it twice and test for idempotency
264       apply_manifest(pp, :catch_failures => true)
265       apply_manifest(pp, :catch_changes => true)
266     end
267
268     describe file("#{tmpdir}/testrepo_excludes/.git/info/exclude") do
269       its(:content) { should match /exclude1.txt/ }
270       its(:content) { should match /exclude2.txt/ }
271     end
272   end
273
274   context 'with force' do
275     before(:all) do
276       shell("mkdir -p #{tmpdir}/testrepo_force/folder")
277       shell("touch #{tmpdir}/testrepo_force/temp.txt")
278     end
279
280     it 'applies the manifest' do
281       pp = <<-EOS
282       vcsrepo { "#{tmpdir}/testrepo_force":
283         ensure => present,
284         provider => git,
285         source => "file://#{tmpdir}/testrepo.git",
286         force => true,
287       }
288       EOS
289
290       # Run it twice and test for idempotency
291       apply_manifest(pp, :catch_failures => true)
292       apply_manifest(pp, :catch_changes => true)
293     end
294
295     describe file("#{tmpdir}/testrepo_force/folder") do
296       it { should_not be_directory }
297     end
298
299     describe file("#{tmpdir}/testrepo_force/temp.txt") do
300       it { should_not be_file }
301     end
302
303     describe file("#{tmpdir}/testrepo_force/.git") do
304       it { should be_directory }
305     end
306   end
307
308   context 'as a user' do
309     before(:all) do
310       shell("chmod 707 #{tmpdir}")
311       pp = <<-EOS
312       user { 'testuser':
313         ensure => present,
314       }
315       EOS
316
317       apply_manifest(pp, :catch_failures => true)
318     end
319
320     it 'applies the manifest' do
321       pp = <<-EOS
322       vcsrepo { "#{tmpdir}/testrepo_user":
323         ensure => present,
324         provider => git,
325         source => "file://#{tmpdir}/testrepo.git",
326         user => 'testuser',
327       }
328       EOS
329
330       # Run it twice and test for idempotency
331       apply_manifest(pp, :catch_failures => true)
332       apply_manifest(pp, :catch_changes => true)
333     end
334
335     describe file("#{tmpdir}/testrepo_user") do
336       it { should be_directory }
337       it { should be_owned_by 'testuser' }
338     end
339
340     describe file("#{tmpdir}/testrepo_user") do
341       it { should be_directory }
342       it { should be_grouped_into 'testuser' }
343     end
344   end
345
346   context 'non-origin remote name' do
347     it 'applies the manifest' do
348       pp = <<-EOS
349       vcsrepo { "#{tmpdir}/testrepo_remote":
350         ensure => present,
351         provider => git,
352         source => "file://#{tmpdir}/testrepo.git",
353         remote => 'testorigin',
354       }
355       EOS
356
357       # Run it twice and test for idempotency
358       apply_manifest(pp, :catch_failures => true)
359       apply_manifest(pp, :catch_changes => true)
360     end
361
362     it 'remote name is "testorigin"' do
363       shell("git --git-dir=#{tmpdir}/testrepo_remote/.git remote | grep 'testorigin'")
364     end
365
366     after(:all) do
367       pp = 'user { "testuser": ensure => absent }'
368       apply_manifest(pp, :catch_failures => true)
369     end
370   end
371
372   context 'as a user with ssh' do
373     before(:all) do
374       # create user
375       pp = <<-EOS
376       user { 'testuser-ssh':
377         ensure => present,
378         managehome => true,
379       }
380       EOS
381       apply_manifest(pp, :catch_failures => true)
382
383       # create ssh keys
384       shell('mkdir -p /home/testuser-ssh/.ssh')
385       shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""')
386
387       # copy public key to authorized_keys
388       shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys')
389       shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config')
390       shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh')
391     end
392
393     it 'applies the manifest' do
394       pp = <<-EOS
395       vcsrepo { "#{tmpdir}/testrepo_user_ssh":
396         ensure => present,
397         provider => git,
398         source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git",
399         user => 'testuser-ssh',
400       }
401       EOS
402
403       # Run it twice and test for idempotency
404       apply_manifest(pp, :catch_failures => true)
405       apply_manifest(pp, :catch_changes => true)
406     end
407
408     after(:all) do
409       pp = <<-EOS
410       user { 'testuser-ssh':
411         ensure => absent,
412         managehome => true,
413       }
414       EOS
415       apply_manifest(pp, :catch_failures => true)
416     end
417   end
418
419   context 'using an identity file' do
420     before(:all) do
421       # create user
422       pp = <<-EOS
423       user { 'testuser-ssh':
424         ensure => present,
425         managehome => true,
426       }
427       EOS
428       apply_manifest(pp, :catch_failures => true)
429
430       # create ssh keys
431       shell('mkdir -p /home/testuser-ssh/.ssh')
432       shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""')
433
434       # copy public key to authorized_keys
435       shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys')
436       shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config')
437       shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh')
438     end
439
440     it 'applies the manifest' do
441       pp = <<-EOS
442       vcsrepo { "#{tmpdir}/testrepo_user_ssh_id":
443         ensure => present,
444         provider => git,
445         source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git",
446         identity => '/home/testuser-ssh/.ssh/id_rsa',
447       }
448       EOS
449
450       # Run it twice and test for idempotency
451       apply_manifest(pp, :catch_failures => true)
452       apply_manifest(pp, :catch_changes => true)
453     end
454
455     after(:all) do
456       pp = <<-EOS
457       user { 'testuser-ssh':
458         ensure => absent,
459         managehome => true,
460       }
461       EOS
462       apply_manifest(pp, :catch_failures => true)
463     end
464   end
465 end