Fixes configuring jetty.xml
[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 rspec coverage report shows not-our-code results, add it here
7 custom_filters = [
8 ]
9 RSpec::Puppet::Coverage.filters.push(*custom_filters)
10
11 #
12 # NB: This is a library of helper fns used by the rspec-puppet tests
13 #
14
15 # Tests that are common to all possible configurations
16 def generic_tests()
17   # Confirm that module compiles
18   it { should compile }
19   it { should compile.with_all_deps }
20
21   # Confirm presence of classes
22   it { should contain_class('opendaylight') }
23   it { should contain_class('opendaylight::params') }
24   it { should contain_class('opendaylight::install') }
25   it { should contain_class('opendaylight::config') }
26   it { should contain_class('opendaylight::service') }
27
28   # Confirm relationships between classes
29   it { should contain_class('opendaylight::install').that_comes_before('Class[opendaylight::config]') }
30   it { should contain_class('opendaylight::config').that_requires('Class[opendaylight::install]') }
31   it { should contain_class('opendaylight::config').that_notifies('Class[opendaylight::service]') }
32   it { should contain_class('opendaylight::service').that_subscribes_to('Class[opendaylight::config]') }
33   it { should contain_class('opendaylight::service').that_comes_before('Class[opendaylight]') }
34   it { should contain_class('opendaylight').that_requires('Class[opendaylight::service]') }
35
36   # Confirm presence of generic resources
37   it { should contain_service('opendaylight') }
38   it { should contain_file('org.apache.karaf.features.cfg') }
39
40   # Confirm properties of generic resources
41   # NB: These hashes don't work with Ruby 1.8.7, but we
42   #   don't support 1.8.7 so that's okay. See issue #36.
43   it {
44     should contain_service('opendaylight').with(
45       'ensure'      => 'running',
46       'enable'      => 'true',
47       'hasstatus'   => 'true',
48       'hasrestart'  => 'true',
49     )
50   }
51   it {
52     should contain_file('org.apache.karaf.features.cfg').with(
53       'ensure'      => 'file',
54       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
55       'owner'   => 'odl',
56       'group'   => 'odl',
57     )
58   }
59 end
60
61 # Shared tests that specialize in testing log file size and rollover
62 def log_file_settings(options = {})
63   # Extraxt params. The dafault value should be same as in opendaylight::params
64   log_max_size = options.fetch(:log_max_size, '10GB')
65   log_max_rollover = options.fetch(:log_max_rollover, 2)
66
67   it {
68     should contain_file_line('logmaxsize').with(
69       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
70       'line'   => "log4j.appender.out.maxFileSize=#{log_max_size}",
71       'match'  => '^log4j.appender.out.maxFileSize.*$',
72     )
73   }
74   it {
75     should contain_file_line('logmaxrollover').with(
76       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
77       'line'   => "log4j.appender.out.maxBackupIndex=#{log_max_rollover}",
78       'match'  => '^log4j.appender.out.maxBackupIndex.*$',
79     )
80   }
81 end
82
83 # Shared tests that specialize in testing Karaf feature installs
84 def karaf_feature_tests(options = {})
85   # Extract params
86   # NB: This default list should be the same as the one in opendaylight::params
87   # TODO: Remove this possible source of bugs^^
88   default_features = options.fetch(:default_features, ['config', 'standard', 'region', 'package', 'kar', 'ssh', 'management'])
89   extra_features = options.fetch(:extra_features, [])
90
91   # The order of this list concat matters
92   features = default_features + extra_features
93   features_csv = features.join(',')
94
95   # Confirm properties of Karaf features config file
96   # NB: These hashes don't work with Ruby 1.8.7, but we
97   #   don't support 1.8.7 so that's okay. See issue #36.
98   it {
99     should contain_file('org.apache.karaf.features.cfg').with(
100       'ensure'      => 'file',
101       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
102       'owner'   => 'odl',
103       'group'   => 'odl',
104     )
105   }
106   it {
107     should contain_file_line('featuresBoot').with(
108       'path'  => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
109       'line'  => "featuresBoot=#{features_csv}",
110       'match' => '^featuresBoot=.*$',
111     )
112   }
113 end
114
115 # Shared tests that specialize in testing ODL's REST port config
116 def odl_rest_port_tests(options = {})
117   # Extract params
118   # NB: This default value should be the same as one in opendaylight::params
119   # TODO: Remove this possible source of bugs^^
120   odl_rest_port = options.fetch(:odl_rest_port, 8080)
121
122   # Confirm properties of ODL REST port config file
123   # NB: These hashes don't work with Ruby 1.8.7, but we
124   #   don't support 1.8.7 so that's okay. See issue #36.
125   it {
126     should contain_augeas('jetty.xml')
127   }
128 end
129
130 def log_level_tests(options = {})
131   # Extract params
132   # NB: This default value should be the same as one in opendaylight::params
133   # TODO: Remove this possible source of bugs^^
134   log_levels = options.fetch(:log_levels, {})
135
136   if log_levels.empty?
137     # Should contain log level config file
138     it {
139       should_not contain_file_line('logger-org.opendaylight.ovsdb')
140     }
141   else
142     # Verify each custom log level config entry
143     log_levels.each_pair do |logger, level|
144       it {
145         should contain_file_line("logger-#{logger}").with(
146           'ensure' => 'present',
147           'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
148           'line' => "log4j.logger.#{logger}=#{level}",
149         )
150       }
151     end
152   end
153 end
154
155 def enable_ha_tests(options = {})
156   # Extract params
157   enable_ha = options.fetch(:enable_ha, false)
158   odl_bind_ip = options.fetch(:odl_bind_ip, '0.0.0.0')
159   ha_node_ips = options.fetch(:ha_node_ips, [])
160   ha_db_modules = options.fetch(:ha_db_modules, { 'default' => false })
161   # HA_NODE_IPS size
162   ha_node_count = ha_node_ips.size
163
164   if (enable_ha) && (ha_node_count < 2)
165     # Check for HA_NODE_COUNT < 2
166     fail("Number of HA nodes less than 2: #{ha_node_count} and HA Enabled")
167   end
168
169   if enable_ha
170     ha_node_index = ha_node_ips.index(odl_bind_ip)
171     it {
172       should contain_file('akka.conf').with(
173         'path'    => '/opt/opendaylight/configuration/initial/akka.conf',
174         'ensure'  => 'file',
175         'owner'   => 'odl',
176         'group'   => 'odl',
177         'content' => /roles\s*=\s*\["member-#{ha_node_index}"\]/
178       )
179     }
180
181     ha_db_modules.each do |mod, urn|
182       it { should contain_file('module-shards.conf').with(
183         'path'    => '/opt/opendaylight/configuration/initial/module-shards.conf',
184         'ensure'  => 'file',
185         'owner'   => 'odl',
186         'group'   => 'odl',
187         'content' => /name = "#{mod}"/
188       )}
189       if mod == 'default'
190         it { should contain_file('modules.conf').with(
191           'path'    => '/opt/opendaylight/configuration/initial/modules.conf',
192           'ensure'  => 'file',
193           'owner'   => 'odl',
194           'group'   => 'odl'
195         )}
196       else
197         it { should contain_file('modules.conf').with(
198           'path'    => '/opt/opendaylight/configuration/initial/modules.conf',
199           'ensure'  => 'file',
200           'owner'   => 'odl',
201           'group'   => 'odl',
202           'content' => /name = "#{mod}"/,
203         )}
204       end
205     end
206   else
207     it {
208       should_not contain_file('akka.conf')
209       should_not contain_file('module-shards.conf')
210       should_not contain_file('modules.conf')
211       }
212   end
213 end
214
215 def rpm_install_tests(options = {})
216   # Extract params
217   rpm_repo = options.fetch(:rpm_repo, 'opendaylight-6-testing')
218   java_opts = options.fetch(:java_opts, '-Djava.net.preferIPv4Stack=true')
219
220   # Default to CentOS 7 Yum repo URL
221
222   # Confirm presence of RPM-related resources
223   it { should contain_yumrepo(rpm_repo) }
224   it { should contain_package('opendaylight') }
225
226   # Confirm relationships between RPM-related resources
227   it { should contain_package('opendaylight').that_requires("Yumrepo[#{rpm_repo}]") }
228   it { should contain_yumrepo(rpm_repo).that_comes_before('Package[opendaylight]') }
229
230   # Confirm properties of RPM-related resources
231   # NB: These hashes don't work with Ruby 1.8.7, but we
232   #   don't support 1.8.7 so that's okay. See issue #36.
233   it {
234     should contain_yumrepo(rpm_repo).with(
235       'enabled'     => '1',
236       'gpgcheck'    => '0',
237       'descr'       => 'OpenDaylight SDN Controller',
238       'baseurl'     => "http://cbs.centos.org/repos/nfv7-#{rpm_repo}/$basearch/os/",
239     )
240   }
241   it {
242     should contain_package('opendaylight').with(
243       'ensure'   => 'present',
244     )
245   }
246
247   it {
248     should contain_file_line('java_options_systemd').with(
249       'ensure' => 'present',
250       'path' => '/usr/lib/systemd/system/opendaylight.service',
251       'line' => "Environment=_JAVA_OPTIONS=\'#{java_opts}\'",
252       'after' => 'ExecStart=/opt/opendaylight/bin/start',
253     )
254   }
255 end
256
257 def deb_install_tests(options = {})
258   # Extract params
259   deb_repo = options.fetch(:deb_repo, 'ppa:odl-team/carbon')
260
261   # Confirm the presence of Deb-related resources
262   it { should contain_apt__ppa(deb_repo) }
263   it { should contain_package('opendaylight') }
264
265   # Confirm relationships between Deb-related resources
266   it { should contain_package('opendaylight').that_requires("Apt::Ppa[#{deb_repo}]") }
267   it { should contain_apt__ppa(deb_repo).that_comes_before('Package[opendaylight]') }
268
269   # Confirm presence of Deb-related resources
270   it {
271     should contain_package('opendaylight').with(
272       'ensure'   => 'present',
273     )
274   }
275 end
276
277 # Shared tests for unsupported OSs
278 def unsupported_os_tests(options = {})
279   # Extract params
280   expected_msg = options.fetch(:expected_msg)
281   rpm_repo = options.fetch(:rpm_repo, 'opendaylight-6-testing')
282
283   # Confirm that classes fail on unsupported OSs
284   it { expect { should contain_class('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
285   it { expect { should contain_class('opendaylight::install') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
286   it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
287   it { expect { should contain_class('opendaylight::service') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
288
289   # Confirm that other resources fail on unsupported OSs
290   it { expect { should contain_yumrepo(rpm_repo) }.to raise_error(Puppet::Error, /#{expected_msg}/) }
291   it { expect { should contain_package('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
292   it { expect { should contain_service('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
293   it { expect { should contain_file('org.apache.karaf.features.cfg') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
294 end
295
296 # Shared tests that specialize in testing security group mode
297 def enable_sg_tests(sg_mode='stateful', os_release)
298   # Extract params
299   # NB: This default value should be the same as one in opendaylight::params
300   # TODO: Remove this possible source of bugs^^
301
302   it { should contain_file('/opt/opendaylight/etc/opendaylight') }
303   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
304   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
305   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
306
307   if os_release != '7.3' and sg_mode == 'stateful'
308     # Confirm sg_mode becomes learn
309     it {
310       should contain_file('netvirt-aclservice-config.xml').with(
311         'ensure'      => 'file',
312         'path'        => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml',
313         'owner'   => 'odl',
314         'group'   => 'odl',
315         'content'     => /learn/
316       )
317     }
318   else
319     # Confirm other sg_mode is passed correctly
320     it {
321       should contain_file('netvirt-aclservice-config.xml').with(
322         'ensure'      => 'file',
323         'path'        => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml',
324         'owner'   => 'odl',
325         'group'   => 'odl',
326         'content'     => /#{sg_mode}/
327       )
328     }
329   end
330 end
331
332 # Shared tests that specialize in testing SNAT mechanism
333 def snat_mechanism_tests(snat_mechanism='controller')
334   it { should contain_file('/opt/opendaylight/etc/opendaylight') }
335   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
336   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
337   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
338
339   # Confirm snat_mechanism
340   it {
341     should contain_file('netvirt-natservice-config.xml').with(
342       'ensure'      => 'file',
343       'path'        => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-natservice-config.xml',
344       'owner'   => 'odl',
345       'group'   => 'odl',
346       'content'     =>  /<nat-mode>#{snat_mechanism}<\/nat-mode>/
347       )
348     }
349 end
350
351 # Shared tests that specialize in testing SFC Config
352 def sfc_tests()
353   it { should contain_file('/opt/opendaylight/etc/opendaylight') }
354   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
355   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
356   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
357
358   it {
359     should contain_file('netvirt-elanmanager-config.xml').with(
360       'ensure'  => 'file',
361       'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-elanmanager-config.xml',
362       'owner'   => 'odl',
363       'group'   => 'odl',
364       'source'  => 'puppet:///modules/opendaylight/netvirt-elanmanager-config.xml'
365       )
366     should contain_file('genius-itm-config.xml').with(
367       'ensure'  => 'file',
368       'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/genius-itm-config.xml',
369       'owner'   => 'odl',
370       'group'   => 'odl',
371       'source'  => 'puppet:///modules/opendaylight/genius-itm-config.xml'
372       )
373     }
374 end
375
376 # Shared tests that specialize in testing VPP routing node config
377 def vpp_routing_node_tests(options = {})
378   # Extract params
379   # NB: This default list should be the same as the one in opendaylight::params
380   # TODO: Remove this possible source of bugs^^
381   routing_node = options.fetch(:routing_node, '')
382
383   if routing_node.empty?
384     it { should_not contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg') }
385     it { should_not contain_file_line('routing-node') }
386   else
387     # Confirm properties of Karaf config file
388     # NB: These hashes don't work with Ruby 1.8.7, but we
389     #   don't support 1.8.7 so that's okay. See issue #36.
390     it {
391       should contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg').with(
392         'ensure'      => 'file',
393         'path'        => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg',
394         'owner'   => 'odl',
395         'group'   => 'odl',
396       )
397     }
398     it {
399       should contain_file_line('routing-node').with(
400         'path'  => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg',
401         'line'  => "routing-node=#{routing_node}",
402         'match' => '^routing-node=.*$',
403       )
404     }
405   end
406 end
407
408 # ODL username/password tests
409 def username_password_tests(username, password)
410
411   it {
412     should contain_odl_user(username).with(
413       :password => password
414     )
415   }
416 end