diff --git a/whitebox_tempest_plugin/api/compute/base.py b/whitebox_tempest_plugin/api/compute/base.py index 06299bc8..ced4a599 100644 --- a/whitebox_tempest_plugin/api/compute/base.py +++ b/whitebox_tempest_plugin/api/compute/base.py @@ -21,8 +21,8 @@ from tempest.api.compute import base from tempest.common import waiters from tempest import config -from whitebox_tempest_plugin import exceptions from whitebox_tempest_plugin.services import clients +from whitebox_tempest_plugin import utils as whitebox_utils CONF = config.CONF LOG = logging.getLogger(__name__) @@ -99,28 +99,6 @@ class BaseWhiteboxComputeTest(base.BaseV2ComputeAdminTest): return new_image['id'] - def get_ctlplane_address(self, compute_hostname): - """Return the appropriate host address depending on a deployment. - - In TripleO deployments the Undercloud does not have DNS entries for - the compute hosts. This method checks if there are 'DNS' mappings of - the provided hostname to its control plane IP address and returns it. - For Devstack deployments, no such parameters will exist and the method - will just return compute_hostname - - :param compute_hostname: str the compute hostname - :return: The address to be used to access the compute host. For - devstack deployments, this is compute_host itself. For - TripleO, it needs to be looked up in the configuration. - """ - if not CONF.whitebox.ctlplane_addresses: - return compute_hostname - - if compute_hostname in CONF.whitebox.ctlplane_addresses: - return CONF.whitebox.ctlplane_addresses[compute_hostname] - - raise exceptions.CtrlplaneAddressResolutionError(host=compute_hostname) - def list_compute_hosts(self): """Returns a list of all nova-compute hostnames in the deployment. Assumes all are up and running. @@ -133,7 +111,7 @@ class BaseWhiteboxComputeTest(base.BaseV2ComputeAdminTest): def get_server_xml(self, server_id): server = self.servers_client.show_server(server_id) host = server['server']['OS-EXT-SRV-ATTR:host'] - cntrlplane_addr = self.get_ctlplane_address(host) + cntrlplane_addr = whitebox_utils.get_ctlplane_address(host) server_instance_name = self.servers_client.show_server( server_id)['server']['OS-EXT-SRV-ATTR:instance_name'] diff --git a/whitebox_tempest_plugin/api/compute/test_cpu_pinning.py b/whitebox_tempest_plugin/api/compute/test_cpu_pinning.py index 00cdf061..44de9005 100644 --- a/whitebox_tempest_plugin/api/compute/test_cpu_pinning.py +++ b/whitebox_tempest_plugin/api/compute/test_cpu_pinning.py @@ -337,7 +337,7 @@ class CPUThreadPolicyTest(BasePinningTest): """ siblings = {} - host = self.get_ctlplane_address(host) + host = whitebox_utils.get_ctlplane_address(host) virshxml = clients.VirshXMLClient(host) capxml = virshxml.capabilities() root = ET.fromstring(capxml) @@ -490,11 +490,12 @@ class NUMALiveMigrationTest(BasePinningTest): @decorators.skip_because(bug='2007395', bug_type='storyboard') def test_cpu_pinning(self): - host1, host2 = [self.get_ctlplane_address(host) for host in - self.list_compute_hosts()] + host1, host2 = self.list_compute_hosts() + ctlplane1, ctlplane2 = [whitebox_utils.get_ctlplane_address(host) for + host in [host1, host2]] - numaclient_1 = clients.NUMAClient(host1) - numaclient_2 = clients.NUMAClient(host2) + numaclient_1 = clients.NUMAClient(ctlplane1) + numaclient_2 = clients.NUMAClient(ctlplane2) # Get hosts's topology topo_1 = numaclient_1.get_host_topology() @@ -560,9 +561,9 @@ class NUMALiveMigrationTest(BasePinningTest): # Live migrate server_b to server_a's compute, adding the second # NUMA node's CPUs to vcpu_pin_set host_a = self.get_host_other_than(server_b['id']) - host_a_addr = self.get_ctlplane_address(host_a) + host_a_addr = whitebox_utils.get_ctlplane_address(host_a) host_a_sm = clients.NovaServiceManager( - host_a_addr, 'nova-compute', self.os_admin.services_client) + host_a, 'nova-compute', self.os_admin.services_client) numaclient_a = clients.NUMAClient(host_a_addr) topo_a = numaclient_a.get_host_topology() with host_a_sm.config_options( @@ -601,10 +602,11 @@ class NUMALiveMigrationTest(BasePinningTest): def test_emulator_threads(self): # Need 4 CPUs on each host - host1, host2 = [self.get_ctlplane_address(host) for host in - self.list_compute_hosts()] + host1, host2 = self.list_compute_hosts() + ctlplane1, ctlplane2 = [whitebox_utils.get_ctlplane_address(host) for + host in [host1, host2]] - for host in [host1, host2]: + for host in [ctlplane1, ctlplane2]: numaclient = clients.NUMAClient(host) num_cpus = numaclient.get_num_cpus() if num_cpus < 4: @@ -666,7 +668,7 @@ class NUMALiveMigrationTest(BasePinningTest): self.delete_server(server_b['id']) def test_hugepages(self): - host_a, host_b = [self.get_ctlplane_address(host) for host in + host_a, host_b = [whitebox_utils.get_ctlplane_address(host) for host in self.list_compute_hosts()] numaclient_a = clients.NUMAClient(host_a) diff --git a/whitebox_tempest_plugin/api/compute/test_volume_negative.py b/whitebox_tempest_plugin/api/compute/test_volume_negative.py index 19c10735..6a6a356c 100644 --- a/whitebox_tempest_plugin/api/compute/test_volume_negative.py +++ b/whitebox_tempest_plugin/api/compute/test_volume_negative.py @@ -22,6 +22,7 @@ from tempest import config from whitebox_tempest_plugin.api.compute import base from whitebox_tempest_plugin.services import clients +from whitebox_tempest_plugin import utils as whitebox_utils CONF = config.CONF @@ -70,7 +71,9 @@ class VolumesAdminNegativeTest(base.BaseWhiteboxComputeTest, self.assertGreater( len(disks_after_attach), len(disks_before_attach)) - host = self.get_ctlplane_address(server['OS-EXT-SRV-ATTR:host']) + host = whitebox_utils.get_ctlplane_address( + server['OS-EXT-SRV-ATTR:host'] + ) # stop the libvirt service clients.ServiceManager(host, 'libvirt').stop() diff --git a/whitebox_tempest_plugin/services/clients.py b/whitebox_tempest_plugin/services/clients.py index 9f789575..2c6b26a6 100644 --- a/whitebox_tempest_plugin/services/clients.py +++ b/whitebox_tempest_plugin/services/clients.py @@ -27,6 +27,7 @@ from tempest.lib import exceptions as tempest_libexc from whitebox_tempest_plugin.common import waiters from whitebox_tempest_plugin import exceptions +from whitebox_tempest_plugin import utils as whitebox_utils CONF = config.CONF LOG = logging.getLogger(__name__) @@ -35,13 +36,13 @@ LOG = logging.getLogger(__name__) class SSHClient(object): """A client to execute remote commands, based on tempest.lib.common.ssh.""" - def __init__(self, hostname): + def __init__(self, ctlplane_address): self.ssh_key = CONF.whitebox.ctlplane_ssh_private_key_path self.ssh_user = CONF.whitebox.ctlplane_ssh_username - self.hostname = hostname + self.ctlplane_address = ctlplane_address def execute(self, command, container_name=None, sudo=False): - ssh_client = ssh.Client(self.hostname, self.ssh_user, + ssh_client = ssh.Client(self.ctlplane_address, self.ssh_user, key_filename=self.ssh_key) if (CONF.whitebox.containers and container_name): executable = CONF.whitebox.container_runtime @@ -174,20 +175,26 @@ class NovaServiceManager(ServiceManager): """ def __init__(self, host, service, services_client): - super(NovaServiceManager, self).__init__(host, service) + super(NovaServiceManager, self).__init__( + whitebox_utils.get_ctlplane_address(host), + service + ) self.services_client = services_client + self.host = host def start(self): result = self.execute(self.start_command, sudo=True) waiters.wait_for_nova_service_state(self.services_client, - self.hostname, self.service, + self.host, + self.service, 'up') return result def stop(self): result = self.execute(self.stop_command, sudo=True) waiters.wait_for_nova_service_state(self.services_client, - self.hostname, self.service, + self.host, + self.service, 'down') return result diff --git a/whitebox_tempest_plugin/tests/test_base.py b/whitebox_tempest_plugin/tests/test_base.py index 8f5f7519..440d25f6 100644 --- a/whitebox_tempest_plugin/tests/test_base.py +++ b/whitebox_tempest_plugin/tests/test_base.py @@ -15,7 +15,6 @@ import mock from whitebox_tempest_plugin.api.compute import base as compute_base -from whitebox_tempest_plugin import exceptions from whitebox_tempest_plugin.tests import base @@ -48,15 +47,6 @@ class ComputeBaseTestCase(base.WhiteboxPluginTestCase): 'fake-host2': 'fake-ip2'}, group='whitebox') - def test_get_ctlplane_address(self): - self.assertEqual('fake-ip', - self.test_class.get_ctlplane_address('fake-host')) - - @mock.patch.object(compute_base.LOG, 'error') - def test_get_ctlplane_address_keyerror(self, mock_log): - self.assertRaises(exceptions.CtrlplaneAddressResolutionError, - self.test_class.get_ctlplane_address, 'missing-id') - def test_list_compute_hosts(self): self.assertItemsEqual(['fake-host', 'fake-host2'], self.test_class.list_compute_hosts()) diff --git a/whitebox_tempest_plugin/tests/test_utils.py b/whitebox_tempest_plugin/tests/test_utils.py index c9a7b7c0..a53d1fe6 100644 --- a/whitebox_tempest_plugin/tests/test_utils.py +++ b/whitebox_tempest_plugin/tests/test_utils.py @@ -12,12 +12,19 @@ # License for the specific language governing permissions and limitations # under the License. +from whitebox_tempest_plugin import exceptions from whitebox_tempest_plugin.tests import base from whitebox_tempest_plugin import utils class UtilsTestCase(base.WhiteboxPluginTestCase): + def setUp(self): + super(UtilsTestCase, self).setUp() + self.flags(ctlplane_addresses={'fake-host': 'fake-ip', + 'fake-host2': 'fake-ip2'}, + group='whitebox') + def test_normalize_json(self): json = {'2': [2, 3, 1], '1': True, @@ -34,3 +41,11 @@ class UtilsTestCase(base.WhiteboxPluginTestCase): 'y': [3, 4, 5], 'z': [0, 1, 3]}]}, utils.normalize_json(json)) + + def test_get_ctlplane_address(self): + self.assertEqual('fake-ip', + utils.get_ctlplane_address('fake-host')) + + def test_get_ctlplane_address_keyerror(self): + self.assertRaises(exceptions.CtrlplaneAddressResolutionError, + utils.get_ctlplane_address, 'missing-id') diff --git a/whitebox_tempest_plugin/utils.py b/whitebox_tempest_plugin/utils.py index 3358dc1f..d90d8f4a 100644 --- a/whitebox_tempest_plugin/utils.py +++ b/whitebox_tempest_plugin/utils.py @@ -15,12 +15,16 @@ import six from oslo_serialization import jsonutils +from tempest import config +from whitebox_tempest_plugin import exceptions if six.PY2: import contextlib2 as contextlib else: import contextlib +CONF = config.CONF + def normalize_json(json): """Normalizes a JSON dict for consistent equality tests. Sorts the keys, @@ -43,3 +47,26 @@ def normalize_json(json): def multicontext(*context_managers): with contextlib.ExitStack() as stack: yield [stack.enter_context(mgr) for mgr in context_managers] + + +def get_ctlplane_address(compute_hostname): + """Return the appropriate host address depending on a deployment. + + In TripleO deployments the Undercloud does not have DNS entries for + the compute hosts. This method checks if there are 'DNS' mappings of + the provided hostname to its control plane IP address and returns it. + For Devstack deployments, no such parameters will exist and the method + will just return compute_hostname + + :param compute_hostname: str the compute hostname + :return: The address to be used to access the compute host. For + devstack deployments, this is compute_host itself. For TripleO, it needs + to be looked up in the configuration. + """ + if not CONF.whitebox.ctlplane_addresses: + return compute_hostname + + if compute_hostname in CONF.whitebox.ctlplane_addresses: + return CONF.whitebox.ctlplane_addresses[compute_hostname] + + raise exceptions.CtrlplaneAddressResolutionError(host=compute_hostname)