From ea345c6c5587cadcc6fec4d80cec5ffaa397d753 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Wed, 15 Apr 2020 22:15:29 +0200 Subject: [PATCH 01/11] First NovaCloudController test cases Not yet covering the same amount as nova-cloud-controller's Amulet tests. https://launchpad.net/bugs/1828424 --- zaza/openstack/charm_tests/nova/tests.py | 91 +++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 0f27e9f..7a8ff82 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -20,9 +20,10 @@ import logging import unittest import zaza.model -import zaza.openstack.charm_tests.test_utils as test_utils import zaza.openstack.charm_tests.glance.setup as glance_setup +import zaza.openstack.charm_tests.test_utils as test_utils import zaza.openstack.configure.guest +import zaza.openstack.utilities.openstack as openstack_utils class BaseGuestCreateTest(unittest.TestCase): @@ -156,6 +157,94 @@ class NovaCompute(test_utils.OpenStackBaseTest): self.assertFalse(int(run['Code']) == 0) +class NovaCloudController(test_utils.OpenStackBaseTest): + """Run nova-cloud-controller specific tests.""" + + XENIAL_MITAKA = openstack_utils.get_os_release('xenial_mitaka') + XENIAL_NEWTON = openstack_utils.get_os_release('xenial_newton') + XENIAL_OCATA = openstack_utils.get_os_release('xenial_ocata') + BIONIC_QUEENS = openstack_utils.get_os_release('bionic_queens') + + @classmethod + def setUpClass(cls): + """Run class setup for running nova-cloud-controller tests.""" + super(NovaCloudController, cls).setUpClass() + cls.current_release = openstack_utils.get_os_release() + + @property + def services(self): + """Return a list of services for the selected OpenStack release.""" + services = ['nova-scheduler', 'nova-conductor'] + if self.current_release <= self.BIONIC_QUEENS: + services.append('nova-api-os-compute') + if self.current_release <= self.XENIAL_MITAKA: + services.append('nova-cert') + if self.current_release >= self.XENIAL_OCATA: + services.append('apache2') + return services + + def test_104_compute_api_functionality(self): + """Verify basic compute API functionality.""" + logging.info('Instantiating nova client...') + keystone_session = openstack_utils.get_overcloud_keystone_session() + nova = openstack_utils.get_nova_session_client(keystone_session) + + logging.info('Checking api functionality...') + + actual_service_names = [service['binary'] for service in + nova.services.list()] + for expected_service_name in ('nova-scheduler', 'nova-conductor', + 'nova-compute'): + assert(expected_service_name in actual_service_names) + + # Thanks to setup.create_flavors we should have a few flavors already: + assert(len(nova.flavors.list()) > 0) + + # Just checking it's not raising and returning an iterable: + assert(len(nova.servers.list()) >= 0) + + def test_900_restart_on_config_change(self): + """Checking restart happens on config change. + + Change debug mode and assert that change propagates to the correct + file and that services are restarted as a result + """ + # Expected default and alternate values + current_value = zaza.model.get_application_config( + 'nova-cloud-controller')['debug']['value'] + new_value = str(not bool(current_value)).title() + current_value = str(current_value).title() + + set_default = {'debug': current_value} + set_alternate = {'debug': new_value} + default_entry = {'DEFAULT': {'debug': [current_value]}} + alternate_entry = {'DEFAULT': {'debug': [new_value]}} + + # Config file affected by juju set config change + conf_file = '/etc/nova/nova.conf' + + # Make config change, check for service restarts + logging.info( + 'Setting verbose on nova-cloud-controller {}'.format( + set_alternate)) + self.restart_on_changed( + conf_file, + set_default, + set_alternate, + default_entry, + alternate_entry, + self.services) + + def test_901_pause_resume(self): + """Run pause and resume tests. + + Pause service and check services are stopped then resume and check + they are started + """ + with self.pause_resume(self.services): + logging.info("Testing pause resume") + + class SecurityTests(test_utils.OpenStackBaseTest): """nova-compute and nova-cloud-controller security tests.""" From 0f8396b213556dd1da5061849c0a3a2d6fd50f82 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 10:08:28 +0200 Subject: [PATCH 02/11] Fix test_104_compute_api_functionality --- zaza/openstack/charm_tests/nova/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 7a8ff82..0ac4041 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -191,7 +191,7 @@ class NovaCloudController(test_utils.OpenStackBaseTest): logging.info('Checking api functionality...') - actual_service_names = [service['binary'] for service in + actual_service_names = [service.to_dict()['binary'] for service in nova.services.list()] for expected_service_name in ('nova-scheduler', 'nova-conductor', 'nova-compute'): From 7c1f01e3681e897e2a55b093725309ef2267472b Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 12:04:23 +0200 Subject: [PATCH 03/11] Add test_220_nova_metadata_propagate --- zaza/openstack/charm_tests/nova/tests.py | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 0ac4041..4f94316 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -203,6 +203,42 @@ class NovaCloudController(test_utils.OpenStackBaseTest): # Just checking it's not raising and returning an iterable: assert(len(nova.servers.list()) >= 0) + def test_220_nova_metadata_propagate(self): + """Verify that the vendor-data settings are propagated. + + Change vendor-data-url and assert that change propagates to the correct + file and that services are restarted as a result + """ + if self.current_release < self.XENIAL_NEWTON: + logging.info("Feature didn't exist before Newton. Nothing to test") + return + + # Expected default and alternate values + current_value = zaza.model.get_application_config( + 'nova-cloud-controller')['vendor-data-url']['value'] + new_value = 'http://some-other.url/vdata' + + set_default = {'vendor-data-url': current_value} + set_alternate = {'vendor-data-url': new_value} + default_entry = {'api': { + 'vendordata_dynamic_targets': [current_value]}} + alternate_entry = {'api': {'vendordata_dynamic_targets': [new_value]}} + + # Config file affected by juju set config change + conf_file = '/etc/nova/nova.conf' + + # Make config change, check for service restarts + logging.info( + 'Setting config on nova-cloud-controller to {}'.format( + set_alternate)) + self.restart_on_changed( + conf_file, + set_default, + set_alternate, + default_entry, + alternate_entry, + self.services) + def test_900_restart_on_config_change(self): """Checking restart happens on config change. From 071754e7cf56917ac27ea53e7daa613d2ba3693a Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 12:04:33 +0200 Subject: [PATCH 04/11] Add test_302_api_rate_limiting_is_enabled --- zaza/openstack/charm_tests/nova/tests.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 4f94316..800fce0 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -239,6 +239,14 @@ class NovaCloudController(test_utils.OpenStackBaseTest): alternate_entry, self.services) + def test_302_api_rate_limiting_is_enabled(self): + """Check that API rate limiting is enabled.""" + logging.info('Checking api-paste config file data...') + zaza.model.block_until_oslo_config_entries_match( + 'nova-cloud-controller', '/etc/nova/api-paste.ini', { + 'filter:legacy_ratelimit': { + 'limits': ["( POST, '*', .*, 9999, MINUTE );"]}}) + def test_900_restart_on_config_change(self): """Checking restart happens on config change. From 975248f571e3b3e69d2ef9574fc0126c54d5423a Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 13:13:39 +0200 Subject: [PATCH 05/11] Add test_106_compute_catalog_endpoints --- zaza/openstack/charm_tests/nova/tests.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 800fce0..9fac67b 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -203,6 +203,18 @@ class NovaCloudController(test_utils.OpenStackBaseTest): # Just checking it's not raising and returning an iterable: assert(len(nova.servers.list()) >= 0) + def test_106_compute_catalog_endpoints(self): + """Verify that the compute endpoints are present in the catalog.""" + overcloud_auth = openstack_utils.get_overcloud_auth() + keystone_client = openstack_utils.get_keystone_client( + overcloud_auth) + actual_endpoints = keystone_client.service_catalog.get_endpoints() + logging.info('Checking compute endpoints...') + actual_compute_interfaces = [endpoint['interface'] for endpoint in + actual_endpoints['compute']] + for expected_interface in ('internal', 'admin', 'public'): + assert(expected_interface in actual_compute_interfaces) + def test_220_nova_metadata_propagate(self): """Verify that the vendor-data settings are propagated. From 8b8155347ec09b17b1623d482a75ddac9ec7c773 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 18:04:40 +0200 Subject: [PATCH 06/11] Fix typos --- zaza/openstack/charm_tests/test_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zaza/openstack/charm_tests/test_utils.py b/zaza/openstack/charm_tests/test_utils.py index 82fed63..137f096 100644 --- a/zaza/openstack/charm_tests/test_utils.py +++ b/zaza/openstack/charm_tests/test_utils.py @@ -160,7 +160,7 @@ class BaseCharmTest(unittest.TestCase): Workaround: libjuju refuses to accept data with types other than strings - through the zuzu.model.set_application_config + through the zaza.model.set_application_config :param config: Config dictionary with any typed values :type config: Dict[str,Any] @@ -317,7 +317,7 @@ class BaseCharmTest(unittest.TestCase): # If this is not an OSLO config file set default_config={} if default_entry: logging.debug( - 'Waiting for updates to propagate to '.format(config_file)) + 'Waiting for updates to propagate to {}'.format(config_file)) model.block_until_oslo_config_entries_match( self.application_name, config_file, From 1594a09625a80cfa5d04c44f39cb0d43bb57cda7 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Sun, 19 Apr 2020 16:08:11 +0200 Subject: [PATCH 07/11] Fix test_220_nova_metadata_propagate --- zaza/openstack/charm_tests/nova/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 9fac67b..1b32f83 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -161,9 +161,9 @@ class NovaCloudController(test_utils.OpenStackBaseTest): """Run nova-cloud-controller specific tests.""" XENIAL_MITAKA = openstack_utils.get_os_release('xenial_mitaka') - XENIAL_NEWTON = openstack_utils.get_os_release('xenial_newton') XENIAL_OCATA = openstack_utils.get_os_release('xenial_ocata') BIONIC_QUEENS = openstack_utils.get_os_release('bionic_queens') + BIONIC_ROCKY = openstack_utils.get_os_release('bionic_rocky') @classmethod def setUpClass(cls): @@ -221,8 +221,8 @@ class NovaCloudController(test_utils.OpenStackBaseTest): Change vendor-data-url and assert that change propagates to the correct file and that services are restarted as a result """ - if self.current_release < self.XENIAL_NEWTON: - logging.info("Feature didn't exist before Newton. Nothing to test") + if self.current_release < self.BIONIC_ROCKY: + logging.info("Feature didn't exist before Rocky. Nothing to test") return # Expected default and alternate values From 6005ca7517c2c7f31c5221b78efcfe6542c68b50 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 15:15:12 +0200 Subject: [PATCH 08/11] Add test_310_pci_alias_config --- zaza/openstack/charm_tests/nova/tests.py | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 1b32f83..6c5c3b1 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -16,6 +16,7 @@ """Encapsulate nova testing.""" +import json import logging import unittest @@ -259,6 +260,71 @@ class NovaCloudController(test_utils.OpenStackBaseTest): 'filter:legacy_ratelimit': { 'limits': ["( POST, '*', .*, 9999, MINUTE );"]}}) + def test_310_pci_alias_config(self): + """Verify that the pci alias data is rendered properly. + + Change pci-alias and assert that change propagates to the correct + file and that services are restarted as a result + """ + logging.info('Checking pci aliases in nova config...') + + # Expected default and alternate values + current_value = zaza.model.get_application_config( + 'nova-cloud-controller')['pci-alias'] + try: + current_value = current_value['value'] + except KeyError: + current_value = None + new_value = '[{}, {}]'.format( + json.dumps({ + 'name': 'IntelNIC', + 'capability_type': 'pci', + 'product_id': '1111', + 'vendor_id': '8086', + 'device_type': 'type-PF' + }, sort_keys=True), + json.dumps({ + 'name': ' Cirrus Logic ', + 'capability_type': 'pci', + 'product_id': '0ff2', + 'vendor_id': '10de', + 'device_type': 'type-PCI' + }, sort_keys=True)) + + set_default = {'pci-alias': current_value} + set_alternate = {'pci-alias': new_value} + + expected_conf_section = 'DEFAULT' + expected_conf_key = 'pci_alias' + if self.current_release >= self.XENIAL_OCATA: + expected_conf_section = 'pci' + expected_conf_key = 'alias' + + default_entry = {expected_conf_section: {}} + alternate_entry = {expected_conf_section: { + expected_conf_key: [ + ('{"capability_type": "pci", "device_type": "type-PF", ' + '"name": "IntelNIC", "product_id": "1111", ' + '"vendor_id": "8086"}'), + ('{"capability_type": "pci", "device_type": "type-PCI", ' + '"name": " Cirrus Logic ", "product_id": "0ff2", ' + '"vendor_id": "10de"}')]}} + + # Config file affected by juju set config change + conf_file = '/etc/nova/nova.conf' + + # Make config change, check for service restarts + logging.info( + 'Setting config on nova-cloud-controller to {}'.format( + set_alternate)) + self.restart_on_changed( + conf_file, + set_default, + set_alternate, + default_entry, + alternate_entry, + self.services) + def test_900_restart_on_config_change(self): """Checking restart happens on config change. From 13d9702cdb594c74cb6f9c8eff1521fe7064b049 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Fri, 17 Apr 2020 15:28:28 +0200 Subject: [PATCH 09/11] Add test_902_quota_settings --- zaza/openstack/charm_tests/nova/tests.py | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 6c5c3b1..f366629 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -366,6 +366,49 @@ class NovaCloudController(test_utils.OpenStackBaseTest): with self.pause_resume(self.services): logging.info("Testing pause resume") + def test_902_quota_settings(self): + """Verify that the quota settings are propagated. + + Change quota-instances and assert that change propagates to the correct + file and that services are restarted as a result + """ + # Expected default and alternate values + current_value = zaza.model.get_application_config( + 'nova-cloud-controller')['quota-instances'] + try: + current_value = current_value['value'] + except KeyError: + current_value = 0 + new_value = '20' + + set_default = {'quota-instances': current_value} + set_alternate = {'quota-instances': new_value} + + expected_conf_section = 'DEFAULT' + expected_conf_key = 'quota_instances' + if self.current_release >= self.XENIAL_OCATA: + expected_conf_section = 'quota' + expected_conf_key = 'instances' + + default_entry = {expected_conf_section: {}} + alternate_entry = {expected_conf_section: { + expected_conf_key: [new_value]}} + + # Config file affected by juju set config change + conf_file = '/etc/nova/nova.conf' + + # Make config change, check for service restarts + logging.info( + 'Setting config on nova-cloud-controller to {}'.format( + set_alternate)) + self.restart_on_changed( + conf_file, + set_default, + set_alternate, + default_entry, + alternate_entry, + self.services) + class SecurityTests(test_utils.OpenStackBaseTest): """nova-compute and nova-cloud-controller security tests.""" From 9477fd4c525c648a0db6f7e76e5167adcac45f00 Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Mon, 20 Apr 2020 00:53:46 +0200 Subject: [PATCH 10/11] Fix test_106_compute_catalog_endpoints prior to Rocky --- zaza/openstack/charm_tests/nova/tests.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index f366629..922ba0c 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -210,11 +210,18 @@ class NovaCloudController(test_utils.OpenStackBaseTest): keystone_client = openstack_utils.get_keystone_client( overcloud_auth) actual_endpoints = keystone_client.service_catalog.get_endpoints() + logging.info('Checking compute endpoints...') - actual_compute_interfaces = [endpoint['interface'] for endpoint in - actual_endpoints['compute']] - for expected_interface in ('internal', 'admin', 'public'): - assert(expected_interface in actual_compute_interfaces) + + if self.current_release < self.BIONIC_ROCKY: + actual_compute_endpoints = actual_endpoints['compute'][0] + for expected_url in ('internalURL', 'adminURL', 'publicURL'): + assert(expected_url in actual_compute_endpoints) + else: + actual_compute_interfaces = [endpoint['interface'] for endpoint in + actual_endpoints['compute']] + for expected_interface in ('internal', 'admin', 'public'): + assert(expected_interface in actual_compute_interfaces) def test_220_nova_metadata_propagate(self): """Verify that the vendor-data settings are propagated. From 3d11b9c018bf200fb22a8edc5e8e2fa70169f25b Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Mon, 20 Apr 2020 10:51:38 +0200 Subject: [PATCH 11/11] Fix test_106_compute_catalog_endpoints on Queens --- zaza/openstack/charm_tests/nova/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zaza/openstack/charm_tests/nova/tests.py b/zaza/openstack/charm_tests/nova/tests.py index 922ba0c..03faaae 100644 --- a/zaza/openstack/charm_tests/nova/tests.py +++ b/zaza/openstack/charm_tests/nova/tests.py @@ -163,6 +163,7 @@ class NovaCloudController(test_utils.OpenStackBaseTest): XENIAL_MITAKA = openstack_utils.get_os_release('xenial_mitaka') XENIAL_OCATA = openstack_utils.get_os_release('xenial_ocata') + XENIAL_QUEENS = openstack_utils.get_os_release('xenial_queens') BIONIC_QUEENS = openstack_utils.get_os_release('bionic_queens') BIONIC_ROCKY = openstack_utils.get_os_release('bionic_rocky') @@ -213,7 +214,7 @@ class NovaCloudController(test_utils.OpenStackBaseTest): logging.info('Checking compute endpoints...') - if self.current_release < self.BIONIC_ROCKY: + if self.current_release < self.XENIAL_QUEENS: actual_compute_endpoints = actual_endpoints['compute'][0] for expected_url in ('internalURL', 'adminURL', 'publicURL'): assert(expected_url in actual_compute_endpoints)