Update mod version and pup version in metadata
[integration/packaging/puppet-opendaylight.git] / spec / spec_helper.rb
1 require 'puppetlabs_spec_helper/module_spec_helper'
2
3 # Customize filters to ignore 3rd-party code
4 # If the coverage report shows not-our-code results, add it here
5 custom_filters = [
6   'Anchor[java::end]',
7   'Stage[setup]',
8   'Anchor[java::begin:]',
9   'Archive::Download[opendaylight.tar.gz]',
10   'Archive::Download[opendaylight-systemd.tar.gz]',
11   'Archive::Extract[opendaylight]',
12   'Archive::Extract[opendaylight-systemd]',
13   'Class[Java::Config]',
14   'Class[Java::Params]',
15   'Class[Stdlib::Stages]',
16   'Class[Stdlib]',
17   'Exec[download archive opendaylight.tar.gz and check sum]',
18   'Exec[download archive opendaylight-systemd.tar.gz and check sum]',
19   'Exec[opendaylight unpack]',
20   'Exec[opendaylight-systemd unpack]',
21   'Exec[rm-on-error-opendaylight.tar.gz]',
22   'Exec[rm-on-error-opendaylight-systemd.tar.gz]',
23   'Exec[update-java-alternatives]',
24   'Package[curl]',
25   'Stage[deploy]',
26   'Stage[deploy_app]',
27   'Stage[deploy_infra]',
28   'Stage[runtime]',
29   'Stage[setup_app]',
30   'Stage[setup_infra]',
31 ]
32 RSpec::Puppet::Coverage.filters.push(*custom_filters)
33
34 #
35 # NB: This is a library of helper fns used by the rspec-puppet tests
36 #
37
38 # Tests that are common to all possible configurations
39 def generic_tests()
40   # Confirm that module compiles
41   it { should compile }
42   it { should compile.with_all_deps }
43
44   # Confirm presence of classes
45   it { should contain_class('opendaylight') }
46   it { should contain_class('opendaylight::params') }
47   it { should contain_class('opendaylight::install') }
48   it { should contain_class('opendaylight::config') }
49   it { should contain_class('opendaylight::service') }
50
51   # Confirm relationships between classes
52   it { should contain_class('opendaylight::install').that_comes_before('opendaylight::config') }
53   it { should contain_class('opendaylight::config').that_requires('opendaylight::install') }
54   it { should contain_class('opendaylight::config').that_notifies('opendaylight::service') }
55   it { should contain_class('opendaylight::service').that_subscribes_to('opendaylight::config') }
56   it { should contain_class('opendaylight::service').that_comes_before('opendaylight') }
57   it { should contain_class('opendaylight').that_requires('opendaylight::service') }
58
59   # Confirm presence of generic resources
60   it { should contain_service('opendaylight') }
61   it { should contain_file('org.apache.karaf.features.cfg') }
62
63   # Confirm properties of generic resources
64   # NB: These hashes don't work with Ruby 1.8.7, but we
65   #   don't support 1.8.7 so that's okay. See issue #36.
66   it {
67     should contain_service('opendaylight').with(
68       'ensure'      => 'running',
69       'enable'      => 'true',
70       'hasstatus'   => 'true',
71       'hasrestart'  => 'true',
72     )
73   }
74   it {
75     should contain_file('org.apache.karaf.features.cfg').with(
76       'ensure'      => 'file',
77       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
78       'owner'   => 'odl',
79       'group'   => 'odl',
80     )
81   }
82 end
83
84 # Shared tests that specialize in testing Karaf feature installs
85 def karaf_feature_tests(options = {})
86   # Extract params
87   # NB: This default list should be the same as the one in opendaylight::params
88   # TODO: Remove this possible source of bugs^^
89   default_features = options.fetch(:default_features, ['config', 'standard', 'region', 'package', 'kar', 'ssh', 'management'])
90   extra_features = options.fetch(:extra_features, [])
91
92   # The order of this list concat matters
93   features = default_features + extra_features
94   features_csv = features.join(',')
95
96   # Confirm properties of Karaf features config file
97   # NB: These hashes don't work with Ruby 1.8.7, but we
98   #   don't support 1.8.7 so that's okay. See issue #36.
99   it {
100     should contain_file('org.apache.karaf.features.cfg').with(
101       'ensure'      => 'file',
102       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
103       'owner'   => 'odl',
104       'group'   => 'odl',
105     )
106   }
107   it {
108     should contain_file_line('featuresBoot').with(
109       'path'  => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
110       'line'  => "featuresBoot=#{features_csv}",
111       'match' => '^featuresBoot=.*$',
112     )
113   }
114 end
115
116 # Shared tests that specialize in testing ODL's REST port config
117 def odl_rest_port_tests(options = {})
118   # Extract params
119   # NB: This default value should be the same as one in opendaylight::params
120   # TODO: Remove this possible source of bugs^^
121   odl_rest_port = options.fetch(:odl_rest_port, 8080)
122
123   # Confirm properties of ODL REST port config file
124   # NB: These hashes don't work with Ruby 1.8.7, but we
125   #   don't support 1.8.7 so that's okay. See issue #36.
126   it {
127     should contain_file('jetty.xml').with(
128       'ensure'      => 'file',
129       'path'        => '/opt/opendaylight/etc/jetty.xml',
130       'owner'   => 'odl',
131       'group'   => 'odl',
132       'content'     => /Property name="jetty.port" default="#{odl_rest_port}"/
133     )
134   }
135 end
136
137 def log_level_tests(options = {})
138   # Extract params
139   # NB: This default value should be the same as one in opendaylight::params
140   # TODO: Remove this possible source of bugs^^
141   log_levels = options.fetch(:log_levels, {})
142
143   if log_levels.empty?
144     # Should contain log level config file
145     it {
146       should contain_file('org.ops4j.pax.logging.cfg').with(
147         'ensure'      => 'file',
148         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
149         'owner'   => 'odl',
150         'group'   => 'odl',
151       )
152     }
153     # Should not contain custom log level config
154     it {
155       should_not contain_file('org.ops4j.pax.logging.cfg').with(
156         'ensure'      => 'file',
157         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
158         'owner'   => 'odl',
159         'group'   => 'odl',
160         'content'     => /# Log level config added by puppet-opendaylight/
161       )
162     }
163   else
164     # Should contain log level config file
165     it {
166       should contain_file('org.ops4j.pax.logging.cfg').with(
167         'ensure'      => 'file',
168         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
169         'owner'   => 'odl',
170         'group'   => 'odl',
171       )
172     }
173     # Should contain custom log level config
174     it {
175       should contain_file('org.ops4j.pax.logging.cfg').with(
176         'ensure'      => 'file',
177         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
178         'owner'   => 'odl',
179         'group'   => 'odl',
180         'content'     => /# Log level config added by puppet-opendaylight/
181       )
182     }
183     # Verify each custom log level config entry
184     log_levels.each_pair do |logger, level|
185       it {
186         should contain_file('org.ops4j.pax.logging.cfg').with(
187           'ensure'      => 'file',
188           'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
189           'owner'   => 'odl',
190           'group'   => 'odl',
191           'content'     => /^log4j.logger.#{logger} = #{level}/
192         )
193       }
194     end
195   end
196 end
197
198 # Shared tests that specialize in testing enabling L3 via ODL OVSDB
199 def enable_l3_tests(options = {})
200   # Extract params
201   # NB: This default value should be the same as one in opendaylight::params
202   # TODO: Remove this possible source of bugs^^
203   enable_l3 = options.fetch(:enable_l3, 'no')
204
205   if [true, 'yes'].include? enable_l3
206     # Confirm ODL OVSDB L3 is enabled
207     it {
208       should contain_file('custom.properties').with(
209         'ensure'      => 'file',
210         'path'        => '/opt/opendaylight/etc/custom.properties',
211         'owner'   => 'odl',
212         'group'   => 'odl',
213         'content'     => /^ovsdb.l3.fwd.enabled=yes/
214       )
215     }
216   elsif [false, 'no'].include? enable_l3
217     # Confirm ODL OVSDB L3 is disabled
218     it {
219       should contain_file('custom.properties').with(
220         'ensure'      => 'file',
221         'path'        => '/opt/opendaylight/etc/custom.properties',
222         'owner'   => 'odl',
223         'group'   => 'odl',
224         'content'     => /^ovsdb.l3.fwd.enabled=no/
225       )
226     }
227   end
228 end
229
230 def tarball_install_tests(options = {})
231   # Extract params
232   # NB: These default values should be the same as ones in opendaylight::params
233   # TODO: Remove this possible source of bugs^^
234   tarball_url = options.fetch(:tarball_url, 'https://nexus.opendaylight.org/content/repositories/staging/org/opendaylight/integration/distribution-karaf/0.4.0-Beryllium-RC2/distribution-karaf-0.4.0-Beryllium-RC2.tar.gz')
235   unitfile_url = options.fetch(:unitfile_url, 'https://github.com/dfarrell07/opendaylight-systemd/archive/master/opendaylight-unitfile.tar.gz')
236   osfamily = options.fetch(:osfamily, 'RedHat')
237
238   # Confirm presence of tarball-related resources
239   it { should contain_archive('opendaylight') }
240   it { should contain_class('java') }
241   it { should contain_file('/opt/opendaylight/') }
242   it { should contain_user('odl') }
243   it { should contain_group('odl') }
244
245   # Confirm relationships between tarball-related resources
246   it { should contain_archive('opendaylight').that_comes_before('File[/opt/opendaylight/]') }
247   it { should contain_archive('opendaylight').that_comes_before('User[odl]') }
248   it { should contain_file('/opt/opendaylight/').that_requires('Archive[opendaylight]') }
249   it { should contain_file('/opt/opendaylight/').that_requires('Group[odl]') }
250   it { should contain_file('/opt/opendaylight/').that_requires('User[odl]') }
251   it { should contain_user('odl').that_comes_before('File[/opt/opendaylight/]') }
252   it { should contain_user('odl').that_requires('Archive[opendaylight]') }
253   it { should contain_user('odl').that_requires('Group[odl]') }
254   it { should contain_group('odl').that_comes_before('File[/opt/opendaylight/]') }
255   it { should contain_group('odl').that_comes_before('User[odl]') }
256
257   # Confirm properties of tarball-related resources
258   # NB: These hashes don't work with Ruby 1.8.7, but we
259   #   don't support 1.8.7 so that's okay. See issue #36.
260   it {
261     should contain_archive('opendaylight').with(
262       'ensure'           => 'present',
263       'url'              => tarball_url,
264       'target'           => '/opt/opendaylight/',
265       'checksum'         => false,
266       'strip_components' => 1,
267       'timeout'          => 600,
268     )
269   }
270   it {
271     should contain_file('/opt/opendaylight/').with(
272       'ensure'  => 'directory',
273       'recurse' => true,
274       'owner'   => 'odl',
275       'group'   => 'odl',
276     )
277   }
278   it {
279     should contain_user('odl').with(
280       'name'       => 'odl',
281       'ensure'     => 'present',
282       'home'       => '/opt/opendaylight/',
283       'membership' => 'minimum',
284       'groups'     => 'odl',
285     )
286   }
287   it {
288     should contain_group('odl').with(
289       'name'       => 'odl',
290       'ensure'     => 'present',
291     )
292   }
293
294   # OS-specific validations
295   case osfamily
296   when 'RedHat'
297     # Validations specific to Red Hat family OSs (RHEL/CentOS/Fedora)
298     it { should contain_archive('opendaylight-systemd') }
299     it { should contain_file('/usr/lib/systemd/system/opendaylight.service') }
300     it { should contain_archive('opendaylight-systemd').that_comes_before('File[/usr/lib/systemd/system/opendaylight.service]') }
301     it { should contain_file('/usr/lib/systemd/system/opendaylight.service').that_requires('Archive[opendaylight-systemd]') }
302
303     # NB: These hashes don't work with Ruby 1.8.7, but we
304     #   don't support 1.8.7 so that's okay. See issue #36.
305     it {
306       should contain_package('java').with(
307         'name' => 'java-1.7.0-openjdk',
308       )
309     }
310     it {
311       should contain_archive('opendaylight-systemd').with(
312         'ensure'           => 'present',
313         'url'              => unitfile_url,
314         'target'           => '/usr/lib/systemd/system/',
315         'root_dir'         => 'opendaylight.service',
316         'checksum'         => false,
317         'strip_components' => 1,
318         'follow_redirects' => true,
319       )
320     }
321     it {
322       should contain_file('/usr/lib/systemd/system/opendaylight.service').with(
323         'ensure'  => 'file',
324         'owner'   => 'root',
325         'group'   => 'root',
326         'mode'    => '0644',
327       )
328     }
329   when 'Debian'
330     # Validations specific to Debain family OSs (Ubuntu)
331     it {
332       should contain_package('java').with(
333         'name' => 'openjdk-7-jdk',
334       )
335     }
336     it {
337       should contain_file('/etc/init/opendaylight.conf').with(
338         'ensure'  => 'file',
339         'owner'   => 'root',
340         'group'   => 'root',
341         'mode'    => '0644',
342       )
343     }
344     expected_msg = 'Debian has limited support, is less stable, less tested.'
345     it {
346       expect {
347         # This could be any check, most (all?) will raise warning
348         should contain_file('/etc/init/opendaylight.conf').to(
349           raise_warning(Puppet::Warning, /#{expected_msg}/)
350         )
351       }
352     }
353   else
354     fail("Unexpected osfamily #{osfamily}")
355   end
356
357   # Verify that there are no unexpected resources from RPM-type installs
358   it { should_not contain_yumrepo('opendaylight-4-testing') }
359   it { should_not contain_package('opendaylight') }
360 end
361
362 def rpm_install_tests(options = {})
363   # Extract params
364   # Choose Yum URL based on OS (CentOS vs Fedora)
365   # NB: Currently using the CentOS CBS for both Fedora and CentOS
366   operatingsystem  = options.fetch(:operatingsystem, 'CentOS')
367   case operatingsystem
368   when 'CentOS'
369     yum_repo = 'http://cbs.centos.org/repos/nfv7-opendaylight-4-testing/$basearch/os/'
370   when 'Fedora'
371     yum_repo = 'http://cbs.centos.org/repos/nfv7-opendaylight-4-testing/$basearch/os/'
372   else
373     fail("Unknown operatingsystem: #{operatingsystem}")
374   end
375
376   # Default to CentOS 7 Yum repo URL
377
378   # Confirm presence of RPM-related resources
379   it { should contain_yumrepo('opendaylight-4-testing') }
380   it { should contain_package('opendaylight') }
381
382   # Confirm relationships between RPM-related resources
383   it { should contain_package('opendaylight').that_requires('Yumrepo[opendaylight-4-testing]') }
384   it { should contain_yumrepo('opendaylight-4-testing').that_comes_before('Package[opendaylight]') }
385
386   # Confirm properties of RPM-related resources
387   # NB: These hashes don't work with Ruby 1.8.7, but we
388   #   don't support 1.8.7 so that's okay. See issue #36.
389   it {
390     should contain_yumrepo('opendaylight-4-testing').with(
391       'enabled'     => '1',
392       'gpgcheck'    => '0',
393       'descr'       => 'CentOS CBS OpenDaylight Berillium testing repository',
394       'baseurl'     => yum_repo,
395     )
396   }
397   it {
398     should contain_package('opendaylight').with(
399       'ensure'   => 'present',
400     )
401   }
402 end
403
404 # Shared tests for unsupported OSs
405 def unsupported_os_tests(options = {})
406   # Extract params
407   expected_msg = options.fetch(:expected_msg)
408
409   # Confirm that classes fail on unsupported OSs
410   it { expect { should contain_class('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
411   it { expect { should contain_class('opendaylight::install') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
412   it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
413   it { expect { should contain_class('opendaylight::service') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
414
415   # Confirm that other resources fail on unsupported OSs
416   it { expect { should contain_yumrepo('opendaylight-4-testing') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
417   it { expect { should contain_package('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
418   it { expect { should contain_service('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
419   it { expect { should contain_file('org.apache.karaf.features.cfg') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
420 end