From 20aed992e1188173480ce8ca4cb80fc18642bde1 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 12 Sep 2016 16:19:53 -0700 Subject: [PATCH] Add nova-lxd tempest plugin Add infrastructure support for nova-lxd tempest plugin. To run the tests, run the following command in the tempest tree: tox -e all-plugin -- nova_lxd Change-Id: I030cfd0a38e5fa191baa0acc48a969b3b553fced Signed-off-by: Chuck Short --- nova_lxd_tempest_plugin/README | 3 + nova_lxd_tempest_plugin/__init__.py | 0 nova_lxd_tempest_plugin/plugin.py | 33 +++++ nova_lxd_tempest_plugin/tests/__init__.py | 0 nova_lxd_tempest_plugin/tests/api/__init__.py | 0 .../tests/api/test_create_server.py | 90 +++++++++++++ .../tests/api/test_servers.py | 119 ++++++++++++++++++ .../tests/scenario/__init__.py | 0 setup.cfg | 4 + 9 files changed, 249 insertions(+) create mode 100644 nova_lxd_tempest_plugin/README create mode 100644 nova_lxd_tempest_plugin/__init__.py create mode 100644 nova_lxd_tempest_plugin/plugin.py create mode 100644 nova_lxd_tempest_plugin/tests/__init__.py create mode 100644 nova_lxd_tempest_plugin/tests/api/__init__.py create mode 100644 nova_lxd_tempest_plugin/tests/api/test_create_server.py create mode 100644 nova_lxd_tempest_plugin/tests/api/test_servers.py create mode 100644 nova_lxd_tempest_plugin/tests/scenario/__init__.py diff --git a/nova_lxd_tempest_plugin/README b/nova_lxd_tempest_plugin/README new file mode 100644 index 00000000..c00f2d5c --- /dev/null +++ b/nova_lxd_tempest_plugin/README @@ -0,0 +1,3 @@ +To run tempest specific tests for nova-lxd run the following command: + + tox -e all-plugin -- nova_lxd diff --git a/nova_lxd_tempest_plugin/__init__.py b/nova_lxd_tempest_plugin/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/nova_lxd_tempest_plugin/plugin.py b/nova_lxd_tempest_plugin/plugin.py new file mode 100644 index 00000000..8cfb5e15 --- /dev/null +++ b/nova_lxd_tempest_plugin/plugin.py @@ -0,0 +1,33 @@ +# Copyright 2016 Canonical Ltd +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os + +from tempest.test_discover import plugins + + +class MyPlugin(plugins.TempestPlugin): + def load_tests(self): + base_path = os.path.split(os.path.dirname( + os.path.abspath(__file__)))[0] + test_dir = "nova_lxd_tempest_plugin/tests" + full_test_dir = os.path.join(base_path, test_dir) + return full_test_dir, base_path + + def register_opts(self, conf): + pass + + def get_opt_lists(self): + pass diff --git a/nova_lxd_tempest_plugin/tests/__init__.py b/nova_lxd_tempest_plugin/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/nova_lxd_tempest_plugin/tests/api/__init__.py b/nova_lxd_tempest_plugin/tests/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/nova_lxd_tempest_plugin/tests/api/test_create_server.py b/nova_lxd_tempest_plugin/tests/api/test_create_server.py new file mode 100644 index 00000000..e7a4b445 --- /dev/null +++ b/nova_lxd_tempest_plugin/tests/api/test_create_server.py @@ -0,0 +1,90 @@ +# Copyright 2016 Canonical Ltd +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from pylxd import client + +from tempest.api.compute import base +from tempest.common.utils import data_utils +from tempest import config + +CONF = config.CONF + + +class LXDServersTestJSON(base.BaseV2ComputeAdminTest): + disk_config = 'AUTO' + + @classmethod + def setup_credentials(cls): + cls.prepare_instance_network() + super(LXDServersTestJSON, cls).setup_credentials() + + @classmethod + def setup_clients(cls): + super(LXDServersTestJSON, cls).setup_clients() + cls.client = cls.os_adm.servers_client + cls.flavors_client = cls.os_adm.flavors_client + + @classmethod + def resource_setup(cls): + cls.set_validation_resources() + super(LXDServersTestJSON, cls).resource_setup() + cls.meta = {'hello': 'world'} + cls.accessIPv4 = '1.1.1.1' + cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2' + cls.name = data_utils.rand_name(cls.__name__ + '-server') + cls.password = data_utils.rand_password() + disk_config = cls.disk_config + cls.server_initial = cls.create_test_server( + validatable=True, + wait_until='ACTIVE', + name=cls.name, + metadata=cls.meta, + accessIPv4=cls.accessIPv4, + accessIPv6=cls.accessIPv6, + disk_config=disk_config, + adminPass=cls.password) + cls.server = ( + cls.client.show_server(cls.server_initial['id'])['server']) + + def test_verify_created_server_vcpus(self): + # Verify that the number of vcpus reported by the instance matches + # the amount stated by the flavor + flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor'] + + lxd = client.Client() + profile = lxd.profiles.get( + self.server['OS-EXT-SRV-ATTR:instance_name']) + self.assertEqual( + '%s' % flavor['vcpu'], profile.config['limits.cpu']) + + def test_verify_created_server_memory(self): + # Verify that the memory reported by the instance matches + # the amount stated by the flavor + flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor'] + + lxd = client.Client() + profile = lxd.profiles.get( + self.server['OS-EXT-SRV-ATTR:instance_name']) + self.assertEqual( + '%sMB' % flavor['ram'], profile.config['limits.memory']) + + def test_verify_created_server_disk_size(self): + flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor'] + + lxd = client.Client() + profile = lxd.profiles.get( + self.server['OS-EXT-SRV-ATTR:instance_name']) + self.assertEqual( + '%sGB' % flavor['disk'], profile.devices['root']['size']) diff --git a/nova_lxd_tempest_plugin/tests/api/test_servers.py b/nova_lxd_tempest_plugin/tests/api/test_servers.py new file mode 100644 index 00000000..3e782de0 --- /dev/null +++ b/nova_lxd_tempest_plugin/tests/api/test_servers.py @@ -0,0 +1,119 @@ +# Copyright 2016 Canonical Ltd +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os + +from pylxd import client + +from tempest.api.compute import base +from tempest.common.utils import data_utils +from tempest.common.utils.linux import remote_client +from tempest import config + +CONF = config.CONF + + +class LXDServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest): + disk_config = 'AUTO' + + @classmethod + def setup_credentials(cls): + cls.prepare_instance_network() + super(LXDServersWithSpecificFlavorTestJSON, cls).setup_credentials() + + @classmethod + def setup_clients(cls): + super(LXDServersWithSpecificFlavorTestJSON, cls).setup_clients() + cls.flavor_client = cls.os_adm.flavors_client + cls.client = cls.os_adm.servers_client + + @classmethod + def resource_setup(cls): + cls.set_validation_resources() + + super(LXDServersWithSpecificFlavorTestJSON, cls).resource_setup() + + def test_verify_created_server_ephemeral_disk(self): + # Verify that the ephemeral disk is created when creating server + flavor_base = self.flavors_client.show_flavor( + self.flavor_ref)['flavor'] + + def create_flavor_with_extra_specs(): + flavor_with_eph_disk_name = data_utils.rand_name('eph_flavor') + flavor_with_eph_disk_id = data_utils.rand_int_id(start=1000) + + ram = flavor_base['ram'] + vcpus = flavor_base['vcpus'] + disk = flavor_base['disk'] + + # Create a flavor with extra specs + flavor = (self.flavor_client. + create_flavor(name=flavor_with_eph_disk_name, + ram=ram, vcpus=vcpus, disk=disk, + id=flavor_with_eph_disk_id, + ephemeral=1))['flavor'] + self.addCleanup(flavor_clean_up, flavor['id']) + + return flavor['id'] + + def create_flavor_without_extra_specs(): + flavor_no_eph_disk_name = data_utils.rand_name('no_eph_flavor') + flavor_no_eph_disk_id = data_utils.rand_int_id(start=1000) + + ram = flavor_base['ram'] + vcpus = flavor_base['vcpus'] + disk = flavor_base['disk'] + + # Create a flavor without extra specs + flavor = (self.flavor_client. + create_flavor(name=flavor_no_eph_disk_name, + ram=ram, vcpus=vcpus, disk=disk, + id=flavor_no_eph_disk_id))['flavor'] + self.addCleanup(flavor_clean_up, flavor['id']) + + return flavor['id'] + + def flavor_clean_up(flavor_id): + self.flavor_client.delete_flavor(flavor_id) + self.flavor_client.wait_for_resource_deletion(flavor_id) + + flavor_with_eph_disk_id = create_flavor_with_extra_specs() + + admin_pass = self.image_ssh_password + + server_with_eph_disk = self.create_test_server( + validatable=True, + wait_until='ACTIVE', + adminPass=admin_pass, + flavor=flavor_with_eph_disk_id) + + server_with_eph_disk = self.client.show_server( + server_with_eph_disk['id'])['server'] + + linux_client = remote_client.RemoteClient( + self.get_server_ip(server_with_eph_disk), + self.ssh_user, + admin_pass, + self.validation_resources['keypair']['private_key'], + server=server_with_eph_disk, + servers_client=self.client) + cmd = 'sudo touch /mnt/tempest.txt' + linux_client.exec_command(cmd) + + lxd = client.Client() + profile = lxd.profiles.get(server_with_eph_disk[ + 'OS-EXT-SRV-ATTR:instance_name']) + tempfile = '%s/tempest.txt' % profile.devices['ephemeral0']['source'] + self.assertTrue(os.path.exists(tempfile)) diff --git a/nova_lxd_tempest_plugin/tests/scenario/__init__.py b/nova_lxd_tempest_plugin/tests/scenario/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/setup.cfg b/setup.cfg index 86fab2a1..0564a92e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,6 +25,10 @@ packages = nova/virt/lxd nova/tests +[entry_points] +tempest.test_plugins = + nova-lxd-tempest-plugin = nova_lxd_tempest_plugin.plugin:MyPlugin + [build_sphinx] source-dir = doc/source build-dir = doc/build