1 require 'puppetlabs_spec_helper/module_spec_helper'
3 # Customize filters to ignore 3rd-party code
4 # If the coverage report shows not-our-code results, add it here
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]',
17 'Exec[Configure ODL OVSDB Clustering]',
18 'Exec[download archive opendaylight.tar.gz and check sum]',
19 'Exec[download archive opendaylight-systemd.tar.gz and check sum]',
20 'Exec[opendaylight unpack]',
21 'Exec[opendaylight-systemd unpack]',
22 'Exec[rm-on-error-opendaylight.tar.gz]',
23 'Exec[rm-on-error-opendaylight-systemd.tar.gz]',
24 'Exec[reload_systemd_units]',
25 'Exec[update-java-alternatives]',
29 'Stage[deploy_infra]',
34 RSpec::Puppet::Coverage.filters.push(*custom_filters)
37 # NB: This is a library of helper fns used by the rspec-puppet tests
40 # Tests that are common to all possible configurations
42 # Confirm that module compiles
44 it { should compile.with_all_deps }
46 # Confirm presence of classes
47 it { should contain_class('opendaylight') }
48 it { should contain_class('opendaylight::params') }
49 it { should contain_class('opendaylight::install') }
50 it { should contain_class('opendaylight::config') }
51 it { should contain_class('opendaylight::service') }
53 # Confirm relationships between classes
54 it { should contain_class('opendaylight::install').that_comes_before('Class[opendaylight::config]') }
55 it { should contain_class('opendaylight::config').that_requires('Class[opendaylight::install]') }
56 it { should contain_class('opendaylight::config').that_notifies('Class[opendaylight::service]') }
57 it { should contain_class('opendaylight::service').that_subscribes_to('Class[opendaylight::config]') }
58 it { should contain_class('opendaylight::service').that_comes_before('Class[opendaylight]') }
59 it { should contain_class('opendaylight').that_requires('Class[opendaylight::service]') }
61 # Confirm presence of generic resources
62 it { should contain_service('opendaylight') }
63 it { should contain_file('org.apache.karaf.features.cfg') }
65 # Confirm properties of generic resources
66 # NB: These hashes don't work with Ruby 1.8.7, but we
67 # don't support 1.8.7 so that's okay. See issue #36.
69 should contain_service('opendaylight').with(
70 'ensure' => 'running',
72 'hasstatus' => 'true',
73 'hasrestart' => 'true',
77 should contain_file('org.apache.karaf.features.cfg').with(
79 'path' => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
86 # Shared tests that specialize in testing Karaf feature installs
87 def karaf_feature_tests(options = {})
89 # NB: This default list should be the same as the one in opendaylight::params
90 # TODO: Remove this possible source of bugs^^
91 default_features = options.fetch(:default_features, ['config', 'standard', 'region', 'package', 'kar', 'ssh', 'management'])
92 extra_features = options.fetch(:extra_features, [])
94 # The order of this list concat matters
95 features = default_features + extra_features
96 features_csv = features.join(',')
98 # Confirm properties of Karaf features config file
99 # NB: These hashes don't work with Ruby 1.8.7, but we
100 # don't support 1.8.7 so that's okay. See issue #36.
102 should contain_file('org.apache.karaf.features.cfg').with(
104 'path' => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
110 should contain_file_line('featuresBoot').with(
111 'path' => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
112 'line' => "featuresBoot=#{features_csv}",
113 'match' => '^featuresBoot=.*$',
118 # Shared tests that specialize in testing ODL's REST port config
119 def odl_rest_port_tests(options = {})
121 # NB: This default value should be the same as one in opendaylight::params
122 # TODO: Remove this possible source of bugs^^
123 odl_rest_port = options.fetch(:odl_rest_port, 8080)
125 # Confirm properties of ODL REST port config file
126 # NB: These hashes don't work with Ruby 1.8.7, but we
127 # don't support 1.8.7 so that's okay. See issue #36.
129 should contain_file('jetty.xml').with(
131 'path' => '/opt/opendaylight/etc/jetty.xml',
134 'content' => /Property name="jetty.port" default="#{odl_rest_port}"/
139 def log_level_tests(options = {})
141 # NB: This default value should be the same as one in opendaylight::params
142 # TODO: Remove this possible source of bugs^^
143 log_levels = options.fetch(:log_levels, {})
146 # Should contain log level config file
148 should contain_file('org.ops4j.pax.logging.cfg').with(
150 'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
155 # Should not contain custom log level config
157 should_not contain_file('org.ops4j.pax.logging.cfg').with(
159 'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
162 'content' => /# Log level config added by puppet-opendaylight/
166 # Should contain log level config file
168 should contain_file('org.ops4j.pax.logging.cfg').with(
170 'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
175 # Should contain custom log level config
177 should contain_file('org.ops4j.pax.logging.cfg').with(
179 'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
182 'content' => /# Log level config added by puppet-opendaylight/
185 # Verify each custom log level config entry
186 log_levels.each_pair do |logger, level|
188 should contain_file('org.ops4j.pax.logging.cfg').with(
190 'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
193 'content' => /^log4j.logger.#{logger} = #{level}/
200 def enable_ha_tests(options = {})
202 enable_ha = options.fetch(:enable_ha, false)
203 ha_node_ips = options.fetch(:ha_node_ips, [])
204 ha_node_index = options.fetch(:ha_node_index, 0)
206 ha_node_count = ha_node_ips.size
208 if (enable_ha) && (ha_node_count < 2)
209 # Check for HA_NODE_COUNT < 2
210 fail("Number of HA nodes less than 2: #{ha_node_count} and HA Enabled")
214 def rpm_install_tests(options = {})
216 rpm_repo = options.fetch(:rpm_repo, 'opendaylight-5-testing')
217 java_opts = options.fetch(:java_opts, '-Djava.net.preferIPv4Stack=true')
219 # Default to CentOS 7 Yum repo URL
221 # Confirm presence of RPM-related resources
222 it { should contain_yumrepo(rpm_repo) }
223 it { should contain_package('opendaylight') }
225 # Confirm relationships between RPM-related resources
226 it { should contain_package('opendaylight').that_requires("Yumrepo[#{rpm_repo}]") }
227 it { should contain_yumrepo(rpm_repo).that_comes_before('Package[opendaylight]') }
229 # Confirm properties of RPM-related resources
230 # NB: These hashes don't work with Ruby 1.8.7, but we
231 # don't support 1.8.7 so that's okay. See issue #36.
233 should contain_yumrepo(rpm_repo).with(
236 'descr' => 'OpenDaylight SDN Controller',
237 'baseurl' => "http://cbs.centos.org/repos/nfv7-#{rpm_repo}/$basearch/os/",
241 should contain_package('opendaylight').with(
242 'ensure' => 'present',
247 should contain_file_line('java_options_systemd').with(
248 'ensure' => 'present',
249 'path' => '/usr/lib/systemd/system/opendaylight.service',
250 'line' => "Environment=_JAVA_OPTIONS=\'#{java_opts}\'",
251 'after' => 'ExecStart=/opt/opendaylight/bin/start',
256 def deb_install_tests(options = {})
258 deb_repo = options.fetch(:deb_repo, 'ppa:odl-team/boron')
260 # Confirm the presence of Deb-related resources
261 it { should contain_apt__ppa(deb_repo) }
262 it { should contain_package('opendaylight') }
264 # Confirm relationships between Deb-related resources
265 it { should contain_package('opendaylight').that_requires("Apt::Ppa[#{deb_repo}]") }
266 it { should contain_apt__ppa(deb_repo).that_comes_before('Package[opendaylight]') }
268 # Confirm presence of Deb-related resources
270 should contain_package('opendaylight').with(
271 'ensure' => 'present',
276 # Shared tests for unsupported OSs
277 def unsupported_os_tests(options = {})
279 expected_msg = options.fetch(:expected_msg)
280 rpm_repo = options.fetch(:rpm_repo, 'opendaylight-5-testing')
282 # Confirm that classes fail on unsupported OSs
283 it { expect { should contain_class('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
284 it { expect { should contain_class('opendaylight::install') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
285 it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
286 it { expect { should contain_class('opendaylight::service') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
288 # Confirm that other resources fail on unsupported OSs
289 it { expect { should contain_yumrepo(rpm_repo) }.to raise_error(Puppet::Error, /#{expected_msg}/) }
290 it { expect { should contain_package('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
291 it { expect { should contain_service('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
292 it { expect { should contain_file('org.apache.karaf.features.cfg') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
295 # Shared tests that specialize in testing security group mode
296 def enable_sg_tests(sg_mode='stateful', os_release)
298 # NB: This default value should be the same as one in opendaylight::params
299 # TODO: Remove this possible source of bugs^^
301 it { should contain_file('/opt/opendaylight/etc/opendaylight') }
302 it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
303 it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
304 it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
306 if os_release != '7.3' and sg_mode == 'stateful'
307 # Confirm sg_mode becomes learn
309 should contain_file('netvirt-aclservice-config.xml').with(
311 'path' => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml',
318 # Confirm other sg_mode is passed correctly
320 should contain_file('netvirt-aclservice-config.xml').with(
322 'path' => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml',
325 'content' => /#{sg_mode}/
331 # Shared tests that specialize in testing VPP routing node config
332 def vpp_routing_node_tests(options = {})
334 # NB: This default list should be the same as the one in opendaylight::params
335 # TODO: Remove this possible source of bugs^^
336 routing_node = options.fetch(:routing_node, '')
338 if routing_node.empty?
339 it { should_not contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.cfg') }
340 it { should_not contain_file_line('routing-node') }
342 # Confirm properties of Karaf config file
343 # NB: These hashes don't work with Ruby 1.8.7, but we
344 # don't support 1.8.7 so that's okay. See issue #36.
346 should contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.cfg').with(
348 'path' => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.cfg',
354 should contain_file_line('routing-node').with(
355 'path' => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.cfg',
356 'line' => "routing-node=#{routing_node}",
357 'match' => '^routing-node=.*$',