Ensure vagrant user/group for non-vagrant testing
[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' 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 => 'master',
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 'with shallow clone' do
148     it 'does a shallow clone' do
149       pp = <<-EOS
150       vcsrepo { "#{tmpdir}/testrepo_shallow":
151         ensure => present,
152         provider => git,
153         source => "file://#{tmpdir}/testrepo.git",
154         depth => '1',
155       }
156       EOS
157
158       # Run it twice and test for idempotency
159       apply_manifest(pp, :catch_failures => true)
160       apply_manifest(pp, :catch_changes => true)
161     end
162
163     describe file("#{tmpdir}/testrepo_shallow/.git/shallow") do
164       it { should be_file }
165     end
166   end
167
168   context 'path is not empty and not a repository' do
169     before(:all) do
170       shell("mkdir #{tmpdir}/not_a_repo", :acceptable_exit_codes => [0,1])
171       shell("touch #{tmpdir}/not_a_repo/file1.txt", :acceptable_exit_codes => [0,1])
172     end
173
174     it 'should raise an exception' do
175       pp = <<-EOS
176       vcsrepo { "#{tmpdir}/not_a_repo":
177         ensure => present,
178         provider => git
179         source => "file://#{tmpdir}/testrepo.git",
180       }
181       EOS
182       apply_manifest(pp, :expect_failures => true)
183     end
184   end
185
186   context 'with an owner' do
187     pp = <<-EOS
188     user { 'vagrant':
189       ensure => present,
190     }
191     EOS
192
193     apply_manifest(pp, :catch_failures => true)
194     it 'clones a repo' do
195       pp = <<-EOS
196       vcsrepo { "#{tmpdir}/testrepo_owner":
197         ensure => present,
198         provider => git,
199         source => "file://#{tmpdir}/testrepo.git",
200         owner => 'vagrant',
201       }
202       EOS
203
204       # Run it twice and test for idempotency
205       apply_manifest(pp, :catch_failures => true)
206       apply_manifest(pp, :catch_changes => true)
207     end
208
209     describe file("#{tmpdir}/testrepo_owner") do
210       it { should be_directory }
211       it { should be_owned_by 'vagrant' }
212     end
213   end
214
215   context 'with a group' do
216     pp = <<-EOS
217     group { 'vagrant':
218       ensure => present,
219     }
220     EOS
221
222     apply_manifest(pp, :catch_failures => true)
223
224     it 'clones a repo' do
225       pp = <<-EOS
226       vcsrepo { "/#{tmpdir}/testrepo_group":
227         ensure => present,
228         provider => git,
229         source => "file://#{tmpdir}/testrepo.git",
230         group => 'vagrant',
231       }
232       EOS
233
234       # Run it twice and test for idempotency
235       apply_manifest(pp, :catch_failures => true)
236       apply_manifest(pp, :catch_changes => true)
237     end
238
239     describe file("#{tmpdir}/testrepo_group") do
240       it { should be_directory }
241       it { should be_grouped_into 'vagrant' }
242     end
243   end
244
245   context 'with excludes' do
246     it 'clones a repo' do
247       pp = <<-EOS
248       vcsrepo { "#{tmpdir}/testrepo_excludes":
249         ensure => present,
250         provider => git,
251         source => "file://#{tmpdir}/testrepo.git",
252         excludes => ['exclude1.txt', 'exclude2.txt'],
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_excludes/.git/info/exclude") do
262       its(:content) { should match /exclude1.txt/ }
263       its(:content) { should match /exclude2.txt/ }
264     end
265   end
266
267   context 'with force' do
268     before(:all) do
269       shell("mkdir -p #{tmpdir}/testrepo_force/folder")
270       shell("touch #{tmpdir}/testrepo_force/temp.txt")
271     end
272
273     it 'applies the manifest' do
274       pp = <<-EOS
275       vcsrepo { "#{tmpdir}/testrepo_force":
276         ensure => present,
277         provider => git,
278         source => "file://#{tmpdir}/testrepo.git",
279         force => true,
280       }
281       EOS
282
283       # Run it twice and test for idempotency
284       apply_manifest(pp, :catch_failures => true)
285       apply_manifest(pp, :catch_changes => true)
286     end
287
288     describe file("#{tmpdir}/testrepo_force/folder") do
289       it { should_not be_directory }
290     end
291
292     describe file("#{tmpdir}/testrepo_force/temp.txt") do
293       it { should_not be_file }
294     end
295
296     describe file("#{tmpdir}/testrepo_force/.git") do
297       it { should be_directory }
298     end
299   end
300
301   context 'as a user' do
302     before(:all) do
303       shell("chmod 707 #{tmpdir}")
304       pp = <<-EOS
305       user { 'testuser':
306         ensure => present,
307       }
308       EOS
309
310       apply_manifest(pp, :catch_failures => true)
311     end
312
313     it 'applies the manifest' do
314       pp = <<-EOS
315       vcsrepo { "#{tmpdir}/testrepo_user":
316         ensure => present,
317         provider => git,
318         source => "file://#{tmpdir}/testrepo.git",
319         user => 'testuser',
320       }
321       EOS
322
323       # Run it twice and test for idempotency
324       apply_manifest(pp, :catch_failures => true)
325       apply_manifest(pp, :catch_changes => true)
326     end
327
328     describe file("#{tmpdir}/testrepo_user") do
329       it { should be_directory }
330       it { should be_owned_by 'testuser' }
331     end
332
333     describe file("#{tmpdir}/testrepo_user") do
334       it { should be_directory }
335       it { should be_grouped_into 'testuser' }
336     end
337   end
338
339   context 'non-origin remote name' do
340     it 'applies the manifest' do
341       pp = <<-EOS
342       vcsrepo { "#{tmpdir}/testrepo_remote":
343         ensure => present,
344         provider => git,
345         source => "file://#{tmpdir}/testrepo.git",
346         remote => 'testorigin',
347       }
348       EOS
349
350       # Run it twice and test for idempotency
351       apply_manifest(pp, :catch_failures => true)
352       apply_manifest(pp, :catch_changes => true)
353     end
354
355     it 'remote name is "testorigin"' do
356       shell("git --git-dir=#{tmpdir}/testrepo_remote/.git remote | grep 'testorigin'")
357     end
358
359     after(:all) do
360       pp = 'user { "testuser": ensure => absent }'
361       apply_manifest(pp, :catch_failures => true)
362     end
363   end
364
365   context 'as a user with ssh' do
366     before(:all) do
367       # create user
368       pp = <<-EOS
369       user { 'testuser-ssh':
370         ensure => present,
371         managehome => true,
372       }
373       EOS
374       apply_manifest(pp, :catch_failures => true)
375
376       # create ssh keys
377       shell('mkdir -p /home/testuser-ssh/.ssh')
378       shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""')
379
380       # copy public key to authorized_keys
381       shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys')
382       shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config')
383       shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh')
384     end
385
386     it 'applies the manifest' do
387       pp = <<-EOS
388       vcsrepo { "#{tmpdir}/testrepo_user_ssh":
389         ensure => present,
390         provider => git,
391         source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git",
392         user => 'testuser-ssh',
393       }
394       EOS
395
396       # Run it twice and test for idempotency
397       apply_manifest(pp, :catch_failures => true)
398       apply_manifest(pp, :catch_changes => true)
399     end
400
401     after(:all) do
402       pp = <<-EOS
403       user { 'testuser-ssh':
404         ensure => absent,
405         managehome => true,
406       }
407       EOS
408       apply_manifest(pp, :catch_failures => true)
409     end
410   end
411
412   context 'using an identity file' do
413     before(:all) do
414       # create user
415       pp = <<-EOS
416       user { 'testuser-ssh':
417         ensure => present,
418         managehome => true,
419       }
420       EOS
421       apply_manifest(pp, :catch_failures => true)
422
423       # create ssh keys
424       shell('mkdir -p /home/testuser-ssh/.ssh')
425       shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""')
426
427       # copy public key to authorized_keys
428       shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys')
429       shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config')
430       shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh')
431     end
432
433     it 'applies the manifest' do
434       pp = <<-EOS
435       vcsrepo { "#{tmpdir}/testrepo_user_ssh_id":
436         ensure => present,
437         provider => git,
438         source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git",
439         identity => '/home/testuser-ssh/.ssh/id_rsa',
440       }
441       EOS
442
443       # Run it twice and test for idempotency
444       apply_manifest(pp, :catch_failures => true)
445       apply_manifest(pp, :catch_changes => true)
446     end
447
448     after(:all) do
449       pp = <<-EOS
450       user { 'testuser-ssh':
451         ensure => absent,
452         managehome => true,
453       }
454       EOS
455       apply_manifest(pp, :catch_failures => true)
456     end
457   end
458 end