Revert "Only test Boron in Rakefile suites on ..."
[integration/packaging/puppet-opendaylight.git] / spec / spec_helper.rb
1 require 'puppetlabs_spec_helper/module_spec_helper'
2 require 'rspec-puppet-facts'
3 include RspecPuppetFacts
4
5 # Customize filters to ignore 3rd-party code
6 # If the coverage report shows not-our-code results, add it here
7 custom_filters = [
8   'Anchor[java::end]',
9   'Stage[setup]',
10   'Anchor[java::begin:]',
11   'Archive::Download[opendaylight.tar.gz]',
12   'Archive::Download[opendaylight-systemd.tar.gz]',
13   'Archive::Extract[opendaylight]',
14   'Archive::Extract[opendaylight-systemd]',
15   'Class[Java::Config]',
16   'Class[Java::Params]',
17   'Class[Stdlib::Stages]',
18   'Class[Stdlib]',
19   'Exec[Configure ODL OVSDB Clustering]',
20   'Exec[download archive opendaylight.tar.gz and check sum]',
21   'Exec[download archive opendaylight-systemd.tar.gz and check sum]',
22   'Exec[opendaylight unpack]',
23   'Exec[opendaylight-systemd unpack]',
24   'Exec[rm-on-error-opendaylight.tar.gz]',
25   'Exec[rm-on-error-opendaylight-systemd.tar.gz]',
26   'Exec[reload_systemd_units]',
27   'Exec[update-java-alternatives]',
28   'Package[curl]',
29   'Stage[deploy]',
30   'Stage[deploy_app]',
31   'Stage[deploy_infra]',
32   'Stage[runtime]',
33   'Stage[setup_app]',
34   'Stage[setup_infra]',
35 ]
36 RSpec::Puppet::Coverage.filters.push(*custom_filters)
37
38 #
39 # NB: This is a library of helper fns used by the rspec-puppet tests
40 #
41
42 # Tests that are common to all possible configurations
43 def generic_tests()
44   # Confirm that module compiles
45   it { should compile }
46   it { should compile.with_all_deps }
47
48   # Confirm presence of classes
49   it { should contain_class('opendaylight') }
50   it { should contain_class('opendaylight::params') }
51   it { should contain_class('opendaylight::install') }
52   it { should contain_class('opendaylight::config') }
53   it { should contain_class('opendaylight::service') }
54
55   # Confirm relationships between classes
56   it { should contain_class('opendaylight::install').that_comes_before('Class[opendaylight::config]') }
57   it { should contain_class('opendaylight::config').that_requires('Class[opendaylight::install]') }
58   it { should contain_class('opendaylight::config').that_notifies('Class[opendaylight::service]') }
59   it { should contain_class('opendaylight::service').that_subscribes_to('Class[opendaylight::config]') }
60   it { should contain_class('opendaylight::service').that_comes_before('Class[opendaylight]') }
61   it { should contain_class('opendaylight').that_requires('Class[opendaylight::service]') }
62
63   # Confirm presence of generic resources
64   it { should contain_service('opendaylight') }
65   it { should contain_file('org.apache.karaf.features.cfg') }
66
67   # Confirm properties of generic resources
68   # NB: These hashes don't work with Ruby 1.8.7, but we
69   #   don't support 1.8.7 so that's okay. See issue #36.
70   it {
71     should contain_service('opendaylight').with(
72       'ensure'      => 'running',
73       'enable'      => 'true',
74       'hasstatus'   => 'true',
75       'hasrestart'  => 'true',
76     )
77   }
78   it {
79     should contain_file('org.apache.karaf.features.cfg').with(
80       'ensure'      => 'file',
81       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
82       'owner'   => 'odl',
83       'group'   => 'odl',
84     )
85   }
86 end
87
88 # Shared tests that specialize in testing Karaf feature installs
89 def karaf_feature_tests(options = {})
90   # Extract params
91   # NB: This default list should be the same as the one in opendaylight::params
92   # TODO: Remove this possible source of bugs^^
93   default_features = options.fetch(:default_features, ['config', 'standard', 'region', 'package', 'kar', 'ssh', 'management'])
94   extra_features = options.fetch(:extra_features, [])
95
96   # The order of this list concat matters
97   features = default_features + extra_features
98   features_csv = features.join(',')
99
100   # Confirm properties of Karaf features config file
101   # NB: These hashes don't work with Ruby 1.8.7, but we
102   #   don't support 1.8.7 so that's okay. See issue #36.
103   it {
104     should contain_file('org.apache.karaf.features.cfg').with(
105       'ensure'      => 'file',
106       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
107       'owner'   => 'odl',
108       'group'   => 'odl',
109     )
110   }
111   it {
112     should contain_file_line('featuresBoot').with(
113       'path'  => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
114       'line'  => "featuresBoot=#{features_csv}",
115       'match' => '^featuresBoot=.*$',
116     )
117   }
118 end
119
120 # Shared tests that specialize in testing ODL's REST port config
121 def odl_rest_port_tests(options = {})
122   # Extract params
123   # NB: This default value should be the same as one in opendaylight::params
124   # TODO: Remove this possible source of bugs^^
125   odl_rest_port = options.fetch(:odl_rest_port, 8080)
126
127   # Confirm properties of ODL REST port config file
128   # NB: These hashes don't work with Ruby 1.8.7, but we
129   #   don't support 1.8.7 so that's okay. See issue #36.
130   it {
131     should contain_file('jetty.xml').with(
132       'ensure'      => 'file',
133       'path'        => '/opt/opendaylight/etc/jetty.xml',
134       'owner'   => 'odl',
135       'group'   => 'odl',
136       'content'     => /Property name="jetty.port" default="#{odl_rest_port}"/
137     )
138   }
139 end
140
141 def log_level_tests(options = {})
142   # Extract params
143   # NB: This default value should be the same as one in opendaylight::params
144   # TODO: Remove this possible source of bugs^^
145   log_levels = options.fetch(:log_levels, {})
146
147   if log_levels.empty?
148     # Should contain log level config file
149     it {
150       should contain_file('org.ops4j.pax.logging.cfg').with(
151         'ensure'      => 'file',
152         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
153         'owner'   => 'odl',
154         'group'   => 'odl',
155       )
156     }
157     # Should not contain custom log level config
158     it {
159       should_not contain_file('org.ops4j.pax.logging.cfg').with(
160         'ensure'      => 'file',
161         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
162         'owner'   => 'odl',
163         'group'   => 'odl',
164         'content'     => /# Log level config added by puppet-opendaylight/
165       )
166     }
167   else
168     # Should contain log level config file
169     it {
170       should contain_file('org.ops4j.pax.logging.cfg').with(
171         'ensure'      => 'file',
172         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
173         'owner'   => 'odl',
174         'group'   => 'odl',
175       )
176     }
177     # Should contain custom log level config
178     it {
179       should contain_file('org.ops4j.pax.logging.cfg').with(
180         'ensure'      => 'file',
181         'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
182         'owner'   => 'odl',
183         'group'   => 'odl',
184         'content'     => /# Log level config added by puppet-opendaylight/
185       )
186     }
187     # Verify each custom log level config entry
188     log_levels.each_pair do |logger, level|
189       it {
190         should contain_file('org.ops4j.pax.logging.cfg').with(
191           'ensure'      => 'file',
192           'path'        => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
193           'owner'   => 'odl',
194           'group'   => 'odl',
195           'content'     => /^log4j.logger.#{logger} = #{level}/
196         )
197       }
198     end
199   end
200 end
201
202 def enable_ha_tests(options = {})
203   # Extract params
204   enable_ha = options.fetch(:enable_ha, false)
205   ha_node_ips = options.fetch(:ha_node_ips, [])
206   ha_node_index = options.fetch(:ha_node_index, 0)
207   # HA_NODE_IPS size
208   ha_node_count = ha_node_ips.size
209
210   if (enable_ha) && (ha_node_count < 2)
211     # Check for HA_NODE_COUNT < 2
212     fail("Number of HA nodes less than 2: #{ha_node_count} and HA Enabled")
213   end
214 end
215
216 def rpm_install_tests(options = {})
217   # Extract params
218   rpm_repo = options.fetch(:rpm_repo, 'opendaylight-6-testing')
219   java_opts = options.fetch(:java_opts, '-Djava.net.preferIPv4Stack=true')
220
221   # Default to CentOS 7 Yum repo URL
222
223   # Confirm presence of RPM-related resources
224   it { should contain_yumrepo(rpm_repo) }
225   it { should contain_package('opendaylight') }
226
227   # Confirm relationships between RPM-related resources
228   it { should contain_package('opendaylight').that_requires("Yumrepo[#{rpm_repo}]") }
229   it { should contain_yumrepo(rpm_repo).that_comes_before('Package[opendaylight]') }
230
231   # Confirm properties of RPM-related resources
232   # NB: These hashes don't work with Ruby 1.8.7, but we
233   #   don't support 1.8.7 so that's okay. See issue #36.
234   it {
235     should contain_yumrepo(rpm_repo).with(
236       'enabled'     => '1',
237       'gpgcheck'    => '0',
238       'descr'       => 'OpenDaylight SDN Controller',
239       'baseurl'     => "http://cbs.centos.org/repos/nfv7-#{rpm_repo}/$basearch/os/",
240     )
241   }
242   it {
243     should contain_package('opendaylight').with(
244       'ensure'   => 'present',
245     )
246   }
247
248   it {
249     should contain_file_line('java_options_systemd').with(
250       'ensure' => 'present',
251       'path' => '/usr/lib/systemd/system/opendaylight.service',
252       'line' => "Environment=_JAVA_OPTIONS=\'#{java_opts}\'",
253       'after' => 'ExecStart=/opt/opendaylight/bin/start',
254     )
255   }
256 end
257
258 def deb_install_tests(options = {})
259   # Extract params
260   deb_repo = options.fetch(:deb_repo, 'ppa:odl-team/boron')
261
262   # Confirm the presence of Deb-related resources
263   it { should contain_apt__ppa(deb_repo) }
264   it { should contain_package('opendaylight') }
265
266   # Confirm relationships between Deb-related resources
267   it { should contain_package('opendaylight').that_requires("Apt::Ppa[#{deb_repo}]") }
268   it { should contain_apt__ppa(deb_repo).that_comes_before('Package[opendaylight]') }
269
270   # Confirm presence of Deb-related resources
271   it {
272     should contain_package('opendaylight').with(
273       'ensure'   => 'present',
274     )
275   }
276 end
277
278 # Shared tests for unsupported OSs
279 def unsupported_os_tests(options = {})
280   # Extract params
281   expected_msg = options.fetch(:expected_msg)
282   rpm_repo = options.fetch(:rpm_repo, 'opendaylight-6-testing')
283
284   # Confirm that classes fail on unsupported OSs
285   it { expect { should contain_class('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
286   it { expect { should contain_class('opendaylight::install') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
287   it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
288   it { expect { should contain_class('opendaylight::service') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
289
290   # Confirm that other resources fail on unsupported OSs
291   it { expect { should contain_yumrepo(rpm_repo) }.to raise_error(Puppet::Error, /#{expected_msg}/) }
292   it { expect { should contain_package('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
293   it { expect { should contain_service('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
294   it { expect { should contain_file('org.apache.karaf.features.cfg') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
295 end
296
297 # Shared tests that specialize in testing security group mode
298 def enable_sg_tests(sg_mode='stateful', os_release)
299   # Extract params
300   # NB: This default value should be the same as one in opendaylight::params
301   # TODO: Remove this possible source of bugs^^
302
303   it { should contain_file('/opt/opendaylight/etc/opendaylight') }
304   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
305   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
306   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
307
308   if os_release != '7.3' and sg_mode == 'stateful'
309     # Confirm sg_mode becomes learn
310     it {
311       should contain_file('netvirt-aclservice-config.xml').with(
312         'ensure'      => 'file',
313         'path'        => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml',
314         'owner'   => 'odl',
315         'group'   => 'odl',
316         'content'     => /learn/
317       )
318     }
319   else
320     # Confirm other sg_mode is passed correctly
321     it {
322       should contain_file('netvirt-aclservice-config.xml').with(
323         'ensure'      => 'file',
324         'path'        => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml',
325         'owner'   => 'odl',
326         'group'   => 'odl',
327         'content'     => /#{sg_mode}/
328       )
329     }
330   end
331 end
332
333 # Shared tests that specialize in testing VPP routing node config
334 def vpp_routing_node_tests(options = {})
335   # Extract params
336   # NB: This default list should be the same as the one in opendaylight::params
337   # TODO: Remove this possible source of bugs^^
338   routing_node = options.fetch(:routing_node, '')
339
340   if routing_node.empty?
341     it { should_not contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg') }
342     it { should_not contain_file_line('routing-node') }
343   else
344     # Confirm properties of Karaf config file
345     # NB: These hashes don't work with Ruby 1.8.7, but we
346     #   don't support 1.8.7 so that's okay. See issue #36.
347     it {
348       should contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg').with(
349         'ensure'      => 'file',
350         'path'        => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg',
351         'owner'   => 'odl',
352         'group'   => 'odl',
353       )
354     }
355     it {
356       should contain_file_line('routing-node').with(
357         'path'  => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg',
358         'line'  => "routing-node=#{routing_node}",
359         'match' => '^routing-node=.*$',
360       )
361     }
362   end
363 end