Merge "Switch test_volume_boot_pattern to using full image" into mcp/caracal
diff --git a/tempest/api/compute/admin/test_create_server.py b/tempest/api/compute/admin/test_create_server.py
index aa358d7..8bc999a 100644
--- a/tempest/api/compute/admin/test_create_server.py
+++ b/tempest/api/compute/admin/test_create_server.py
@@ -22,6 +22,7 @@
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
CONF = config.CONF
@@ -210,6 +211,55 @@
validation_resources=validation_resources,
wait_until='PINGABLE')
+ def _test_live_migration(self):
+ block_migration = (CONF.compute_feature_enabled.
+ block_migration_for_live_migration)
+ disk_over_commit = False
+ validation_resources = self.get_class_validation_resources(
+ self.os_primary)
+ server_id = self.create_test_server(
+ image_id=self.image_id,
+ flavor=self.flavor_id,
+ validatable=True,
+ validation_resources=validation_resources,
+ wait_until='PINGABLE')['id']
+ source_host = self.get_host_for_server(server_id)
+ if not CONF.compute_feature_enabled.can_migrate_between_any_hosts:
+ # not to specify a host so that the scheduler will pick one
+ destination_host = None
+ else:
+ destination_host = self.get_host_other_than(server_id)
+ self.admin_servers_client.live_migrate_server(
+ server_id,
+ host=destination_host,
+ block_migration=block_migration,
+ disk_over_commit=disk_over_commit)
+ waiters.wait_for_server_status(self.client,
+ server_id, 'ACTIVE')
+ destination_host = self.get_host_for_server(server_id)
+ self.assertNotEqual(source_host, destination_host)
+
+ def _test_cold_migration(self):
+ # Run as admin to allow migrate tpm secret
+ validation_resources = self.get_class_validation_resources(
+ self.os_admin)
+ server_id = self.create_test_server(
+ clients=self.os_admin,
+ image_id=self.image_id,
+ flavor=self.flavor_id,
+ validatable=True,
+ validation_resources=validation_resources,
+ wait_until='PINGABLE')['id']
+ source_host = self.get_host_for_server(server_id)
+ self.admin_servers_client.migrate_server(server_id)
+ waiters.wait_for_server_status(self.admin_servers_client,
+ server_id, 'VERIFY_RESIZE')
+ self.admin_servers_client.confirm_resize_server(server_id)
+ waiters.wait_for_server_status(self.admin_servers_client,
+ server_id, 'ACTIVE')
+ destination_host = self.get_host_for_server(server_id)
+ self.assertNotEqual(source_host, destination_host)
+
class WindowsServers10Test(WindowsServersBaseTest):
@@ -220,6 +270,20 @@
def test_create_server(self):
self._test_create_server()
+ @decorators.attr(type='multinode')
+ @decorators.idempotent_id('6c22fcb1-4c3e-4bf6-b8c7-c3e2322cf5ff')
+ @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
+ 'Live migration is not available.')
+ def test_live_migration(self):
+ self._test_live_migration()
+
+ @decorators.attr(type='multinode')
+ @decorators.idempotent_id('96d67c40-fd4d-4286-a3c7-880d9eb77a95')
+ @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
+ 'Cold migration is not available.')
+ def test_cold_migration(self):
+ self._test_cold_migration()
+
class WindowsServers11Test(WindowsServersBaseTest):
@@ -229,3 +293,18 @@
@decorators.idempotent_id('1cff7fea-f251-4a05-a667-9b946913a3c5')
def test_create_server(self):
self._test_create_server()
+
+ @decorators.attr(type=['negative'])
+ @decorators.idempotent_id('9afd991e-0478-41ca-b5cf-bf32b10ae5a7')
+ @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
+ 'Live migration is not available.')
+ def test_live_migration_with_vtpm_negative(self):
+ """Test live migrating instance with vTPM should not be supported"""
+ self.assertRaises(lib_exc.BadRequest, self._test_live_migration)
+
+ @decorators.attr(type='multinode')
+ @decorators.idempotent_id('7da88453-cc6d-4fef-b893-b4ae8f40767d')
+ @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
+ 'Cold migration is not available.')
+ def test_cold_migration(self):
+ self._test_cold_migration()
diff --git a/tempest/api/compute/servers/test_console.py b/tempest/api/compute/servers/test_console.py
index 0cbeb41..0ebb268 100644
--- a/tempest/api/compute/servers/test_console.py
+++ b/tempest/api/compute/servers/test_console.py
@@ -33,6 +33,10 @@
def setUp(self):
super(ConsoleTestBase, self).setUp()
self._websocket = None
+ self.server = self.create_test_server(wait_until="ACTIVE")
+ self.use_get_remote_console = False
+ if not self.is_requested_microversion_compatible("2.5"):
+ self.use_get_remote_console = True
def tearDown(self):
super(ConsoleTestBase, self).tearDown()
@@ -43,19 +47,6 @@
# server_check_teardown should be called after super's tearDown.
self.server_check_teardown()
- @classmethod
- def setup_clients(cls):
- super(ConsoleTestBase, cls).setup_clients()
- cls.client = cls.servers_client
-
- @classmethod
- def resource_setup(cls):
- super(ConsoleTestBase, cls).resource_setup()
- cls.server = cls.create_test_server(wait_until="ACTIVE")
- cls.use_get_remote_console = False
- if not cls.is_requested_microversion_compatible("2.5"):
- cls.use_get_remote_console = True
-
@property
def cert_params(self):
ssl_opt = {}
@@ -124,10 +115,11 @@
def _get_console_body(self, type, protocol, get_console):
if self.use_get_remote_console:
- return self.client.get_remote_console(
+ return self.servers_client.get_remote_console(
self.server["id"], type=type, protocol=protocol
)["remote_console"]
- return getattr(self.client, get_console)(self.server["id"], type=type)[
+ return getattr(self.servers_client, get_console)(self.server["id"],
+ type=type)[
"console"
]
diff --git a/tempest/api/volume/admin/test_volume_retype.py b/tempest/api/volume/admin/test_volume_retype.py
index 586111c..c17e01c 100644
--- a/tempest/api/volume/admin/test_volume_retype.py
+++ b/tempest/api/volume/admin/test_volume_retype.py
@@ -63,7 +63,7 @@
src_vol = self.create_volume(volume_type=self.src_vol_type['name'],
snapshot_id=snapshot['id'])
- if not CONF.volume_feature_enabled.snapshot_locked_by_volume:
+ if not CONF.volume_feature_enabled.volume_locked_by_snapshot:
# Delete the snapshot
self.snapshots_client.delete_snapshot(snapshot['id'])
self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 62cb203..d4634e6 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -32,10 +32,23 @@
cls.alt_client = cls.os_alt.volume_transfers_client_latest
cls.alt_volumes_client = cls.os_alt.volumes_client_latest
cls.adm_volumes_client = cls.os_admin.volumes_client_latest
+ cls.volume_type_client = cls.os_admin.volume_types_client_latest
+ cls.encryption_client = cls.os_admin.encryption_types_client_latest
+
+ def _check_default_volume_type(self):
+ default_volume_type = self.volume_type_client.\
+ show_default_volume_type()["volume_type"]["id"]
+ volume_encryption = self.encryption_client.show_encryption_type(
+ default_volume_type)
+ if volume_encryption and volume_encryption.get("provider"):
+ raise self.skipException("Not allowed to run this test with "
+ "encrypted volume")
@decorators.idempotent_id('4d75b645-a478-48b1-97c8-503f64242f1a')
def test_create_get_list_accept_volume_transfer(self):
"""Test creating, getting, listing and accepting of volume transfer"""
+ self._check_default_volume_type()
+
# Create a volume first
volume = self.create_volume()
self.addCleanup(self.delete_volume,
@@ -77,6 +90,8 @@
@decorators.idempotent_id('ab526943-b725-4c07-b875-8e8ef87a2c30')
def test_create_list_delete_volume_transfer(self):
"""Test creating, listing and deleting volume transfer"""
+ self._check_default_volume_type()
+
# Create a volume first
volume = self.create_volume()
self.addCleanup(self.delete_volume,
diff --git a/tempest/config.py b/tempest/config.py
index b41ec84..01e65f9 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1133,10 +1133,11 @@
cfg.ListOpt('supported_crypto_providers',
default=['luks'],
help='A list of enabled cryptoproviders for volumes'),
- cfg.BoolOpt('snapshot_locked_by_volume',
+ cfg.BoolOpt('volume_locked_by_snapshot',
default=False,
- help='Whether snapshot can be deleted, i.e. there is no '
- 'volume dependent on (created from) it'),
+ help='Whether the volume is locked by snapshot, i.e. '
+ 'can remove volume only when no dependent '
+ 'snapshot exist.'),
]
diff --git a/tempest/lib/api_schema/response/volume/volume_types.py b/tempest/lib/api_schema/response/volume/volume_types.py
index 51b3a72..4d09bcd 100644
--- a/tempest/lib/api_schema/response/volume/volume_types.py
+++ b/tempest/lib/api_schema/response/volume/volume_types.py
@@ -31,8 +31,7 @@
'qos_specs_id': {'type': ['string', 'null'], 'format': 'uuid'}
},
'additionalProperties': False,
- 'required': ['name', 'is_public', 'description', 'id',
- 'os-volume-type-access:is_public']
+ 'required': ['name', 'is_public', 'description', 'id']
}
show_volume_type = {
diff --git a/tempest/lib/common/preprov_creds.py b/tempest/lib/common/preprov_creds.py
index 8bb41d1..cdc66bf 100644
--- a/tempest/lib/common/preprov_creds.py
+++ b/tempest/lib/common/preprov_creds.py
@@ -114,7 +114,7 @@
object_storage_operator_role=None,
object_storage_reseller_admin_role=None):
hash_dict = {'roles': {}, 'creds': {}, 'networks': {},
- 'scoped_roles': {}}
+ 'scoped_roles': {}, 'projects': {}}
# Loop over the accounts read from the yaml file
for account in accounts:
@@ -180,6 +180,7 @@
'Unknown resource type %s, ignoring this field',
resource
)
+ hash_dict = cls._append_project(account, temp_hash_key, hash_dict)
return hash_dict
def is_multi_user(self):
@@ -246,6 +247,7 @@
hashes = temp_list
else:
hashes = self.hash_dict['creds'].keys()
+ hashes = self._exclude_used_projects(hashes)
# NOTE(mtreinish): admin is a special case because of the increased
# privilege set which could potentially cause issues on tests where
# that is not expected. So unless the admin role isn't specified do
@@ -272,7 +274,8 @@
free_hash = self._get_free_hash(useable_hashes)
clean_creds = self._sanitize_creds(
self.hash_dict['creds'][free_hash])
- LOG.info('%s allocated creds:\n%s', self.name, clean_creds)
+ LOG.info('%s allocated creds for roles %s in scope %s:\n%s',
+ self.name, roles, scope, clean_creds)
return self._wrap_creds_with_network(free_hash)
@lockutils.synchronized('test_accounts_io', external=True)
@@ -310,12 +313,10 @@
# TODO(gmann): Remove this method in favor of get_project_member_creds()
# after the deprecation phase.
def get_primary_creds(self):
- if self._creds.get('primary'):
- return self._creds.get('primary')
- # NOTE(pas-ha) use the same call as get_project_member_creds
- net_creds = self._get_creds(['member'], scope='project')
- self._creds['primary'] = net_creds
- return net_creds
+ # NOTE(pas-ha) force os_primary and os_project_member
+ # to be exactly the same creds, otherwise they may be from
+ # different projects and fail some RBAC tests
+ return self.get_project_member_creds()
# TODO(gmann): Replace this method with more appropriate name.
# like get_project_alt_member_creds()
@@ -479,3 +480,16 @@
for attr in domain_fields.intersection(set(creds_dict.keys())):
creds_dict.pop(attr)
return creds_dict
+
+ @classmethod
+ def _append_project(cls, account, account_hash, hash_dict):
+ key_to_add = account.get('project_name') or account.get('tenant_name')
+ hash_dict['projects'].setdefault(key_to_add, [])
+ hash_dict['projects'][key_to_add].append(account_hash)
+ return hash_dict
+
+ def _exclude_used_projects(self, hashes):
+ excluded_accounts = []
+ for project in [cred.tenant_name for cred in self._creds.values()]:
+ excluded_accounts.extend(self.hash_dict['projects'][project])
+ return hashes - set(excluded_accounts)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index da33412..700ad3b 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -403,7 +403,7 @@
self.os_adm.servers_client.live_migrate_server(
server_id=server['id'],
- block_migration=True,
+ block_migration='auto',
host=host_id)
waiters.wait_for_server_status(