Merge "Split out config option registration"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 95a4884..ee2da40 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -359,6 +359,10 @@
# iSCSI volumes (boolean value)
#block_migrate_cinder_iscsi=false
+# Enable VNC console. This configuration value should be same
+# as [nova.vnc]->vnc_enabled in nova.conf (boolean value)
+#vnc_console=false
+
[dashboard]
@@ -635,6 +639,9 @@
# creating containers (string value)
#operator_role=Member
+# User role that has reseller admin (string value)
+#reseller_admin_role=ResellerAdmin
+
[object-storage-feature-enabled]
diff --git a/requirements.txt b/requirements.txt
index a08a437..0bddca3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-pbr>=0.5.21,<1.0
+pbr>=0.6,<1.0
anyjson>=0.3.3
httplib2>=0.7.5
jsonschema>=2.0.0,<3.0.0
@@ -8,18 +8,18 @@
paramiko>=1.9.0
netaddr>=0.7.6
python-glanceclient>=0.9.0
-python-keystoneclient>=0.4.2
+python-keystoneclient>=0.6.0
python-novaclient>=2.15.0
-python-neutronclient>=2.3.3,<3
+python-neutronclient>=2.3.4,<3
python-cinderclient>=1.0.6
python-heatclient>=0.2.3
-python-savannaclient>=0.4.1
-python-swiftclient>=1.5
+python-savannaclient>=0.5.0
+python-swiftclient>=1.6
testresources>=0.2.4
keyring>=1.6.1,<2.0,>=2.1
-testrepository>=0.0.17
+testrepository>=0.0.18
oslo.config>=1.2.0
-six>=1.4.1
+six>=1.5.2
iso8601>=0.1.8
fixtures>=0.3.14
testscenarios>=0.4
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 08d8a0d..4818aa6 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -47,7 +47,7 @@
resp, aggregate = self.client.create_aggregate(name=aggregate_name)
self.assertEqual(200, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
- self.assertEqual(None, aggregate['availability_zone'])
+ self.assertIsNone(aggregate['availability_zone'])
resp, _ = self.client.delete_aggregate(aggregate['id'])
self.assertEqual(200, resp.status)
@@ -175,7 +175,7 @@
self.assertEqual(1, len(aggs))
agg = aggs[0]
self.assertEqual(aggregate_name, agg['name'])
- self.assertEqual(None, agg['availability_zone'])
+ self.assertIsNone(agg['availability_zone'])
self.assertIn(self.host, agg['hosts'])
@attr(type='gate')
@@ -190,7 +190,7 @@
resp, body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, body['name'])
- self.assertEqual(None, body['availability_zone'])
+ self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
@attr(type='gate')
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 8a5f1a5..3b7f221 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -175,6 +175,16 @@
rebuilt_image_id = server['image']['id']
self.assertEqual(self.image_ref_alt, rebuilt_image_id)
+ @test.attr(type='gate')
+ def test_reset_network_inject_network_info(self):
+ # Reset Network of a Server
+ resp, server = self.create_test_server(wait_until='ACTIVE')
+ resp, server_body = self.client.reset_network(server['id'])
+ self.assertEqual(202, resp.status)
+ # Inject the Network Info into Server
+ resp, server_body = self.client.inject_network_info(server['id'])
+ self.assertEqual(202, resp.status)
+
class ServersAdminTestXML(ServersAdminTestJSON):
_host_key = (
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 9cdac55..c8ab5ae 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -48,6 +48,7 @@
def _create_server_get_interfaces(self):
resp, server = self.create_test_server(wait_until='ACTIVE')
resp, ifs = self.client.list_interfaces(server['id'])
+ self.assertEqual(200, resp.status)
resp, body = self.client.wait_for_interface_status(
server['id'], ifs[0]['port_id'], 'ACTIVE')
ifs[0]['port_state'] = body['port_state']
@@ -55,6 +56,7 @@
def _test_create_interface(self, server):
resp, iface = self.client.create_interface(server['id'])
+ self.assertEqual(200, resp.status)
resp, iface = self.client.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface)
@@ -64,6 +66,7 @@
network_id = ifs[0]['net_id']
resp, iface = self.client.create_interface(server['id'],
network_id=network_id)
+ self.assertEqual(200, resp.status)
resp, iface = self.client.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface, network_id=network_id)
@@ -73,12 +76,14 @@
iface = ifs[0]
resp, _iface = self.client.show_interface(server['id'],
iface['port_id'])
+ self.assertEqual(200, resp.status)
self.assertEqual(iface, _iface)
def _test_delete_interface(self, server, ifs):
# NOTE(danms): delete not the first or last, but one in the middle
iface = ifs[1]
- self.client.delete_interface(server['id'], iface['port_id'])
+ resp, _ = self.client.delete_interface(server['id'], iface['port_id'])
+ self.assertEqual(202, resp.status)
_ifs = self.client.list_interfaces(server['id'])[1]
start = int(time.time())
@@ -123,6 +128,33 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
+ @attr(type='gate')
+ def test_add_remove_fixed_ip(self):
+ # Add and Remove the fixed IP to server.
+ server, ifs = self._create_server_get_interfaces()
+ interface_count = len(ifs)
+ self.assertTrue(interface_count > 0)
+ self._check_interface(ifs[0])
+ network_id = ifs[0]['net_id']
+ resp, body = self.client.add_fixed_ip(server['id'],
+ network_id)
+ self.assertEqual(202, resp.status)
+ # Remove the fixed IP from server.
+ server_resp, server_detail = self.os.servers_client.get_server(
+ server['id'])
+ # Get the Fixed IP from server.
+ fixed_ip = None
+ for ip_set in server_detail['addresses']:
+ for ip in server_detail['addresses'][ip_set]:
+ if ip['OS-EXT-IPS:type'] == 'fixed':
+ fixed_ip = ip['addr']
+ break
+ if fixed_ip is not None:
+ break
+ resp, body = self.client.remove_fixed_ip(server['id'],
+ fixed_ip)
+ self.assertEqual(202, resp.status)
+
class AttachInterfacesTestXML(AttachInterfacesTestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
index a00a5b5..e5ec08b 100644
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ b/tempest/api/compute/v3/admin/test_aggregates.py
@@ -46,7 +46,7 @@
resp, aggregate = self.client.create_aggregate(name=aggregate_name)
self.assertEqual(201, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
- self.assertEqual(None, aggregate['availability_zone'])
+ self.assertIsNone(aggregate['availability_zone'])
resp, _ = self.client.delete_aggregate(aggregate['id'])
self.assertEqual(204, resp.status)
@@ -175,7 +175,7 @@
self.assertEqual(1, len(aggs))
agg = aggs[0]
self.assertEqual(aggregate_name, agg['name'])
- self.assertEqual(None, agg['availability_zone'])
+ self.assertIsNone(agg['availability_zone'])
self.assertIn(self.host, agg['hosts'])
@test.attr(type='gate')
@@ -190,7 +190,7 @@
resp, body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, body['name'])
- self.assertEqual(None, body['availability_zone'])
+ self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
@test.attr(type='gate')
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index a3046c7..e1c69d9 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -47,6 +47,7 @@
def _create_server_get_interfaces(self):
resp, server = self.create_test_server(wait_until='ACTIVE')
resp, ifs = self.client.list_interfaces(server['id'])
+ self.assertEqual(200, resp.status)
resp, body = self.client.wait_for_interface_status(
server['id'], ifs[0]['port_id'], 'ACTIVE')
ifs[0]['port_state'] = body['port_state']
@@ -54,6 +55,7 @@
def _test_create_interface(self, server):
resp, iface = self.client.create_interface(server['id'])
+ self.assertEqual(200, resp.status)
resp, iface = self.client.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface)
@@ -63,6 +65,7 @@
network_id = ifs[0]['net_id']
resp, iface = self.client.create_interface(server['id'],
network_id=network_id)
+ self.assertEqual(200, resp.status)
resp, iface = self.client.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface, network_id=network_id)
@@ -72,12 +75,14 @@
iface = ifs[0]
resp, _iface = self.client.show_interface(server['id'],
iface['port_id'])
+ self.assertEqual(200, resp.status)
self.assertEqual(iface, _iface)
def _test_delete_interface(self, server, ifs):
# NOTE(danms): delete not the first or last, but one in the middle
iface = ifs[1]
- self.client.delete_interface(server['id'], iface['port_id'])
+ resp, _ = self.client.delete_interface(server['id'], iface['port_id'])
+ self.assertEqual(202, resp.status)
_ifs = self.client.list_interfaces(server['id'])[1]
start = int(time.time())
@@ -121,3 +126,30 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
+
+ @attr(type='gate')
+ def test_add_remove_fixed_ip(self):
+ # Add and Remove the fixed IP to server.
+ server, ifs = self._create_server_get_interfaces()
+ interface_count = len(ifs)
+ self.assertGreater(interface_count, 0)
+ self._check_interface(ifs[0])
+ network_id = ifs[0]['net_id']
+ resp, body = self.client.add_fixed_ip(server['id'],
+ network_id)
+ self.assertEqual(202, resp.status)
+ server_resp, server_detail = self.servers_client.get_server(
+ server['id'])
+ # Get the Fixed IP from server.
+ fixed_ip = None
+ for ip_set in server_detail['addresses']:
+ for ip in server_detail['addresses'][ip_set]:
+ if ip['type'] == 'fixed':
+ fixed_ip = ip['addr']
+ break
+ if fixed_ip is not None:
+ break
+ # Remove the fixed IP from server.
+ resp, body = self.client.remove_fixed_ip(server['id'],
+ fixed_ip)
+ self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index e642715..406c45a 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -410,3 +410,16 @@
resp, server = self.servers_client.start(self.server_id)
self.assertEqual(202, resp.status)
self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+
+ @testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
+ 'VNC Console feature is disabled')
+ @test.attr(type='gate')
+ def test_get_vnc_console(self):
+ # Get the VNC console
+ console_types = ['novnc', 'xvpvnc']
+ for console_type in console_types:
+ resp, body = self.servers_client.get_vnc_console(self.server_id,
+ console_type)
+ self.assertEqual(200, resp.status)
+ self.assertEqual(console_type, body['type'])
+ self.assertNotEqual('', body['url'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 78ecf93..05b704f 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -125,7 +125,7 @@
self.assertEqual(interface2, endpoint['interface'])
self.assertEqual(url2, endpoint['url'])
self.assertEqual(region2, endpoint['region'])
- self.assertEqual('False', str(endpoint['enabled']))
+ self.assertEqual('false', str(endpoint['enabled']).lower())
self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 2a5401f..d448c01 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -70,7 +70,7 @@
@attr(type='gate')
def test_delete_image(self):
- # Deletes a image by image_id
+ # Deletes an image by image_id
# Create image
image_name = data_utils.rand_name('image')
@@ -90,6 +90,43 @@
self.assertEqual(resp.status, 200)
self.assertNotIn(image_id, images)
+ @attr(type='gate')
+ def test_update_image(self):
+ # Updates an image by image_id
+
+ # Create image
+ image_name = data_utils.rand_name('image')
+ resp, body = self.client.create_image(name=image_name,
+ container_format='bare',
+ disk_format='iso',
+ visibility='public')
+ self.assertEqual(201, resp.status)
+ self.assertEqual('queued', body['status'])
+ image_id = body['id']
+
+ # Now try uploading an image file
+ file_content = '*' * 1024
+ image_file = StringIO.StringIO(file_content)
+ resp, body = self.client.store_image(image_id, image_file)
+ self.assertEqual(204, resp.status)
+
+ # Update Image
+ new_image_name = data_utils.rand_name('new-image')
+ new_visibility = 'private'
+ resp, body = self.client.update_image(image_id, [
+ dict(replace='/name', value=new_image_name),
+ dict(replace='/visibility', value=new_visibility)])
+
+ self.assertEqual(200, resp.status)
+
+ # Verifying updating
+
+ resp, body = self.client.get_image(image_id)
+ self.assertEqual(200, resp.status)
+ self.assertEqual(image_id, body['id'])
+ self.assertEqual(new_image_name, body['name'])
+ self.assertEqual(new_visibility, body['visibility'])
+
class ListImagesTest(base.BaseV2ImageTest):
"""
@@ -212,3 +249,19 @@
self.assertEqual(len(images_list), params['limit'],
"Failed to get images by limit")
+
+ @attr(type='gate')
+ def test_get_image_schema(self):
+ # Test to get image schema
+ schema = "image"
+ resp, body = self.client.get_schema(schema)
+ self.assertEqual(200, resp.status)
+ self.assertEqual("image", body['name'])
+
+ @attr(type='gate')
+ def test_get_images_schema(self):
+ # Test to get images schema
+ schema = "images"
+ resp, body = self.client.get_schema(schema)
+ self.assertEqual(200, resp.status)
+ self.assertEqual("images", body['name'])
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 41fc49d..530262f 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -22,6 +22,7 @@
image_id = self._create_image()
resp, member = self.os_img_client.add_member(image_id,
self.alt_tenant_id)
+ self.assertEqual(200, resp.status)
self.assertEqual(member['member_id'], self.alt_tenant_id)
self.assertEqual(member['image_id'], image_id)
self.assertEqual(member['status'], 'pending')
@@ -30,7 +31,8 @@
self.alt_tenant_id,
'accepted')
self.assertIn(image_id, self._list_image_ids_as_alt())
- _, body = self.os_img_client.get_image_membership(image_id)
+ resp, body = self.os_img_client.get_image_membership(image_id)
+ self.assertEqual(200, resp.status)
members = body['members']
member = members[0]
self.assertEqual(len(members), 1, str(members))
@@ -43,11 +45,44 @@
image_id = self._create_image()
resp, member = self.os_img_client.add_member(image_id,
self.alt_tenant_id)
+ self.assertEqual(200, resp.status)
self.assertEqual(member['member_id'], self.alt_tenant_id)
self.assertEqual(member['image_id'], image_id)
self.assertEqual(member['status'], 'pending')
self.assertNotIn(image_id, self._list_image_ids_as_alt())
+ resp, _ = self.alt_img_client.update_member_status(image_id,
+ self.alt_tenant_id,
+ 'rejected')
+ self.assertEqual(200, resp.status)
+ self.assertNotIn(image_id, self._list_image_ids_as_alt())
+
+ @attr(type='gate')
+ def test_get_image_member(self):
+ image_id = self._create_image()
+ self.os_img_client.add_member(image_id,
+ self.alt_tenant_id)
self.alt_img_client.update_member_status(image_id,
self.alt_tenant_id,
- 'rejected')
+ 'accepted')
+
+ self.assertIn(image_id, self._list_image_ids_as_alt())
+ resp, member = self.os_img_client.get_member(image_id,
+ self.alt_tenant_id)
+ self.assertEqual(200, resp.status)
+ self.assertEqual(self.alt_tenant_id, member['member_id'])
+ self.assertEqual(image_id, member['image_id'])
+ self.assertEqual('accepted', member['status'])
+
+ @attr(type='gate')
+ def test_remove_image_member(self):
+ image_id = self._create_image()
+ self.os_img_client.add_member(image_id,
+ self.alt_tenant_id)
+ self.alt_img_client.update_member_status(image_id,
+ self.alt_tenant_id,
+ 'accepted')
+
+ self.assertIn(image_id, self._list_image_ids_as_alt())
+ resp = self.os_img_client.remove_member(image_id, self.alt_tenant_id)
+ self.assertEqual(204, resp.status)
self.assertNotIn(image_id, self._list_image_ids_as_alt())
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index dd888a6..8720985 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -53,8 +53,6 @@
# Default to ipv4.
_ip_version = 4
- _tenant_network_cidr = CONF.network.tenant_network_cidr
- _tenant_network_mask_bits = CONF.network.tenant_network_mask_bits
@classmethod
def setUpClass(cls):
@@ -147,8 +145,12 @@
def create_subnet(cls, network):
"""Wrapper utility that returns a test subnet."""
# The cidr and mask_bits depend on the ip version.
- cidr = netaddr.IPNetwork(cls._tenant_network_cidr)
- mask_bits = cls._tenant_network_mask_bits
+ if cls._ip_version == 4:
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+ mask_bits = CONF.network.tenant_network_mask_bits
+ elif cls._ip_version == 6:
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+ mask_bits = CONF.network.tenant_network_v6_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
body = None
failure = None
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 304b2ca..b278002 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -38,11 +38,13 @@
self.assertNotIn(router_id, routers_list)
def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
- resp, _ = self.client.remove_router_interface_with_subnet_id(
+ resp, body = self.client.remove_router_interface_with_subnet_id(
router_id, subnet_id)
self.assertEqual('200', resp['status'])
+ self.assertEqual(subnet_id, body['subnet_id'])
def _remove_router_interface_with_port_id(self, router_id, port_id):
- resp, _ = self.client.remove_router_interface_with_port_id(
+ resp, body = self.client.remove_router_interface_with_port_id(
router_id, port_id)
self.assertEqual('200', resp['status'])
+ self.assertEqual(port_id, body['port_id'])
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index aba2c8e..654552d 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -85,8 +85,12 @@
updated_net = body['network']
self.assertEqual(updated_net['name'], new_name)
# Find a cidr that is not in use yet and create a subnet with it
- cidr = netaddr.IPNetwork(self._tenant_network_cidr)
- mask_bits = self._tenant_network_mask_bits
+ if self._ip_version == 4:
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+ mask_bits = CONF.network.tenant_network_mask_bits
+ elif self._ip_version == 6:
+ cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+ mask_bits = CONF.network.tenant_network_v6_mask_bits
for subnet_cidr in cidr.subnet(mask_bits):
try:
resp, body = self.client.create_subnet(
@@ -464,8 +468,6 @@
class NetworksIpV6TestJSON(NetworksTestJSON):
_ip_version = 6
- _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
- _tenant_network_mask_bits = CONF.network.tenant_network_v6_mask_bits
@classmethod
def setUpClass(cls):
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 0ff91ab..2657031 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -256,3 +256,48 @@
def _delete_extra_routes(self, router_id):
resp, _ = self.client.delete_extra_routes(router_id)
+
+ @test.attr(type='smoke')
+ def test_update_router_admin_state(self):
+ self.router = self.create_router(data_utils.rand_name('router-'))
+ self.assertFalse(self.router['admin_state_up'])
+ # Update router admin state
+ resp, update_body = self.client.update_router(self.router['id'],
+ admin_state_up=True)
+ self.assertEqual('200', resp['status'])
+ self.assertTrue(update_body['router']['admin_state_up'])
+ resp, show_body = self.client.show_router(self.router['id'])
+ self.assertEqual('200', resp['status'])
+ self.assertTrue(show_body['router']['admin_state_up'])
+
+ @test.attr(type='smoke')
+ def test_add_multiple_router_interfaces(self):
+ network = self.create_network()
+ subnet01 = self.create_subnet(network)
+ subnet02 = self.create_subnet(network)
+ router = self.create_router(data_utils.rand_name('router-'))
+ interface01 = self._add_router_interface_with_subnet_id(router['id'],
+ subnet01['id'])
+ self._verify_router_interface(router['id'], subnet01['id'],
+ interface01['port_id'])
+ interface02 = self._add_router_interface_with_subnet_id(router['id'],
+ subnet02['id'])
+ self._verify_router_interface(router['id'], subnet02['id'],
+ interface02['port_id'])
+
+ def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
+ resp, interface = self.client.add_router_interface_with_subnet_id(
+ router_id, subnet_id)
+ self.assertEqual('200', resp['status'])
+ self.addCleanup(self._remove_router_interface_with_subnet_id,
+ router_id, subnet_id)
+ self.assertEqual(subnet_id, interface['subnet_id'])
+ return interface
+
+ def _verify_router_interface(self, router_id, subnet_id, port_id):
+ resp, show_port_body = self.client.show_port(port_id)
+ self.assertEqual('200', resp['status'])
+ interface_port = show_port_body['port']
+ self.assertEqual(router_id, interface_port['device_id'])
+ self.assertEqual(subnet_id,
+ interface_port['fixed_ips'][0]['subnet_id'])
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 788292d..b14adc0 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -17,9 +17,12 @@
from tempest.api.object_storage import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest import test
+CONF = config.CONF
+
class AccountQuotasTest(base.BaseObjectTest):
@@ -41,7 +44,7 @@
try:
_, roles = cls.os_admin.identity_client.list_roles()
reseller_role_id = next(r['id'] for r in roles if r['name']
- == 'ResellerAdmin')
+ == CONF.object_storage.reseller_admin_role)
except StopIteration:
msg = "No ResellerAdmin role found"
raise exceptions.NotFound(msg)
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index cab307d..402cd90 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -17,9 +17,12 @@
from tempest.api.object_storage import base
from tempest import clients
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest import test
+CONF = config.CONF
+
class AccountQuotasNegativeTest(base.BaseObjectTest):
@@ -41,7 +44,7 @@
try:
_, roles = cls.os_admin.identity_client.list_roles()
reseller_role_id = next(r['id'] for r in roles if r['name']
- == 'ResellerAdmin')
+ == CONF.object_storage.reseller_admin_role)
except StopIteration:
msg = "No ResellerAdmin role found"
raise exceptions.NotFound(msg)
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 3e621f4..291f0d1 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -135,7 +135,7 @@
# the cause of the server not signalling the waitcondition
# to heat.
resp, body = cls.client.get_resource(cls.stack_identifier,
- 'SmokeServerNeutron')
+ 'Server')
server_id = body['physical_resource_id']
LOG.debug('Console output for %s', server_id)
resp, output = cls.servers_client.get_console_output(
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
new file mode 100644
index 0000000..5921a7a
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+#
+# Author: Chmouel Boudjnah <chmouel@enovance.com>
+#
+# 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.api.orchestration import base
+from tempest import clients
+from tempest.common.utils import data_utils
+from tempest import config
+
+
+CONF = config.CONF
+
+
+class SwiftResourcesTestJSON(base.BaseOrchestrationTest):
+ _interface = 'json'
+ template = """
+heat_template_version: 2013-05-23
+description: Template which creates a Swift container ressource
+
+resources:
+ SwiftContainerWebsite:
+ DeletionPolicy: "Delete"
+ Type: OS::Swift::Container
+ Properties:
+ X-Container-Read: ".r:*"
+ X-Container-Meta:
+ web-index: "index.html"
+ web-error: "error.html"
+
+ SwiftContainer:
+ Type: OS::Swift::Container
+
+outputs:
+ WebsiteURL:
+ description: "URL for website hosted on S3"
+ value: { get_attr: [SwiftContainer, WebsiteURL] }
+ DomainName:
+ description: "Domain of Swift host"
+ value: { get_attr: [SwiftContainer, DomainName] }
+
+"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(SwiftResourcesTestJSON, cls).setUpClass()
+ cls.client = cls.orchestration_client
+ cls.stack_name = data_utils.rand_name('heat')
+ os = clients.Manager()
+ if not CONF.service_available.swift:
+ raise cls.skipException("Swift support is required")
+ cls.account_client = os.account_client
+ cls.container_client = os.container_client
+ # create the stack
+ cls.stack_identifier = cls.create_stack(
+ cls.stack_name,
+ cls.template)
+ cls.stack_id = cls.stack_identifier.split('/')[1]
+ cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
+ cls.test_resources = {}
+ _, resources = cls.client.list_resources(cls.stack_identifier)
+ for resource in resources:
+ cls.test_resources[resource['logical_resource_id']] = resource
+
+ def test_created_resources(self):
+ """Created stack should be on the list of existing stacks."""
+ resources = [('SwiftContainer', 'OS::Swift::Container'),
+ ('SwiftContainerWebsite', 'OS::Swift::Container')]
+ for resource_name, resource_type in resources:
+ resource = self.test_resources.get(resource_name)
+ self.assertIsInstance(resource, dict)
+ self.assertEqual(resource_type, resource['resource_type'])
+ self.assertEqual(resource_name, resource['logical_resource_id'])
+ self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
+
+ def test_created_containers(self):
+ params = {'format': 'json'}
+ resp, container_list = \
+ self.account_client.list_account_containers(params=params)
+ self.assertEqual('200', resp['status'])
+ self.assertEqual(2, len(container_list))
+ for cont in container_list:
+ self.assertTrue(cont['name'].startswith(self.stack_name))
+
+ def test_acl(self):
+ acl_headers = ('x-container-meta-web-index', 'x-container-read')
+
+ swcont = self.test_resources.get(
+ 'SwiftContainer')['physical_resource_id']
+ swcont_website = self.test_resources.get(
+ 'SwiftContainerWebsite')['physical_resource_id']
+
+ headers, _ = self.container_client.list_container_metadata(swcont)
+ for h in acl_headers:
+ self.assertNotIn(h, headers)
+ headers, _ = self.container_client.list_container_metadata(
+ swcont_website)
+ for h in acl_headers:
+ self.assertIn(h, headers)
+
+ def test_metadata(self):
+ metadatas = {
+ "web-index": "index.html",
+ "web-error": "error.html"
+ }
+ swcont_website = self.test_resources.get(
+ 'SwiftContainerWebsite')['physical_resource_id']
+ headers, _ = self.container_client.list_container_metadata(
+ swcont_website)
+
+ for meta in metadatas:
+ header_meta = "x-container-meta-%s" % meta
+ self.assertIn(header_meta, headers)
+ self.assertEqual(headers[header_meta], metadatas[meta])
diff --git a/tempest/config.py b/tempest/config.py
index 8e31388..0f5e23c 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -263,7 +263,11 @@
cfg.BoolOpt('block_migrate_cinder_iscsi',
default=False,
help="Does the test environment block migration support "
- "cinder iSCSI volumes")
+ "cinder iSCSI volumes"),
+ cfg.BoolOpt('vnc_console',
+ default=False,
+ help='Enable VNC console. This configuration value should '
+ 'be same as [nova.vnc]->vnc_enabled in nova.conf')
]
@@ -472,6 +476,9 @@
default='Member',
help="Role to add to users created for swift tests to "
"enable creating containers"),
+ cfg.StrOpt('reseller_admin_role',
+ default='ResellerAdmin',
+ help="User role that has reseller admin"),
]
object_storage_feature_group = cfg.OptGroup(
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 4c3a01c..1b1ddab 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -606,7 +606,7 @@
:param floating_ip: type DeletableFloatingIp
"""
floating_ip.update(port_id=None)
- self.assertEqual(None, floating_ip.port_id)
+ self.assertIsNone(floating_ip.port_id)
return floating_ip
def _ping_ip_address(self, ip_address, should_succeed=True):
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index e26f570..700a29b 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -15,14 +15,14 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class AggregatesClientJSON(RestClient):
+class AggregatesClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(AggregatesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index ea4e95e..9278d5b 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class AvailabilityZoneClientJSON(RestClient):
+class AvailabilityZoneClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(AvailabilityZoneClientJSON, self).__init__(
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index de0f1a8..c05e352 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class CertificatesClientJSON(RestClient):
+class CertificatesClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(CertificatesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index f7e2737..5ad8b98 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class ExtensionsClientJSON(RestClient):
+class ExtensionsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(ExtensionsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index af750a3..8b2c6c9 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class FixedIPsClientJSON(RestClient):
+class FixedIPsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(FixedIPsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 289b09e..a8111af 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -16,13 +16,13 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class FlavorsClientJSON(RestClient):
+class FlavorsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(FlavorsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 0385160..42487c3 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -16,14 +16,14 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class FloatingIPsClientJSON(RestClient):
+class FloatingIPsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(FloatingIPsClientJSON, self).__init__(auth_provider)
self.service = CONF.compute.catalog_type
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index d826a78..fb45997 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -15,13 +15,13 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class HostsClientJSON(RestClient):
+class HostsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(HostsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 74844dc..c6b13b0 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class HypervisorClientJSON(RestClient):
+class HypervisorClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(HypervisorClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index b3d8c35..5a79a29 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -16,7 +16,7 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest.common import waiters
from tempest import config
from tempest import exceptions
@@ -24,7 +24,7 @@
CONF = config.CONF
-class ImagesClientJSON(RestClient):
+class ImagesClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(ImagesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 27930f2..1f6e988 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class InstanceUsagesAuditLogClientJSON(RestClient):
+class InstanceUsagesAuditLogClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(InstanceUsagesAuditLogClientJSON, self).__init__(
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index f4c4c64..9928b94 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -16,14 +16,14 @@
import json
import time
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class InterfacesClientJSON(RestClient):
+class InterfacesClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(InterfacesClientJSON, self).__init__(auth_provider)
@@ -80,3 +80,25 @@
raise exceptions.TimeoutException(message)
return resp, body
+
+ def add_fixed_ip(self, server_id, network_id):
+ """Add a fixed IP to input server instance."""
+ post_body = json.dumps({
+ 'addFixedIp': {
+ 'networkId': network_id
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = json.dumps({
+ 'removeFixedIp': {
+ 'address': ip_address
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 356c2e6..28f3c31 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class KeyPairsClientJSON(RestClient):
+class KeyPairsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(KeyPairsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 765ba79..1493718 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class LimitsClientJSON(RestClient):
+class LimitsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(LimitsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 7607cc0..459ab6d 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -15,13 +15,13 @@
import json
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class QuotasClientJSON(RestClient):
+class QuotasClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(QuotasClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 2cd2d2e..899d4ef 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -16,14 +16,14 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class SecurityGroupsClientJSON(RestClient):
+class SecurityGroupsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(SecurityGroupsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 025c4e5..623bf42 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -18,7 +18,7 @@
import time
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest.common import waiters
from tempest import config
from tempest import exceptions
@@ -26,7 +26,7 @@
CONF = config.CONF
-class ServersClientJSON(RestClient):
+class ServersClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(ServersClientJSON, self).__init__(auth_provider)
@@ -428,3 +428,11 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def reset_network(self, server_id, **kwargs):
+ """Resets the Network of a server"""
+ return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+ def inject_network_info(self, server_id, **kwargs):
+ """Inject the Network Info into server"""
+ return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 8380dc2..1ab25ec 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -17,13 +17,13 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class ServicesClientJSON(RestClient):
+class ServicesClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(ServicesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index b14fa9b..f3a67dd 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -16,13 +16,13 @@
import json
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
CONF = config.CONF
-class TenantUsagesClientJSON(RestClient):
+class TenantUsagesClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(TenantUsagesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 4b9dc0b..5ef11ed 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -17,14 +17,14 @@
import time
import urllib
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
from tempest import config
from tempest import exceptions
CONF = config.CONF
-class VolumesExtensionsClientJSON(RestClient):
+class VolumesExtensionsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(VolumesExtensionsClientJSON, self).__init__(
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
index c167520..f8b9d09 100644
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ b/tempest/services/compute/v3/json/interfaces_client.py
@@ -81,3 +81,25 @@
raise exceptions.TimeoutException(message)
return resp, body
+
+ def add_fixed_ip(self, server_id, network_id):
+ """Add a fixed IP to input server instance."""
+ post_body = json.dumps({
+ 'add_fixed_ip': {
+ 'network_id': network_id
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = json.dumps({
+ 'remove_fixed_ip': {
+ 'address': ip_address
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 840e914..819e366 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -423,3 +423,15 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def get_vnc_console(self, server_id, type):
+ """Get URL of VNC console."""
+ post_body = json.dumps({
+ "get_vnc_console": {
+ "type": type
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ body = json.loads(body)
+ return resp, body['console']
diff --git a/tempest/services/compute/xml/interfaces_client.py b/tempest/services/compute/xml/interfaces_client.py
index 5df6187..8d4bfcc 100644
--- a/tempest/services/compute/xml/interfaces_client.py
+++ b/tempest/services/compute/xml/interfaces_client.py
@@ -24,6 +24,7 @@
from tempest.services.compute.xml.common import Element
from tempest.services.compute.xml.common import Text
from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml.common import XMLNS_11
CONF = config.CONF
@@ -104,3 +105,21 @@
(port_id, status, self.build_timeout))
raise exceptions.TimeoutException(message)
return resp, body
+
+ def add_fixed_ip(self, server_id, network_id):
+ """Add a fixed IP to input server instance."""
+ post_body = Element("addFixedIp",
+ xmlns=XMLNS_11,
+ networkId=network_id)
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ str(Document(post_body)))
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = Element("removeFixedIp",
+ xmlns=XMLNS_11,
+ address=ip_address)
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ str(Document(post_body)))
+ return resp, body
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index da01b83..cd2cb06 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -633,3 +633,11 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def reset_network(self, server_id, **kwargs):
+ """Resets the Network of a server"""
+ return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+ def inject_network_info(self, server_id, **kwargs):
+ """Inject the Network Info into server"""
+ return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
index a32eede..d79ea92 100644
--- a/tempest/services/identity/v3/xml/endpoints_client.py
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -67,6 +67,8 @@
"""Create endpoint."""
region = kwargs.get('region', None)
enabled = kwargs.get('enabled', None)
+ if enabled is not None:
+ enabled = str(enabled).lower()
create_endpoint = Element("endpoint",
xmlns=XMLNS,
service_id=service_id,
@@ -93,7 +95,7 @@
if region:
endpoint.add_attr("region", region)
if enabled is not None:
- endpoint.add_attr("enabled", enabled)
+ endpoint.add_attr("enabled", str(enabled).lower())
resp, body = self.patch('endpoints/%s' % str(endpoint_id), str(doc))
body = self._parse_body(etree.fromstring(body))
return resp, body
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 58819d0..b3014fc 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -39,23 +39,9 @@
filters=self.filters,
insecure=dscv)
- def get_images_schema(self):
- url = 'v2/schemas/images'
- resp, body = self.get(url)
- body = json.loads(body)
- return resp, body
-
- def get_image_schema(self):
- url = 'v2/schemas/image'
- resp, body = self.get(url)
- body = json.loads(body)
- return resp, body
-
def _validate_schema(self, body, type='image'):
- if type == 'image':
- resp, schema = self.get_image_schema()
- elif type == 'images':
- resp, schema = self.get_images_schema()
+ if type in ['image', 'images']:
+ resp, schema = self.get_schema(type)
else:
raise ValueError("%s is not a valid schema type" % type)
@@ -68,6 +54,15 @@
self._http = self._get_http()
return self._http
+ def update_image(self, image_id, patch):
+ data = json.dumps(patch)
+ self._validate_schema(data)
+
+ headers = {"Content-Type": "application/openstack-images-v2.0"
+ "-json-patch"}
+ resp, body = self.patch('v2/images/%s' % image_id, data, headers)
+ return resp, self._parse_resp(body)
+
def create_image(self, name, container_format, disk_format, **kwargs):
params = {
"name": name,
@@ -163,3 +158,21 @@
body = json.loads(body)
self.expected_success(200, resp)
return resp, body
+
+ def get_member(self, image_id, member_id):
+ url = 'v2/images/%s/members/%s' % (image_id, member_id)
+ resp, body = self.get(url)
+ self.expected_success(200, resp)
+ return resp, json.loads(body)
+
+ def remove_member(self, image_id, member_id):
+ url = 'v2/images/%s/members/%s' % (image_id, member_id)
+ resp, _ = self.delete(url)
+ self.expected_success(204, resp)
+ return resp
+
+ def get_schema(self, schema):
+ url = 'v2/schemas/%s' % schema
+ resp, body = self.get(url)
+ body = json.loads(body)
+ return resp, body
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index 37484cf..dec0170 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -48,7 +48,7 @@
key_name = data_utils.rand_name("keypair-")
self.client.create_key_pair(key_name)
self.client.delete_key_pair(key_name)
- self.assertEqual(None, self.client.get_key_pair(key_name))
+ self.assertIsNone(self.client.get_key_pair(key_name))
@test.attr(type='smoke')
def test_get_ec2_keypair(self):
diff --git a/tools/check_logs.py b/tools/check_logs.py
index 15988a6..98e079a 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -32,7 +32,7 @@
def process_files(file_specs, url_specs, whitelists):
- regexp = re.compile(r"^.* (ERROR|CRITICAL) .*\[.*\-.*\]")
+ regexp = re.compile(r"^.* (ERROR|CRITICAL|TRACE) .*\[.*\-.*\]")
had_errors = False
for (name, filename) in file_specs:
whitelist = whitelists.get(name, [])
diff --git a/tox.ini b/tox.ini
index 69e9d57..4a625f8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -29,7 +29,7 @@
sitepackages = True
setenv = VIRTUAL_ENV={envdir}
commands =
- python setup.py testr --slowest --testr-args='{posargs}'
+ bash tools/pretty_tox.sh '{posargs}'
[testenv:full]
sitepackages = True