From 2796dab3cdd96306be80d6b78b8eec3a23f4d9f4 Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Wed, 26 Apr 2017 09:19:08 -0600 Subject: tests: Enable artful --- tests/cloud_tests/releases.yaml | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests/cloud_tests') diff --git a/tests/cloud_tests/releases.yaml b/tests/cloud_tests/releases.yaml index 3ffa68f0..183f78c1 100644 --- a/tests/cloud_tests/releases.yaml +++ b/tests/cloud_tests/releases.yaml @@ -49,6 +49,13 @@ releases: #alias: ubuntu/zesty/default alias: z sstreams_server: https://cloud-images.ubuntu.com/daily + artful: + enabled: true + platform_ident: + lxd: + #alias: ubuntu/artful/default + alias: a + sstreams_server: https://cloud-images.ubuntu.com/daily jessie: platform_ident: lxd: -- cgit v1.2.3 From e11d3899d47ec5fcb545e0c7820af9d3995cb574 Mon Sep 17 00:00:00 2001 From: Ryan Harper Date: Fri, 19 May 2017 16:49:11 -0400 Subject: cc_ntp: write template before installing and add service restart On systems which installed ntp and specified servers or pools in the config ntpd didn't notice the updated configuration file and didn't use the correct configuration. Resolve this by rendering the template first which allows the package install to use the existing configuration. Additionally add a service restart to handle the case where ntp does not need to be installed but it may not have started. Add an integration test to confirm that cc_ntp enables ntp to use the specific servers and pools in the cloud-config. LP: #1645644 --- cloudinit/config/cc_ntp.py | 24 ++++++- tests/cloud_tests/configs/modules/ntp_pools.yaml | 10 +-- tests/cloud_tests/configs/modules/ntp_servers.yaml | 16 +++-- tests/cloud_tests/testcases/modules/ntp.py | 4 +- tests/cloud_tests/testcases/modules/ntp_pools.py | 18 +++-- tests/cloud_tests/testcases/modules/ntp_servers.py | 19 ++++-- tests/unittests/test_handler/test_handler_ntp.py | 78 +++++++++++++++++++++- 7 files changed, 142 insertions(+), 27 deletions(-) (limited to 'tests/cloud_tests') diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py index e33032fd..225f898a 100644 --- a/cloudinit/config/cc_ntp.py +++ b/cloudinit/config/cc_ntp.py @@ -74,10 +74,19 @@ def handle(name, cfg, cloud, log, _args): "not present or disabled by cfg", name) return True - install_ntp(cloud.distro.install_packages, packages=['ntp'], - check_exe="ntpd") rename_ntp_conf() + # ensure when ntp is installed it has a configuration file + # to use instead of starting up with packaged defaults write_ntp_config_template(ntp_cfg, cloud) + install_ntp(cloud.distro.install_packages, packages=['ntp'], + check_exe="ntpd") + + # if ntp was already installed, it may not have started + try: + reload_ntp(systemd=cloud.distro.uses_systemd()) + except util.ProcessExecutionError as e: + LOG.exception("Failed to reload/start ntp service: %s", e) + raise def install_ntp(install_func, packages=None, check_exe="ntpd"): @@ -90,6 +99,7 @@ def install_ntp(install_func, packages=None, check_exe="ntpd"): def rename_ntp_conf(config=NTP_CONF): + """Rename any existing ntp.conf file and render from template""" if os.path.exists(config): util.rename(config, config + ".dist") @@ -125,4 +135,14 @@ def write_ntp_config_template(cfg, cloud): templater.render_to_file(template_fn, NTP_CONF, params) + +def reload_ntp(systemd=False): + service = 'ntp' + if systemd: + cmd = ['systemctl', 'reload-or-restart', service] + else: + cmd = ['service', service, 'restart'] + util.subp(cmd, capture=True) + + # vi: ts=4 expandtab diff --git a/tests/cloud_tests/configs/modules/ntp_pools.yaml b/tests/cloud_tests/configs/modules/ntp_pools.yaml index bd0ac292..e040cc32 100644 --- a/tests/cloud_tests/configs/modules/ntp_pools.yaml +++ b/tests/cloud_tests/configs/modules/ntp_pools.yaml @@ -5,10 +5,9 @@ cloud_config: | #cloud-config ntp: pools: - - 0.pool.ntp.org - - 1.pool.ntp.org - - 2.pool.ntp.org - - 3.pool.ntp.org + - 0.cloud-init.mypool + - 1.cloud-init.mypool + - 172.16.15.14 collect_scripts: ntp_installed_pools: | #!/bin/bash @@ -19,5 +18,8 @@ collect_scripts: ntp_conf_pools: | #!/bin/bash grep '^pool' /etc/ntp.conf + ntpq_servers: | + #!/bin/sh + ntpq -p -w # vi: ts=4 expandtab diff --git a/tests/cloud_tests/configs/modules/ntp_servers.yaml b/tests/cloud_tests/configs/modules/ntp_servers.yaml index 934b9c5d..e0564a03 100644 --- a/tests/cloud_tests/configs/modules/ntp_servers.yaml +++ b/tests/cloud_tests/configs/modules/ntp_servers.yaml @@ -5,16 +5,20 @@ cloud_config: | #cloud-config ntp: servers: - - pool.ntp.org + - 172.16.15.14 + - 172.16.17.18 collect_scripts: ntp_installed_servers: | - #!/bin/bash - dpkg -l | grep ntp | wc -l + #!/bin/sh + dpkg -l | grep -c ntp ntp_conf_dist_servers: | - #!/bin/bash - ls /etc/ntp.conf.dist | wc -l + #!/bin/sh + cat /etc/ntp.conf.dist | wc -l ntp_conf_servers: | - #!/bin/bash + #!/bin/sh grep '^server' /etc/ntp.conf + ntpq_servers: | + #!/bin/sh + ntpq -p -w # vi: ts=4 expandtab diff --git a/tests/cloud_tests/testcases/modules/ntp.py b/tests/cloud_tests/testcases/modules/ntp.py index b1119257..82d32880 100644 --- a/tests/cloud_tests/testcases/modules/ntp.py +++ b/tests/cloud_tests/testcases/modules/ntp.py @@ -13,9 +13,9 @@ class TestNtp(base.CloudTestCase): self.assertEqual(1, int(out)) def test_ntp_dist_entries(self): - """Test dist config file has one entry""" + """Test dist config file is empty""" out = self.get_data_file('ntp_conf_dist_empty') - self.assertEqual(1, int(out)) + self.assertEqual(0, int(out)) def test_ntp_entires(self): """Test config entries""" diff --git a/tests/cloud_tests/testcases/modules/ntp_pools.py b/tests/cloud_tests/testcases/modules/ntp_pools.py index d80cb673..ff6d8fa4 100644 --- a/tests/cloud_tests/testcases/modules/ntp_pools.py +++ b/tests/cloud_tests/testcases/modules/ntp_pools.py @@ -13,16 +13,22 @@ class TestNtpPools(base.CloudTestCase): self.assertEqual(1, int(out)) def test_ntp_dist_entries(self): - """Test dist config file has one entry""" + """Test dist config file is empty""" out = self.get_data_file('ntp_conf_dist_pools') - self.assertEqual(1, int(out)) + self.assertEqual(0, int(out)) def test_ntp_entires(self): """Test config entries""" out = self.get_data_file('ntp_conf_pools') - self.assertIn('pool 0.pool.ntp.org iburst', out) - self.assertIn('pool 1.pool.ntp.org iburst', out) - self.assertIn('pool 2.pool.ntp.org iburst', out) - self.assertIn('pool 3.pool.ntp.org iburst', out) + pools = self.cloud_config.get('ntp').get('pools') + for pool in pools: + self.assertIn('pool %s iburst' % pool, out) + + def test_ntpq_servers(self): + """Test ntpq output has configured servers""" + out = self.get_data_file('ntpq_servers') + pools = self.cloud_config.get('ntp').get('pools') + for pool in pools: + self.assertIn(pool, out) # vi: ts=4 expandtab diff --git a/tests/cloud_tests/testcases/modules/ntp_servers.py b/tests/cloud_tests/testcases/modules/ntp_servers.py index 4879bb6f..9ef270ee 100644 --- a/tests/cloud_tests/testcases/modules/ntp_servers.py +++ b/tests/cloud_tests/testcases/modules/ntp_servers.py @@ -13,13 +13,22 @@ class TestNtpServers(base.CloudTestCase): self.assertEqual(1, int(out)) def test_ntp_dist_entries(self): - """Test dist config file has one entry""" + """Test dist config file is empty""" out = self.get_data_file('ntp_conf_dist_servers') - self.assertEqual(1, int(out)) + self.assertEqual(0, int(out)) def test_ntp_entires(self): - """Test config entries""" - out = self.get_data_file('ntp_conf_servers') - self.assertIn('server pool.ntp.org iburst', out) + """Test config pools entries""" + out = self.get_data_file('ntp_conf_pools') + servers = self.cloud_config.get('ntp').get('servers') + for server in servers: + self.assertIn('server %s iburst' % server, out) + + def test_ntpq_servers(self): + """Test ntpq output has configured servers""" + out = self.get_data_file('ntpq_servers') + servers = self.cloud_config.get('ntp').get('servers') + for server in servers: + self.assertIn(server, out) # vi: ts=4 expandtab diff --git a/tests/unittests/test_handler/test_handler_ntp.py b/tests/unittests/test_handler/test_handler_ntp.py index ec600077..02bd3046 100644 --- a/tests/unittests/test_handler/test_handler_ntp.py +++ b/tests/unittests/test_handler/test_handler_ntp.py @@ -249,6 +249,8 @@ class TestNtp(FilesystemMockingTestCase): } } mycloud = self._get_cloud('ubuntu') + mycloud.distro = mock.MagicMock() + mycloud.distro.uses_systemd.return_value = True side_effect = [NTP_TEMPLATE.lstrip()] with mock.patch.object(util, 'which', return_value=None): @@ -259,13 +261,70 @@ class TestNtp(FilesystemMockingTestCase): with mock.patch.object(os.path, 'isfile', return_value=True): with mock.patch.object(util, 'rename'): - cc_ntp.handle("notimportant", cfg, - mycloud, LOG, None) + with mock.patch.object(util, 'subp') as msubp: + cc_ntp.handle("notimportant", cfg, + mycloud, LOG, None) mockwrite.assert_called_once_with( '/etc/ntp.conf', NTP_EXPECTED_UBUNTU, mode=420) + msubp.assert_any_call(['systemctl', 'reload-or-restart', 'ntp'], + capture=True) + + @mock.patch("cloudinit.config.cc_ntp.install_ntp") + @mock.patch("cloudinit.config.cc_ntp.write_ntp_config_template") + @mock.patch("cloudinit.config.cc_ntp.rename_ntp_conf") + def test_write_config_before_install(self, mock_ntp_rename, + mock_ntp_write_config, + mock_install_ntp): + pools = ['0.mycompany.pool.ntp.org'] + servers = ['192.168.23.3'] + cfg = { + 'ntp': { + 'pools': pools, + 'servers': servers, + } + } + cc = self._get_cloud('ubuntu') + cc.distro = mock.MagicMock() + mock_parent = mock.MagicMock() + mock_parent.attach_mock(mock_ntp_rename, 'mock_ntp_rename') + mock_parent.attach_mock(mock_ntp_write_config, 'mock_ntp_write_config') + mock_parent.attach_mock(mock_install_ntp, 'mock_install_ntp') + + cc_ntp.handle('cc_ntp', cfg, cc, LOG, None) + + """Check call order""" + mock_parent.assert_has_calls([ + mock.call.mock_ntp_rename(), + mock.call.mock_ntp_write_config(cfg.get('ntp'), cc), + mock.call.mock_install_ntp(cc.distro.install_packages, + packages=['ntp'], check_exe="ntpd")]) + + @mock.patch("cloudinit.config.cc_ntp.reload_ntp") + @mock.patch("cloudinit.config.cc_ntp.install_ntp") + @mock.patch("cloudinit.config.cc_ntp.write_ntp_config_template") + @mock.patch("cloudinit.config.cc_ntp.rename_ntp_conf") + def test_reload_ntp_fail_raises_exception(self, mock_rename, + mock_write_conf, + mock_install, + mock_reload): + pools = ['0.mycompany.pool.ntp.org'] + servers = ['192.168.23.3'] + cfg = { + 'ntp': { + 'pools': pools, + 'servers': servers, + } + } + cc = self._get_cloud('ubuntu') + cc.distro = mock.MagicMock() + + mock_reload.side_effect = [util.ProcessExecutionError] + self.assertRaises(util.ProcessExecutionError, + cc_ntp.handle, 'cc_ntp', + cfg, cc, LOG, None) @mock.patch("cloudinit.config.cc_ntp.util") def test_no_ntpcfg_does_nothing(self, mock_util): @@ -275,4 +334,19 @@ class TestNtp(FilesystemMockingTestCase): self.assertFalse(cc.distro.install_packages.called) self.assertFalse(mock_util.subp.called) + @mock.patch("cloudinit.config.cc_ntp.util") + def test_reload_ntp_systemd(self, mock_util): + cc_ntp.reload_ntp(systemd=True) + self.assertTrue(mock_util.subp.called) + mock_util.subp.assert_called_with( + ['systemctl', 'reload-or-restart', 'ntp'], capture=True) + + @mock.patch("cloudinit.config.cc_ntp.util") + def test_reload_ntp_service(self, mock_util): + cc_ntp.reload_ntp(systemd=False) + self.assertTrue(mock_util.subp.called) + mock_util.subp.assert_called_with( + ['service', 'ntp', 'restart'], capture=True) + + # vi: ts=4 expandtab -- cgit v1.2.3 From 5375d9da344e84f496c54b253b42454e0888d101 Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Mon, 22 May 2017 11:58:06 -0700 Subject: Fixing wrong file name regression. --- tests/cloud_tests/testcases/modules/ntp_servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/cloud_tests') diff --git a/tests/cloud_tests/testcases/modules/ntp_servers.py b/tests/cloud_tests/testcases/modules/ntp_servers.py index 9ef270ee..419c8270 100644 --- a/tests/cloud_tests/testcases/modules/ntp_servers.py +++ b/tests/cloud_tests/testcases/modules/ntp_servers.py @@ -19,7 +19,7 @@ class TestNtpServers(base.CloudTestCase): def test_ntp_entires(self): """Test config pools entries""" - out = self.get_data_file('ntp_conf_pools') + out = self.get_data_file('ntp_conf_servers') servers = self.cloud_config.get('ntp').get('servers') for server in servers: self.assertIn('server %s iburst' % server, out) -- cgit v1.2.3 From 9fa17d4bc1ef2564e30ab655bf6de462296aecad Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Mon, 22 May 2017 12:43:31 -0700 Subject: function spelling & docstring update --- tests/cloud_tests/testcases/modules/ntp_servers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/cloud_tests') diff --git a/tests/cloud_tests/testcases/modules/ntp_servers.py b/tests/cloud_tests/testcases/modules/ntp_servers.py index 419c8270..4010cf80 100644 --- a/tests/cloud_tests/testcases/modules/ntp_servers.py +++ b/tests/cloud_tests/testcases/modules/ntp_servers.py @@ -17,8 +17,8 @@ class TestNtpServers(base.CloudTestCase): out = self.get_data_file('ntp_conf_dist_servers') self.assertEqual(0, int(out)) - def test_ntp_entires(self): - """Test config pools entries""" + def test_ntp_entries(self): + """Test config server entries""" out = self.get_data_file('ntp_conf_servers') servers = self.cloud_config.get('ntp').get('servers') for server in servers: -- cgit v1.2.3 From 06a7f0afc4db3f8ba2a6b3b521274ee45a028ef2 Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Mon, 22 May 2017 12:13:55 -0700 Subject: tests: Apply workaround for snapd bug in test case. Snapd does not start on artful or on the versions in proposed. This changes the behavior of the test to confirm that snapd is installed, not that it is started, while the snap team fixes the issue (LP: ##1690880). --- tests/cloud_tests/configs/modules/snappy.yaml | 4 ++-- tests/cloud_tests/testcases/modules/snappy.py | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'tests/cloud_tests') diff --git a/tests/cloud_tests/configs/modules/snappy.yaml b/tests/cloud_tests/configs/modules/snappy.yaml index 923bfe12..0e7dc852 100644 --- a/tests/cloud_tests/configs/modules/snappy.yaml +++ b/tests/cloud_tests/configs/modules/snappy.yaml @@ -6,8 +6,8 @@ cloud_config: | snappy: system_snappy: auto collect_scripts: - snap_version: | + snapd: | #!/bin/bash - snap --version + dpkg -s snapd # vi: ts=4 expandtab diff --git a/tests/cloud_tests/testcases/modules/snappy.py b/tests/cloud_tests/testcases/modules/snappy.py index 3e2f5924..b92271c1 100644 --- a/tests/cloud_tests/testcases/modules/snappy.py +++ b/tests/cloud_tests/testcases/modules/snappy.py @@ -9,10 +9,7 @@ class TestSnappy(base.CloudTestCase): def test_snappy_version(self): """Test snappy version output""" - out = self.get_data_file('snap_version') - self.assertIn('snap ', out) - self.assertIn('snapd ', out) - self.assertIn('series ', out) - self.assertIn('ubuntu ', out) + out = self.get_data_file('snapd') + self.assertIn('Status: install ok installed', out) # vi: ts=4 expandtab -- cgit v1.2.3