Merge pull request #1058 from puppetlabs/issue-1057
[puppet-modules/puppetlabs-apt.git] / spec / defines / source_spec.rb
1 # frozen_string_literal: true
2
3 require 'spec_helper'
4
5 describe 'apt::source' do
6   GPG_KEY_ID = '6F6B15509CF8E59E6E469F327F438280EF8D349F'
7
8   let :pre_condition do
9     'class { "apt": }'
10   end
11
12   let :title do
13     'my_source'
14   end
15
16   let :facts do
17     {
18       os: {
19         family: 'Debian',
20         name: 'Debian',
21         release: {
22           major: '9',
23           full: '9.0',
24         },
25         distro: {
26           codename: 'stretch',
27           id: 'Debian',
28         },
29       },
30     }
31   end
32
33   context 'with defaults' do
34     context 'without location' do
35       it do
36         is_expected.to raise_error(Puppet::Error, %r{source entry without specifying a location})
37       end
38     end
39     context 'with location' do
40       let(:params) { { location: 'hello.there' } }
41
42       it {
43         is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').without_content(%r{# my_source\ndeb-src hello.there wheezy main\n})
44         is_expected.not_to contain_package('apt-transport-https')
45       }
46     end
47   end
48
49   describe 'no defaults' do
50     context 'with complex pin' do
51       let :params do
52         {
53           location: 'hello.there',
54           pin: { 'release' => 'wishwash',
55                  'explanation' => 'wishwash',
56                  'priority'    => 1001 },
57         }
58       end
59
60       it {
61         is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{hello.there stretch main\n})
62       }
63
64       it { is_expected.to contain_file('/etc/apt/sources.list.d/my_source.list').that_notifies('Class[Apt::Update]') }
65
66       it {
67         is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
68                                                                                                             priority: 1001,
69                                                                                                             explanation: 'wishwash',
70                                                                                                             release: 'wishwash')
71       }
72     end
73
74     context 'with simple key' do
75       let :params do
76         {
77           comment: 'foo',
78           location: 'http://debian.mirror.iweb.ca/debian/',
79           release: 'sid',
80           repos: 'testing',
81           key: GPG_KEY_ID,
82           pin: '10',
83           architecture: 'x86_64',
84           allow_unsigned: true,
85         }
86       end
87
88       it {
89         is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n})
90                                                              .without_content(%r{deb-src})
91       }
92
93       it {
94         is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
95                                                                                                             priority: '10',
96                                                                                                             origin: 'debian.mirror.iweb.ca')
97       }
98
99       it {
100         is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
101                                                                                                                                                     id: GPG_KEY_ID)
102       }
103     end
104
105     context 'with complex key' do
106       let :params do
107         {
108           comment: 'foo',
109           location: 'http://debian.mirror.iweb.ca/debian/',
110           release: 'sid',
111           repos: 'testing',
112           key: {
113             'ensure' => 'refreshed',
114             'id' => GPG_KEY_ID,
115             'server' => 'pgp.mit.edu',
116             'content' => 'GPG key content',
117             'source'  => 'http://apt.puppetlabs.com/pubkey.gpg',
118             'weak_ssl' => true,
119           },
120           pin: '10',
121           architecture: 'x86_64',
122           allow_unsigned: true,
123         }
124       end
125
126       it {
127         is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n})
128                                                              .without_content(%r{deb-src})
129       }
130
131       it {
132         is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
133                                                                                                             priority: '10',
134                                                                                                             origin: 'debian.mirror.iweb.ca')
135       }
136
137       it {
138         is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'refreshed',
139                                                                                                                                                     id: GPG_KEY_ID,
140                                                                                                                                                     server: 'pgp.mit.edu',
141                                                                                                                                                     content: 'GPG key content',
142                                                                                                                                                     source: 'http://apt.puppetlabs.com/pubkey.gpg',
143                                                                                                                                                     weak_ssl: true)
144       }
145     end
146   end
147
148   context 'with allow_insecure true' do
149     let :params do
150       {
151         location: 'hello.there',
152         allow_insecure: true,
153       }
154     end
155
156     it {
157       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb \[allow-insecure=yes\] hello.there stretch main\n})
158     }
159   end
160
161   context 'with allow_unsigned true' do
162     let :params do
163       {
164         location: 'hello.there',
165         allow_unsigned: true,
166       }
167     end
168
169     it {
170       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb \[trusted=yes\] hello.there stretch main\n})
171     }
172   end
173
174   context 'with check_valid_until false' do
175     let :params do
176       {
177         location: 'hello.there',
178         check_valid_until: false,
179       }
180     end
181
182     it {
183       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb \[check-valid-until=false\] hello.there stretch main\n})
184     }
185   end
186
187   context 'with check_valid_until true' do
188     let :params do
189       {
190         location: 'hello.there',
191         check_valid_until: true,
192       }
193     end
194
195     it {
196       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb hello.there stretch main\n})
197     }
198   end
199
200   context 'with keyring set' do
201     let :params do
202       {
203         location: 'hello.there',
204         keyring: '/usr/share/keyrings/foo-archive-keyring.gpg',
205       }
206     end
207
208     it {
209       is_expected.to contain_apt__setting('list-my_source')
210         .with(ensure: 'present')
211         .with_content(%r{# my_source\ndeb \[signed-by=/usr/share/keyrings/foo-archive-keyring.gpg\] hello.there stretch main\n})
212     }
213   end
214
215   context 'with keyring, architecture and allow_unsigned set' do
216     let :params do
217       {
218         location: 'hello.there',
219         architecture: 'amd64',
220         allow_unsigned: true,
221         keyring: '/usr/share/keyrings/foo-archive-keyring.gpg',
222       }
223     end
224
225     it {
226       is_expected.to contain_apt__setting('list-my_source')
227         .with(ensure: 'present')
228         .with_content(%r{# my_source\ndeb \[arch=amd64 trusted=yes signed-by=/usr/share/keyrings/foo-archive-keyring.gpg\] hello.there stretch main\n})
229     }
230   end
231
232   context 'with a https location, install apt-transport-https' do
233     let :params do
234       {
235         location: 'HTTPS://foo.bar',
236         allow_unsigned: false,
237       }
238     end
239
240     it {
241       is_expected.to contain_package('apt-transport-https')
242     }
243   end
244
245   context 'with a https location and custom release, install apt-transport-https' do
246     let :facts do
247       {
248         os: {
249           family: 'Debian',
250           name: 'Debian',
251           release: {
252             major: '9',
253             full: '9.0',
254           },
255           distro: {
256             codename: 'stretch',
257             id: 'Debian',
258           },
259         },
260         puppetversion: Puppet.version,
261       }
262     end
263     let :params do
264       {
265         location: 'HTTPS://foo.bar',
266         allow_unsigned: false,
267         release: 'customrelease',
268       }
269     end
270
271     it {
272       is_expected.to contain_package('apt-transport-https')
273     }
274   end
275
276   context 'with a https location, do not install apt-transport-https on oses not in list eg buster' do
277     let :facts do
278       {
279         os: {
280           family: 'Debian',
281           name: 'Debian',
282           release: {
283             major: '10',
284             full: '10.0',
285           },
286           distro: {
287             codename: 'buster',
288             id: 'Debian',
289           },
290         },
291       }
292     end
293     let :params do
294       {
295         location: 'https://foo.bar',
296         allow_unsigned: false,
297       }
298     end
299
300     it {
301       is_expected.not_to contain_package('apt-transport-https')
302     }
303   end
304
305   context 'with architecture equals x86_64' do
306     let :facts do
307       {
308         os: {
309           family: 'Debian',
310           name: 'Debian',
311           release: {
312             major: '7',
313             full: '7.0',
314           },
315           distro: {
316             codename: 'wheezy',
317             id: 'Debian',
318           },
319         },
320       }
321     end
322     let :params do
323       {
324         location: 'hello.there',
325         include: { 'deb' => false, 'src' => true },
326         architecture: 'x86_64',
327       }
328     end
329
330     it {
331       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb-src \[arch=x86_64\] hello.there wheezy main\n})
332     }
333   end
334
335   context 'with architecture fact and unset architecture parameter' do
336     let :facts do
337       super().merge(architecture: 'amd64')
338     end
339     let :params do
340       {
341         location: 'hello.there',
342         include: { 'deb' => false, 'src' => true },
343       }
344     end
345
346     it {
347       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb-src hello.there stretch main\n})
348     }
349   end
350
351   context 'with include_src => true' do
352     let :params do
353       {
354         location: 'hello.there',
355         include: { 'src' => true },
356       }
357     end
358
359     it {
360       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb hello.there stretch main\ndeb-src hello.there stretch main\n})
361     }
362   end
363
364   context 'with include deb => false' do
365     let :params do
366       {
367         include: { 'deb' => false },
368         location: 'hello.there',
369       }
370     end
371
372     it {
373       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').without_content(%r{deb-src hello.there wheezy main\n})
374     }
375     it { is_expected.to contain_apt__setting('list-my_source').without_content(%r{deb hello.there wheezy main\n}) }
376   end
377
378   context 'with include src => true and include deb => false' do
379     let :params do
380       {
381         include: { 'deb' => false, 'src' => true },
382         location: 'hello.there',
383       }
384     end
385
386     it {
387       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{deb-src hello.there stretch main\n})
388     }
389     it { is_expected.to contain_apt__setting('list-my_source').without_content(%r{deb hello.there stretch main\n}) }
390   end
391
392   context 'with ensure => absent' do
393     let :params do
394       {
395         ensure: 'absent',
396       }
397     end
398
399     it {
400       is_expected.to contain_apt__setting('list-my_source').with(ensure: 'absent')
401     }
402   end
403
404   describe 'validation' do
405     context 'with no release' do
406       let :facts do
407         {
408           os: {
409             family: 'Debian',
410             name: 'Debian',
411             release: {
412               major: '8',
413               full: '8.0',
414             },
415             distro: {
416               id: 'Debian',
417             },
418           },
419         }
420       end
421       let(:params) { { location: 'hello.there' } }
422
423       it do
424         is_expected.to raise_error(Puppet::Error, %r{os.distro.codename fact not available: release parameter required})
425       end
426     end
427
428     context 'with release is empty string' do
429       let(:params) { { location: 'hello.there', release: '' } }
430
431       it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{hello\.there  main}) }
432     end
433
434     context 'with invalid pin' do
435       let :params do
436         {
437           location: 'hello.there',
438           pin: true,
439         }
440       end
441
442       it do
443         is_expected.to raise_error(Puppet::Error, %r{expects a value})
444       end
445     end
446
447     context 'with notify_update = undef (default)' do
448       let :params do
449         {
450           location: 'hello.there',
451         }
452       end
453
454       it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(true) }
455     end
456
457     context 'with notify_update = true' do
458       let :params do
459         {
460           location: 'hello.there',
461           notify_update: true,
462         }
463       end
464
465       it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(true) }
466     end
467
468     context 'with notify_update = false' do
469       let :params do
470         {
471           location: 'hello.there',
472           notify_update: false,
473         }
474       end
475
476       it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(false) }
477     end
478   end
479 end