Adding compute server tests
This patch adds following compute server tests
1. create server
2. delete server
3. update server
4. create agent
5. instance migration
6. instance live migration
7. get server passowrd
8. get virtual interfaces
Partially-Implements: blueprint initial-tests-compute
Change-Id: I941e72c1277b3d0a9563fa9de0c51920162263ac
diff --git a/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py
index e2122c4..0de5e47 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py
@@ -14,6 +14,8 @@
# under the License.
from tempest import config
+from tempest import test
+
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
@@ -27,7 +29,7 @@
@classmethod
def skip_checks(cls):
super(AgentsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
+ if not test.is_extension_enabled('os-agents', 'compute'):
raise cls.skipException(
'%s skipped as no compute extensions enabled' % cls.__name__)
@@ -37,3 +39,16 @@
def test_list_agents_rbac(self):
self.rbac_utils.switch_role(self, switchToRbacRole=True)
self.agents_client.list_agents()
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-agents")
+ @decorators.idempotent_id('77d6cae4-1ced-47f7-af2e-3d6a45958fd6')
+ def test_create_agent(self):
+ params = {'hypervisor': 'kvm', 'os': 'win', 'architecture': 'x86',
+ 'version': '7.0', 'url': 'xxx://xxxx/xxx/xxx',
+ 'md5hash': 'add6bb58e139be103324d04d82d8f545'}
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ body = self.agents_client.create_agent(**params)['agent']
+ self.addCleanup(self.agents_client.delete_agent,
+ body['agent_id'])
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
new file mode 100644
index 0000000..39afb4a
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
@@ -0,0 +1,105 @@
+# Copyright 2017 AT&T Corporation.
+# 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 testtools
+
+from tempest.common import waiters
+from tempest import config
+
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.compute import rbac_base as base
+
+CONF = config.CONF
+
+
+class MigrateServerRbacTest(base.BaseV2ComputeRbacTest):
+
+ @classmethod
+ def setup_clients(cls):
+ super(MigrateServerRbacTest, cls).setup_clients()
+ cls.client = cls.servers_client
+ cls.admin_servers_client = cls.os_adm.servers_client
+ cls.hosts_client = cls.os.hosts_client
+
+ def _get_server_details(self, server_id):
+ body = self.client.show_server(server_id)['server']
+ return body
+
+ def _get_host_for_server(self, server_id):
+ return self._get_server_details(server_id)['OS-EXT-SRV-ATTR:host']
+
+ def _get_host_other_than(self, host):
+ for target_host in self._get_compute_hostnames():
+ if host != target_host:
+ return target_host
+
+ def _get_compute_hostnames(self):
+ body = self.hosts_client.list_hosts()['hosts']
+ return [
+ host_record['host_name']
+ for host_record in body
+ if host_record['service'] == 'compute'
+ ]
+
+ def _migrate_server_to(self, server_id, dest_host, volume_backed=False):
+ kwargs = dict()
+ block_migration = getattr(self, 'block_migration', None)
+ if self.block_migration is None:
+ kwargs['disk_over_commit'] = False
+ block_migration = (CONF.compute_feature_enabled.
+ block_migration_for_live_migration and
+ not volume_backed)
+ self.client.live_migrate_server(
+ server_id, host=dest_host, block_migration=block_migration,
+ **kwargs)
+
+ @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
+ 'Cold migration not available.')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-migrate-server:migrate")
+ @decorators.idempotent_id('c6f1607c-9fed-4c00-807e-9ba675b98b1b')
+ def test_cold_migration(self):
+ if CONF.compute.min_compute_nodes < 2:
+ msg = "Less than 2 compute nodes, skipping multinode tests."
+ raise self.skipException(msg)
+
+ server = self.create_test_server(wait_until="ACTIVE")
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ self.client.migrate_server(server['id'])
+ waiters.wait_for_server_status(self.admin_servers_client,
+ server['id'], 'VERIFY_RESIZE')
+
+ @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
+ 'Live migration feature is not enabled.')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-migrate-server:migrate_live")
+ @decorators.idempotent_id('33520834-72c8-4edb-a189-a2e0fc9eb0d3')
+ def test_migration_live(self):
+ if CONF.compute.min_compute_nodes < 2:
+ msg = "Less than 2 compute nodes, skipping multinode tests."
+ raise self.skipException(msg)
+
+ server_id = self.create_test_server(wait_until="ACTIVE",
+ volume_backed=False)['id']
+ actual_host = self._get_host_for_server(server_id)
+ target_host = self._get_host_other_than(actual_host)
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ self._migrate_server_to(server_id, target_host, volume_backed=False)
+ waiters.wait_for_server_status(self.admin_servers_client,
+ server_id, "ACTIVE")
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_password_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_password_rbac.py
index 5ca7b16..3eab333 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_password_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_password_rbac.py
@@ -44,6 +44,14 @@
@rbac_rule_validation.action(
service="nova",
rule="os_compute_api:os-server-password")
- def test_delete_password(self):
+ def test_delete_server_password(self):
self.rbac_utils.switch_role(self, switchToRbacRole=True)
self.client.delete_password(self.server['id'])
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-server-password")
+ @decorators.idempotent_id('f677971a-7d20-493c-977f-6ff0a74b5b2c')
+ def test_get_server_password(self):
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ self.client.show_password(self.server['id'])
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
new file mode 100644
index 0000000..66676d1
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
@@ -0,0 +1,70 @@
+# Copyright 2017 AT&T Corporation.
+# 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 oslo_log import log
+
+from tempest.common import waiters
+
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+from tempest.lib import exceptions
+
+from patrole_tempest_plugin import rbac_exceptions
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.compute import rbac_base as base
+
+LOG = log.getLogger(__name__)
+
+
+class ComputeServersRbacTest(base.BaseV2ComputeRbacTest):
+
+ @classmethod
+ def setup_clients(cls):
+ super(ComputeServersRbacTest, cls).setup_clients()
+ cls.client = cls.servers_client
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:servers:create")
+ @decorators.idempotent_id('4f34c73a-6ddc-4677-976f-71320fa855bd')
+ def test_create_server(self):
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ self.create_test_server(wait_until='ACTIVE')
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:servers:delete")
+ @decorators.idempotent_id('062e3440-e873-4b41-9317-bf6d8be50c12')
+ def test_delete_server(self):
+ server = self.create_test_server(wait_until='ACTIVE')
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ self.client.delete_server(server['id'])
+ waiters.wait_for_server_termination(self.client, server['id'])
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:servers:update")
+ @decorators.idempotent_id('077b17cb-5621-43b9-8adf-5725f0d7a863')
+ def test_update_server(self):
+ server = self.create_test_server(wait_until='ACTIVE')
+ new_name = data_utils.rand_name('server')
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ try:
+ self.client.update_server(server['id'], name=new_name)
+ except exceptions.ServerFault as e:
+ # Some other policy may have blocked it.
+ LOG.info("ServerFault exception caught. Some other policy "
+ "blocked updating of server")
+ raise rbac_exceptions.RbacActionFailed(e)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_virtual_interfaces_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_virtual_interfaces_rbac.py
new file mode 100644
index 0000000..c523e84
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_virtual_interfaces_rbac.py
@@ -0,0 +1,51 @@
+# Copyright 2017 AT&T Corporation.
+# 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 tempest import config
+
+from tempest.lib import decorators
+from tempest.lib import exceptions
+
+from patrole_tempest_plugin import rbac_exceptions
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.compute import rbac_base as base
+
+CONF = config.CONF
+
+
+class ServerVirtualInterfacesRbacTest(base.BaseV2ComputeRbacTest):
+
+ @classmethod
+ def setup_clients(cls):
+ super(ServerVirtualInterfacesRbacTest, cls).setup_clients()
+ cls.client = cls.servers_client
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-virtual-interfaces")
+ @decorators.idempotent_id('fc719ae3-0f73-4689-8378-1b841f0f2818')
+ def test_list_virtual_interfaces(self):
+ server = self.create_test_server(wait_until='ACTIVE')
+ self.rbac_utils.switch_role(self, switchToRbacRole=True)
+ try:
+ self.client.list_virtual_interfaces(server['id'])
+ except exceptions.ServerFault as e:
+ raise rbac_exceptions.RbacActionFailed(e)
+ except exceptions.BadRequest as e:
+ msg = "Listing virtual interfaces is not supported by this cloud."
+ if msg == str(e.resp_body['message']):
+ raise self.skipException(msg)
+ else:
+ raise e