Merge "Add wait for location import task"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index ed94af0..8890109 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -538,6 +538,37 @@
volume['id'], 'available')
return volume
+ @classmethod
+ def verify_metadata_from_api(self, server, ssh_client, verify_method):
+ md_url = 'http://169.254.169.254/openstack/latest/meta_data.json'
+ LOG.info('Attempting to verify tagged devices in server %s via '
+ 'the metadata service: %s', server['id'], md_url)
+
+ def get_and_verify_metadata():
+ try:
+ ssh_client.exec_command('curl -V')
+ except exceptions.SSHExecCommandFailed:
+ if not CONF.compute_feature_enabled.config_drive:
+ raise self.skipException('curl not found in guest '
+ 'and config drive is '
+ 'disabled')
+ LOG.warning('curl was not found in the guest, device '
+ 'tagging metadata was not checked in the '
+ 'metadata API')
+ return True
+ cmd = 'curl %s' % md_url
+ md_json = ssh_client.exec_command(cmd)
+ return verify_method(md_json)
+ # NOTE(gmann) Keep refreshing the metadata info until the metadata
+ # cache is refreshed. For safer side, we will go with wait loop of
+ # build_interval till build_timeout. verify_method() above will return
+ # True if all metadata verification is done as expected.
+ if not test_utils.call_until_true(get_and_verify_metadata,
+ CONF.compute.build_timeout,
+ CONF.compute.build_interval):
+ raise lib_exc.TimeoutException('Timeout while verifying '
+ 'metadata on server.')
+
def _detach_volume(self, server, volume):
"""Helper method to detach a volume.
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index b7db200..0b39b8a 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -16,6 +16,8 @@
import netaddr
import testtools
+from oslo_serialization import jsonutils as json
+
from tempest.api.compute import base
from tempest.common import utils
from tempest.common.utils.linux import remote_client
@@ -235,3 +237,76 @@
servers_client=self.client)
hostname = linux_client.exec_command("hostname").rstrip()
self.assertEqual('guest-instance-1-domain-com', hostname)
+
+
+class ServersV294TestFqdnHostnames(base.BaseV2ComputeTest):
+ """Test creating server with FQDN hostname and verifying attributes
+
+ Starting Antelope release, Nova allows to set hostname as an FQDN
+ type and allows free form characters in hostname using --hostname
+ parameter with API above 2.94 .
+
+ This is to create server with --hostname having FQDN type value having
+ more than 64 characters
+ """
+
+ min_microversion = '2.94'
+
+ @classmethod
+ def setup_credentials(cls):
+ cls.prepare_instance_network()
+ super(ServersV294TestFqdnHostnames, cls).setup_credentials()
+
+ @classmethod
+ def setup_clients(cls):
+ super(ServersV294TestFqdnHostnames, cls).setup_clients()
+ cls.client = cls.servers_client
+
+ @classmethod
+ def resource_setup(cls):
+ super(ServersV294TestFqdnHostnames, cls).resource_setup()
+ cls.validation_resources = cls.get_class_validation_resources(
+ cls.os_primary)
+ cls.accessIPv4 = '1.1.1.1'
+ cls.name = 'guest-instance-1'
+ cls.password = data_utils.rand_password()
+ cls.hostname = 'x' * 52 + '-guest-test.domaintest.com'
+ cls.test_server = cls.create_test_server(
+ validatable=True,
+ validation_resources=cls.validation_resources,
+ wait_until='ACTIVE',
+ name=cls.name,
+ accessIPv4=cls.accessIPv4,
+ adminPass=cls.password,
+ hostname=cls.hostname)
+ cls.server = cls.client.show_server(cls.test_server['id'])['server']
+
+ def verify_metadata_hostname(self, md_json):
+ md_dict = json.loads(md_json)
+ dhcp_domain = CONF.compute_feature_enabled.dhcp_domain
+ if md_dict['hostname'] == f"{self.hostname}{dhcp_domain}":
+ return True
+ else:
+ return False
+
+ @decorators.idempotent_id('e7b05488-f9d5-4fce-91b3-e82216c52017')
+ @testtools.skipUnless(CONF.validation.run_validation,
+ 'Instance validation tests are disabled.')
+ def test_verify_hostname_allows_fqdn(self):
+ """Test to verify --hostname allows FQDN type name scheme
+
+ Verify the hostname has FQDN value and Freeform characters
+ in the hostname are allowed
+ """
+ self.assertEqual(
+ self.hostname, self.server['OS-EXT-SRV-ATTR:hostname'])
+ # Verify that metadata API has correct hostname inside guest
+ linux_client = remote_client.RemoteClient(
+ self.get_server_ip(self.test_server, self.validation_resources),
+ self.ssh_user,
+ self.password,
+ self.validation_resources['keypair']['private_key'],
+ server=self.test_server,
+ servers_client=self.client)
+ self.verify_metadata_from_api(
+ self.test_server, linux_client, self.verify_metadata_hostname)
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index 2640311..d2fdd52 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -23,9 +23,7 @@
from tempest.common import waiters
from tempest import config
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
CONF = config.CONF
@@ -64,36 +62,6 @@
dhcp=True)
super(DeviceTaggingBase, cls).setup_credentials()
- def verify_metadata_from_api(self, server, ssh_client, verify_method):
- md_url = 'http://169.254.169.254/openstack/latest/meta_data.json'
- LOG.info('Attempting to verify tagged devices in server %s via '
- 'the metadata service: %s', server['id'], md_url)
-
- def get_and_verify_metadata():
- try:
- ssh_client.exec_command('curl -V')
- except exceptions.SSHExecCommandFailed:
- if not CONF.compute_feature_enabled.config_drive:
- raise self.skipException('curl not found in guest '
- 'and config drive is '
- 'disabled')
- LOG.warning('curl was not found in the guest, device '
- 'tagging metadata was not checked in the '
- 'metadata API')
- return True
- cmd = 'curl %s' % md_url
- md_json = ssh_client.exec_command(cmd)
- return verify_method(md_json)
- # NOTE(gmann) Keep refreshing the metadata info until the metadata
- # cache is refreshed. For safer side, we will go with wait loop of
- # build_interval till build_timeout. verify_method() above will return
- # True if all metadata verification is done as expected.
- if not test_utils.call_until_true(get_and_verify_metadata,
- CONF.compute.build_timeout,
- CONF.compute.build_interval):
- raise exceptions.TimeoutException('Timeout while verifying '
- 'metadata on server.')
-
def verify_metadata_on_config_drive(self, server, ssh_client,
verify_method):
LOG.info('Attempting to verify tagged devices in server %s via '
diff --git a/tempest/config.py b/tempest/config.py
index bd4a7a1..0fcc71c 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -469,6 +469,15 @@
"the '.' with '-' to comply with fqdn hostname. Nova "
"changed that in Wallaby cycle, if your cloud is older "
"than wallaby then you can keep/make it False."),
+ cfg.StrOpt('dhcp_domain',
+ default='.novalocal',
+ help="Configure a fully-qualified domain name for instance "
+ "hostnames. The value is suffixed to instance hostname "
+ "from the database to construct the hostname that "
+ "appears in the metadata API. To disable this behavior "
+ "(for example in order to correctly support "
+ "microversion's 2.94 FQDN hostnames), set this to the "
+ "empty string."),
cfg.BoolOpt('change_password',
default=False,
help="Does the test environment support changing the admin "
@@ -668,11 +677,11 @@
help="Time in seconds between image operation status "
"checks."),
cfg.ListOpt('container_formats',
- default=['ami', 'ari', 'aki', 'bare', 'ovf', 'ova'],
+ default=['bare', 'ami', 'ari', 'aki', 'ovf', 'ova'],
help="A list of image's container formats "
"users can specify."),
cfg.ListOpt('disk_formats',
- default=['ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2',
+ default=['qcow2', 'raw', 'ami', 'ari', 'aki', 'vhd', 'vmdk',
'vdi', 'iso', 'vhdx'],
help="A list of image's disk formats "
"users can specify.")