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