Merge "port test_quotas into v3 part2"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 80ac9fa..093754c 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -266,6 +266,7 @@
cls.availability_zone_client = cls.os.availability_zone_v3_client
cls.interfaces_client = cls.os.interfaces_v3_client
cls.hypervisor_client = cls.os.hypervisor_v3_client
+ cls.keypairs_client = cls.os.keypairs_v3_client
cls.tenant_usages_client = cls.os.tenant_usages_v3_client
cls.volumes_client = cls.os.volumes_client
cls.certificates_client = cls.os.certificates_v3_client
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index 94175ab..e1bb160 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -24,19 +24,19 @@
from tempest.common.utils import data_utils
from tempest.common.utils.linux.remote_client import RemoteClient
from tempest import config
-from tempest.test import attr
+from tempest import test
CONF = config.CONF
-class ServersTestJSON(base.BaseV2ComputeTest):
+class ServersV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
run_ssh = CONF.compute.run_ssh
disk_config = 'AUTO'
@classmethod
def setUpClass(cls):
- super(ServersTestJSON, cls).setUpClass()
+ super(ServersV3TestJSON, cls).setUpClass()
cls.meta = {'hello': 'world'}
cls.accessIPv4 = '1.1.1.1'
cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
@@ -47,36 +47,37 @@
cls.client = cls.servers_client
cli_resp = cls.create_test_server(name=cls.name,
meta=cls.meta,
- accessIPv4=cls.accessIPv4,
- accessIPv6=cls.accessIPv6,
+ access_ip_v4=cls.accessIPv4,
+ access_ip_v6=cls.accessIPv6,
personality=personality,
disk_config=cls.disk_config)
cls.resp, cls.server_initial = cli_resp
- cls.password = cls.server_initial['adminPass']
+ cls.password = cls.server_initial['admin_password']
cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
resp, cls.server = cls.client.get_server(cls.server_initial['id'])
- @attr(type='smoke')
+ @test.attr(type='smoke')
def test_create_server_response(self):
# Check that the required fields are returned with values
self.assertEqual(202, self.resp.status)
self.assertTrue(self.server_initial['id'] is not None)
- self.assertTrue(self.server_initial['adminPass'] is not None)
+ self.assertTrue(self.server_initial['admin_password'] is not None)
- @attr(type='smoke')
+ @test.attr(type='smoke')
def test_verify_server_details(self):
# Verify the specified server attributes are set correctly
- self.assertEqual(self.accessIPv4, self.server['accessIPv4'])
+ self.assertEqual(self.accessIPv4,
+ self.server['os-access-ips:access_ip_v4'])
# NOTE(maurosr): See http://tools.ietf.org/html/rfc5952 (section 4)
# Here we compare directly with the canonicalized format.
- self.assertEqual(self.server['accessIPv6'],
+ self.assertEqual(self.server['os-access-ips:access_ip_v6'],
str(netaddr.IPAddress(self.accessIPv6)))
self.assertEqual(self.name, self.server['name'])
self.assertEqual(self.image_ref, self.server['image']['id'])
self.assertEqual(self.flavor_ref, self.server['flavor']['id'])
self.assertEqual(self.meta, self.server['metadata'])
- @attr(type='smoke')
+ @test.attr(type='smoke')
def test_list_servers(self):
# The created server should be in the list of all servers
resp, body = self.client.list_servers()
@@ -84,7 +85,7 @@
found = any([i for i in servers if i['id'] == self.server['id']])
self.assertTrue(found)
- @attr(type='smoke')
+ @test.attr(type='smoke')
def test_list_servers_with_detail(self):
# The created server should be in the detailed list of all servers
resp, body = self.client.list_servers_with_detail()
@@ -93,14 +94,14 @@
self.assertTrue(found)
@testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
- @attr(type='gate')
+ @test.attr(type='gate')
def test_can_log_into_created_server(self):
# Check that the user can authenticate with the generated password
linux_client = RemoteClient(self.server, self.ssh_user, self.password)
self.assertTrue(linux_client.can_authenticate())
@testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
- @attr(type='gate')
+ @test.attr(type='gate')
def test_verify_created_server_vcpus(self):
# Verify that the number of vcpus reported by the instance matches
# the amount stated by the flavor
@@ -109,14 +110,14 @@
self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
@testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
- @attr(type='gate')
+ @test.attr(type='gate')
def test_host_name_is_same_as_server_name(self):
# Verify the instance host name is the same as the server name
linux_client = RemoteClient(self.server, self.ssh_user, self.password)
self.assertTrue(linux_client.hostname_equals_servername(self.name))
-class ServersTestManualDisk(ServersTestJSON):
+class ServersV3TestManualDisk(ServersV3TestJSON):
disk_config = 'MANUAL'
@classmethod
@@ -124,8 +125,8 @@
if not CONF.compute_feature_enabled.disk_config:
msg = "DiskConfig extension not enabled."
raise cls.skipException(msg)
- super(ServersTestManualDisk, cls).setUpClass()
+ super(ServersV3TestManualDisk, cls).setUpClass()
-class ServersTestXML(ServersTestJSON):
+class ServersV3TestXML(ServersV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_multiple_create.py b/tempest/api/compute/v3/servers/test_multiple_create.py
index 080bd1a..3ee46ad 100644
--- a/tempest/api/compute/v3/servers/test_multiple_create.py
+++ b/tempest/api/compute/v3/servers/test_multiple_create.py
@@ -18,10 +18,10 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import exceptions
-from tempest.test import attr
+from tempest import test
-class MultipleCreateTestJSON(base.BaseV2ComputeTest):
+class MultipleCreateV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
_name = 'multiple-create-test'
@@ -38,7 +38,7 @@
return resp, body
- @attr(type='gate')
+ @test.attr(type='gate')
def test_multiple_create(self):
resp, body = self._create_multiple_servers(wait_until='ACTIVE',
min_count=1,
@@ -49,31 +49,31 @@
self.assertEqual('202', resp['status'])
self.assertNotIn('reservation_id', body)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_min_count_less_than_one(self):
invalid_min_count = 0
self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
min_count=invalid_min_count)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_min_count_non_integer(self):
invalid_min_count = 2.5
self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
min_count=invalid_min_count)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_max_count_less_than_one(self):
invalid_max_count = 0
self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
max_count=invalid_max_count)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_max_count_non_integer(self):
invalid_max_count = 2.5
self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
max_count=invalid_max_count)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_max_count_less_than_min_count(self):
min_count = 3
max_count = 2
@@ -81,7 +81,7 @@
min_count=min_count,
max_count=max_count)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_multiple_create_with_reservation_return(self):
resp, body = self._create_multiple_servers(wait_until='ACTIVE',
min_count=1,
@@ -91,5 +91,5 @@
self.assertIn('reservation_id', body)
-class MultipleCreateTestXML(MultipleCreateTestJSON):
+class MultipleCreateV3TestXML(MultipleCreateV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_servers.py b/tempest/api/compute/v3/servers/test_servers.py
index d72476d..9eff462 100644
--- a/tempest/api/compute/v3/servers/test_servers.py
+++ b/tempest/api/compute/v3/servers/test_servers.py
@@ -17,31 +17,31 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
-class ServersTestJSON(base.BaseV2ComputeTest):
+class ServersV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(ServersTestJSON, cls).setUpClass()
+ super(ServersV3TestJSON, cls).setUpClass()
cls.client = cls.servers_client
def tearDown(self):
self.clear_servers()
- super(ServersTestJSON, self).tearDown()
+ super(ServersV3TestJSON, self).tearDown()
- @attr(type='gate')
+ @test.attr(type='gate')
def test_create_server_with_admin_password(self):
# If an admin password is provided on server creation, the server's
# root password should be set to that password.
- resp, server = self.create_test_server(adminPass='testpassword')
+ resp, server = self.create_test_server(admin_password='testpassword')
# Verify the password is set correctly in the response
- self.assertEqual('testpassword', server['adminPass'])
+ self.assertEqual('testpassword', server['admin_password'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_create_with_existing_server_name(self):
# Creating a server with a name that already exists is allowed
@@ -60,7 +60,7 @@
name2 = server['name']
self.assertEqual(name1, name2)
- @attr(type='gate')
+ @test.attr(type='gate')
def test_create_specify_keypair(self):
# Specify a keypair while creating a server
@@ -73,7 +73,7 @@
resp, server = self.client.get_server(server['id'])
self.assertEqual(key_name, server['key_name'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_update_server_name(self):
# The server name should be changed to the the provided value
resp, server = self.create_test_server(wait_until='ACTIVE')
@@ -88,46 +88,47 @@
resp, server = self.client.get_server(server['id'])
self.assertEqual('newname', server['name'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_update_access_server_address(self):
# The server's access addresses should reflect the provided values
resp, server = self.create_test_server(wait_until='ACTIVE')
# Update the IPv4 and IPv6 access addresses
resp, body = self.client.update_server(server['id'],
- accessIPv4='1.1.1.1',
- accessIPv6='::babe:202:202')
+ access_ip_v4='1.1.1.1',
+ access_ip_v6='::babe:202:202')
self.assertEqual(200, resp.status)
self.client.wait_for_server_status(server['id'], 'ACTIVE')
# Verify the access addresses have been updated
resp, server = self.client.get_server(server['id'])
- self.assertEqual('1.1.1.1', server['accessIPv4'])
- self.assertEqual('::babe:202:202', server['accessIPv6'])
+ self.assertEqual('1.1.1.1', server['os-access-ips:access_ip_v4'])
+ self.assertEqual('::babe:202:202',
+ server['os-access-ips:access_ip_v6'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_delete_server_while_in_building_state(self):
# Delete a server while it's VM state is Building
resp, server = self.create_test_server(wait_until='BUILD')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_delete_active_server(self):
# Delete a server while it's VM state is Active
resp, server = self.create_test_server(wait_until='ACTIVE')
resp, _ = self.client.delete_server(server['id'])
self.assertEqual('204', resp['status'])
- @attr(type='gate')
+ @test.attr(type='gate')
def test_create_server_with_ipv6_addr_only(self):
# Create a server without an IPv4 address(only IPv6 address).
- resp, server = self.create_test_server(accessIPv6='2001:2001::3')
+ resp, server = self.create_test_server(access_ip_v6='2001:2001::3')
self.assertEqual('202', resp['status'])
self.client.wait_for_server_status(server['id'], 'ACTIVE')
resp, server = self.client.get_server(server['id'])
- self.assertEqual('2001:2001::3', server['accessIPv6'])
+ self.assertEqual('2001:2001::3', server['os-access-ips:access_ip_v6'])
-class ServersTestXML(ServersTestJSON):
+class ServersV3TestXML(ServersV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/test_live_block_migration.py b/tempest/api/compute/v3/test_live_block_migration.py
new file mode 100644
index 0000000..3de50c8
--- /dev/null
+++ b/tempest/api/compute/v3/test_live_block_migration.py
@@ -0,0 +1,173 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# 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 random
+import string
+
+import testtools
+
+from tempest.api.compute import base
+from tempest import config
+from tempest import exceptions
+from tempest.test import attr
+
+
+class LiveBlockMigrationV3TestJSON(base.BaseV3ComputeAdminTest):
+ _host_key = 'os-extended-server-attributes:host'
+ _interface = 'json'
+
+ CONF = config.CONF
+
+ @classmethod
+ def setUpClass(cls):
+ super(LiveBlockMigrationV3TestJSON, cls).setUpClass()
+
+ cls.admin_hosts_client = cls.hosts_admin_client
+ cls.admin_servers_client = cls.servers_admin_client
+
+ cls.created_server_ids = []
+
+ def _get_compute_hostnames(self):
+ _resp, body = self.admin_hosts_client.list_hosts()
+ return [
+ host_record['host_name']
+ for host_record in body
+ if host_record['service'] == 'compute'
+ ]
+
+ def _get_server_details(self, server_id):
+ _resp, body = self.admin_servers_client.get_server(server_id)
+ return body
+
+ def _get_host_for_server(self, server_id):
+ return self._get_server_details(server_id)[self._host_key]
+
+ def _migrate_server_to(self, server_id, dest_host):
+ _resp, body = self.admin_servers_client.live_migrate_server(
+ server_id, dest_host,
+ self.config.compute_feature_enabled.
+ block_migration_for_live_migration)
+ return body
+
+ def _get_host_other_than(self, host):
+ for target_host in self._get_compute_hostnames():
+ if host != target_host:
+ return target_host
+
+ def _get_non_existing_host_name(self):
+ random_name = ''.join(
+ random.choice(string.ascii_uppercase) for x in range(20))
+
+ self.assertNotIn(random_name, self._get_compute_hostnames())
+
+ return random_name
+
+ def _get_server_status(self, server_id):
+ return self._get_server_details(server_id)['status']
+
+ def _get_an_active_server(self):
+ for server_id in self.created_server_ids:
+ if 'ACTIVE' == self._get_server_status(server_id):
+ return server_id
+ else:
+ _, server = self.create_test_server(wait_until="ACTIVE")
+ server_id = server['id']
+ self.password = server['admin_password']
+ self.password = 'password'
+ self.created_server_ids.append(server_id)
+ return server_id
+
+ def _volume_clean_up(self, server_id, volume_id):
+ resp, body = self.volumes_client.get_volume(volume_id)
+ if body['status'] == 'in-use':
+ self.servers_client.detach_volume(server_id, volume_id)
+ self.volumes_client.wait_for_volume_status(volume_id, 'available')
+ self.volumes_client.delete_volume(volume_id)
+
+ @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
+ 'Live migration not available')
+ @attr(type='gate')
+ def test_live_block_migration(self):
+ # Live block migrate an instance to another host
+ if len(self._get_compute_hostnames()) < 2:
+ raise self.skipTest(
+ "Less than 2 compute nodes, skipping migration test.")
+ server_id = self._get_an_active_server()
+ actual_host = self._get_host_for_server(server_id)
+ target_host = self._get_host_other_than(actual_host)
+ self._migrate_server_to(server_id, target_host)
+ self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ self.assertEqual(target_host, self._get_host_for_server(server_id))
+
+ @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
+ 'Live migration not available')
+ @attr(type='gate')
+ def test_invalid_host_for_migration(self):
+ # Migrating to an invalid host should not change the status
+ server_id = self._get_an_active_server()
+ target_host = self._get_non_existing_host_name()
+
+ self.assertRaises(exceptions.BadRequest, self._migrate_server_to,
+ server_id, target_host)
+ self.assertEqual('ACTIVE', self._get_server_status(server_id))
+
+ @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
+ CONF.compute_feature_enabled.
+ block_migration_for_live_migration,
+ 'Block Live migration not available')
+ @testtools.skipIf(not CONF.compute_feature_enabled.
+ block_migrate_cinder_iscsi,
+ 'Block Live migration not configured for iSCSI')
+ @attr(type='gate')
+ def test_iscsi_volume(self):
+ # Live block migrate an instance to another host
+ if len(self._get_compute_hostnames()) < 2:
+ raise self.skipTest(
+ "Less than 2 compute nodes, skipping migration test.")
+ server_id = self._get_an_active_server()
+ actual_host = self._get_host_for_server(server_id)
+ target_host = self._get_host_other_than(actual_host)
+
+ resp, volume = self.volumes_client.create_volume(1,
+ display_name='test')
+
+ self.volumes_client.wait_for_volume_status(volume['id'],
+ 'available')
+ self.addCleanup(self._volume_clean_up, server_id, volume['id'])
+
+ # Attach the volume to the server
+ self.servers_client.attach_volume(server_id, volume['id'],
+ device='/dev/xvdb')
+ self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
+
+ self._migrate_server_to(server_id, target_host)
+ self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ self.assertEqual(target_host, self._get_host_for_server(server_id))
+
+ @classmethod
+ def tearDownClass(cls):
+ for server_id in cls.created_server_ids:
+ cls.servers_client.delete_server(server_id)
+
+ super(LiveBlockMigrationV3TestJSON, cls).tearDownClass()
+
+
+class LiveBlockMigrationV3TestXML(LiveBlockMigrationV3TestJSON):
+ _host_key = (
+ '{http://docs.openstack.org/compute/ext/'
+ 'extended_server_attributes/api/v3}host')
+ _interface = 'xml'
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index f3ef99f..b6c03e0 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -12,8 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import time
-
from tempest import clients
from tempest.common.utils import data_utils
from tempest.openstack.common import log as logging
@@ -118,21 +116,6 @@
cls.clear_keypairs()
super(BaseOrchestrationTest, cls).tearDownClass()
- def wait_for(self, condition):
- """Repeatedly calls condition() until a timeout."""
- start_time = int(time.time())
- while True:
- try:
- condition()
- except Exception:
- pass
- else:
- return
- if int(time.time()) - start_time >= self.build_timeout:
- condition()
- return
- time.sleep(self.build_interval)
-
@staticmethod
def stack_output(stack, output_key):
"""Return a stack output value for a give key."""
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index d63fd8b..643d021 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -15,8 +15,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import time
-
from tempest import clients
from tempest.openstack.common import log as logging
import tempest.test
@@ -107,21 +105,6 @@
except Exception:
pass
- def wait_for(self, condition):
- """Repeatedly calls condition() until a timeout."""
- start_time = int(time.time())
- while True:
- try:
- condition()
- except Exception:
- pass
- else:
- return
- if int(time.time()) - start_time >= self.build_timeout:
- condition()
- return
- time.sleep(self.build_interval)
-
class BaseVolumeV1Test(BaseVolumeTest):
@classmethod
diff --git a/tempest/cli/simple_read_only/test_ceilometer.py b/tempest/cli/simple_read_only/test_ceilometer.py
index 7f2864f..8bdd633 100644
--- a/tempest/cli/simple_read_only/test_ceilometer.py
+++ b/tempest/cli/simple_read_only/test_ceilometer.py
@@ -49,3 +49,6 @@
def test_ceilometermeter_alarm_list(self):
self.ceilometer('alarm-list')
+
+ def test_ceilometer_version(self):
+ self.ceilometer('', flags='--version')
diff --git a/tempest/clients.py b/tempest/clients.py
index 6ff4278..83b72c6 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -238,6 +238,7 @@
self.images_client = ImagesClientXML(*client_args)
self.keypairs_v3_client = KeyPairsV3ClientXML(*client_args)
self.keypairs_client = KeyPairsClientXML(*client_args)
+ self.keypairs_v3_client = KeyPairsV3ClientXML(*client_args)
self.quotas_client = QuotasClientXML(*client_args)
self.quotas_v3_client = QuotasV3ClientXML(*client_args)
self.flavors_client = FlavorsClientXML(*client_args)
@@ -299,6 +300,7 @@
self.images_client = ImagesClientJSON(*client_args)
self.keypairs_v3_client = KeyPairsV3ClientJSON(*client_args)
self.keypairs_client = KeyPairsClientJSON(*client_args)
+ self.keypairs_v3_client = KeyPairsV3ClientJSON(*client_args)
self.quotas_client = QuotasClientJSON(*client_args)
self.quotas_v3_client = QuotasV3ClientJSON(*client_args)
self.flavors_client = FlavorsClientJSON(*client_args)
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index a486801..da31036 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -93,8 +93,8 @@
body = json.loads(body)
# NOTE(maurosr): this deals with the case of multiple server create
# with return reservation id set True
- if 'reservation_id' in body:
- return resp, body
+ if 'servers_reservation' in body:
+ return resp, body['servers_reservation']
return resp, body['server']
def update_server(self, server_id, name=None, meta=None, access_ip_v4=None,
@@ -117,10 +117,10 @@
post_body['name'] = name
if access_ip_v4 is not None:
- post_body['access_ip_v4'] = access_ip_v4
+ post_body['os-access-ips:access_ip_v4'] = access_ip_v4
if access_ip_v6 is not None:
- post_body['access_ip_v6'] = access_ip_v6
+ post_body['os-access-ips:access_ip_v6'] = access_ip_v6
if disk_config is not None:
post_body['os-disk-config:disk_config'] = disk_config
diff --git a/tempest/services/compute/v3/xml/servers_client.py b/tempest/services/compute/v3/xml/servers_client.py
index c3381a3..a5cc291 100644
--- a/tempest/services/compute/v3/xml/servers_client.py
+++ b/tempest/services/compute/v3/xml/servers_client.py
@@ -114,6 +114,10 @@
'/compute/ext/extended_status/api/v3}vm_state')
task_state = ('{http://docs.openstack.org'
'/compute/ext/extended_status/api/v3}task_state')
+ access_ip_v4 = ('{http://docs.openstack.org/compute/ext/'
+ 'os-access-ips/api/v3}access_ip_v4')
+ access_ip_v6 = ('{http://docs.openstack.org/compute/ext/'
+ 'os-access-ips/api/v3}access_ip_v6')
if disk_config in json:
json['os-disk-config:disk_config'] = json.pop(disk_config)
if terminated_at in json:
@@ -129,6 +133,10 @@
json['os-extended-status:vm_state'] = json.pop(vm_state)
if task_state in json:
json['os-extended-status:task_state'] = json.pop(task_state)
+ if access_ip_v4 in json:
+ json['os-access-ips:access_ip_v4'] = json.pop(access_ip_v4)
+ if access_ip_v6 in json:
+ json['os-access-ips:access_ip_v6'] = json.pop(access_ip_v6)
return json
@@ -258,10 +266,14 @@
if name is not None:
server.add_attr("name", name)
+ if access_ip_v4 or access_ip_v6:
+ server.add_attr('xmlns:os-access-ips',
+ "http://docs.openstack.org/compute/ext/"
+ "os-access-ips/api/v3")
if access_ip_v4 is not None:
- server.add_attr("access_ip_v4", access_ip_v4)
+ server.add_attr("os-access-ips:access_ip_v4", access_ip_v4)
if access_ip_v6 is not None:
- server.add_attr("access_ip_v6", access_ip_v6)
+ server.add_attr("os-access-ips:access_ip_v6", access_ip_v6)
if disk_config is not None:
server.add_attr('xmlns:os-disk-config', "http://docs.openstack.org"
"/compute/ext/disk_config/api/v3")
@@ -302,7 +314,6 @@
return_reservation_id: Enable/Disable the return of reservation id.
"""
server = Element("server",
- imageRef=image_ref,
xmlns=XMLNS_V3,
flavor_ref=flavor_ref,
image_ref=image_ref,