Merge "Fix the example of testr testing"
diff --git a/.testr.conf b/.testr.conf
index c25ebec..abaf14a 100644
--- a/.testr.conf
+++ b/.testr.conf
@@ -2,8 +2,7 @@
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \
- OS_TEST_PATH=${OS_TEST_PATH:-./tempest} \
- ${PYTHON:-python} -m subunit.run discover -t ./ $OS_TEST_PATH $LISTOPT $IDOPTION
+ ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./tempest/test_discover} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
group_regex=([^\.]*\.)*
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index 6b24e72..dbf7967 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -17,7 +17,7 @@
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 HostsAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
@@ -41,18 +41,18 @@
hostname = hosts[0]['host_name']
return hostname
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_list_hosts_with_non_admin_user(self):
self.assertRaises(exceptions.Unauthorized,
self.non_admin_client.list_hosts)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_show_host_detail_with_nonexistent_hostname(self):
nonexitent_hostname = data_utils.rand_name('rand_hostname')
self.assertRaises(exceptions.NotFound,
self.client.show_host_detail, nonexitent_hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_show_host_detail_with_non_admin_user(self):
hostname = self._get_host_name()
@@ -60,7 +60,7 @@
self.non_admin_client.show_host_detail,
hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_update_host_with_non_admin_user(self):
hostname = self._get_host_name()
@@ -68,7 +68,8 @@
self.non_admin_client.update_host,
hostname)
- @attr(type=['negative', 'gate'])
+ @test.skip_because(bug="1261964", interface="xml")
+ @test.attr(type=['negative', 'gate'])
def test_update_host_with_extra_param(self):
# only 'status' and 'maintenance_mode' are the valid params.
hostname = self._get_host_name()
@@ -80,7 +81,7 @@
maintenance_mode='enable',
param='XXX')
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_update_host_with_invalid_status(self):
# 'status' can only be 'enable' or 'disable'
hostname = self._get_host_name()
@@ -91,7 +92,7 @@
status='invalid',
maintenance_mode='enable')
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_update_host_with_invalid_maintenance_mode(self):
# 'maintenance_mode' can only be 'enable' or 'disable'
hostname = self._get_host_name()
@@ -102,7 +103,7 @@
status='enable',
maintenance_mode='invalid')
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_update_host_without_param(self):
# 'status' or 'maintenance_mode' needed for host update
hostname = self._get_host_name()
@@ -111,7 +112,7 @@
self.client.update_host,
hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_update_nonexistent_host(self):
nonexitent_hostname = data_utils.rand_name('rand_hostname')
@@ -121,7 +122,7 @@
status='enable',
maintenance_mode='enable')
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_startup_nonexistent_host(self):
nonexitent_hostname = data_utils.rand_name('rand_hostname')
@@ -129,7 +130,7 @@
self.client.startup_host,
nonexitent_hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_startup_host_with_non_admin_user(self):
hostname = self._get_host_name()
@@ -137,7 +138,7 @@
self.non_admin_client.startup_host,
hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_shutdown_nonexistent_host(self):
nonexitent_hostname = data_utils.rand_name('rand_hostname')
@@ -145,7 +146,7 @@
self.client.shutdown_host,
nonexitent_hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_shutdown_host_with_non_admin_user(self):
hostname = self._get_host_name()
@@ -153,7 +154,7 @@
self.non_admin_client.shutdown_host,
hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_reboot_nonexistent_host(self):
nonexitent_hostname = data_utils.rand_name('rand_hostname')
@@ -161,7 +162,7 @@
self.client.reboot_host,
nonexitent_hostname)
- @attr(type=['negative', 'gate'])
+ @test.attr(type=['negative', 'gate'])
def test_reboot_host_with_non_admin_user(self):
hostname = self._get_host_name()
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index ef4f51f..bd431d4 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -38,24 +38,27 @@
self.assertEqual(200, resp.status)
return hypers
+ def assertHypervisors(self, hypers):
+ self.assertTrue(len(hypers) > 0, "No hypervisors found: %s" % hypers)
+
@attr(type='gate')
def test_get_hypervisor_list(self):
# List of hypervisor and available hypervisors hostname
hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
+ self.assertHypervisors(hypers)
@attr(type='gate')
def test_get_hypervisor_list_details(self):
# Display the details of the all hypervisor
resp, hypers = self.client.get_hypervisor_list_details()
self.assertEqual(200, resp.status)
- self.assertTrue(len(hypers) > 0)
+ self.assertHypervisors(hypers)
@attr(type='gate')
def test_get_hypervisor_show_details(self):
# Display the details of the specified hypervisor
hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
+ self.assertHypervisors(hypers)
resp, details = (self.client.
get_hypervisor_show_details(hypers[0]['id']))
@@ -68,7 +71,7 @@
def test_get_hypervisor_show_servers(self):
# Show instances about the specific hypervisors
hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
+ self.assertHypervisors(hypers)
hostname = hypers[0]['hypervisor_hostname']
resp, hypervisors = self.client.get_hypervisor_servers(hostname)
@@ -87,18 +90,29 @@
# Verify that GET shows the specified hypervisor uptime
hypers = self._list_hypervisors()
- resp, uptime = self.client.get_hypervisor_uptime(hypers[0]['id'])
- self.assertEqual(200, resp.status)
- self.assertTrue(len(uptime) > 0)
+ has_valid_uptime = False
+ for hyper in hypers:
+ # because hypervisors might be disabled, this loops looking
+ # for any good hit.
+ try:
+ resp, uptime = self.client.get_hypervisor_uptime(hyper['id'])
+ if (resp.status == 200) and (len(uptime) > 0):
+ has_valid_uptime = True
+ break
+ except Exception:
+ pass
+ self.assertTrue(
+ has_valid_uptime,
+ "None of the hypervisors had a valid uptime: %s" % hypers)
@attr(type='gate')
def test_search_hypervisor(self):
hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
+ self.assertHypervisors(hypers)
resp, hypers = self.client.search_hypervisor(
hypers[0]['hypervisor_hostname'])
self.assertEqual(200, resp.status)
- self.assertTrue(len(hypers) > 0)
+ self.assertHypervisors(hypers)
class HypervisorAdminTestXML(HypervisorAdminTestJSON):
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 9cb425a..e0a5376 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -268,6 +268,7 @@
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
+ cls.keypairs_client = cls.os.keypairs_v3_client
@classmethod
def create_image_from_server(cls, server_id, **kwargs):
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 164c6df..968ae47 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -18,11 +18,8 @@
import netaddr
from tempest.api.compute import base
-from tempest.common.utils import data_utils
from tempest import config
-from tempest import exceptions
-from tempest.test import attr
-from tempest.test import skip_because
+from tempest import test
class VirtualInterfacesTestJSON(base.BaseV2ComputeTest):
@@ -37,9 +34,9 @@
resp, server = cls.create_test_server(wait_until='ACTIVE')
cls.server_id = server['id']
- @skip_because(bug="1183436",
- condition=CONF.service_available.neutron)
- @attr(type='gate')
+ @test.skip_because(bug="1183436",
+ condition=CONF.service_available.neutron)
+ @test.attr(type='gate')
def test_list_virtual_interfaces(self):
# Positive test:Should be able to GET the virtual interfaces list
# for a given server_id
@@ -54,15 +51,6 @@
self.assertTrue(netaddr.valid_mac(mac_address),
"Invalid mac address detected.")
- @attr(type=['negative', 'gate'])
- def test_list_virtual_interfaces_invalid_server_id(self):
- # Negative test: Should not be able to GET virtual interfaces
- # for an invalid server_id
- invalid_server_id = data_utils.rand_name('!@#$%^&*()')
- self.assertRaises(exceptions.NotFound,
- self.client.list_virtual_interfaces,
- invalid_server_id)
-
class VirtualInterfacesTestXML(VirtualInterfacesTestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
new file mode 100644
index 0000000..a2a6c11
--- /dev/null
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -0,0 +1,44 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 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 uuid
+
+from tempest.api.compute import base
+from tempest import exceptions
+from tempest import test
+
+
+class VirtualInterfacesNegativeTestJSON(base.BaseV2ComputeTest):
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(VirtualInterfacesNegativeTestJSON, cls).setUpClass()
+ cls.client = cls.servers_client
+
+ @test.attr(type=['negative', 'gate'])
+ def test_list_virtual_interfaces_invalid_server_id(self):
+ # Negative test: Should not be able to GET virtual interfaces
+ # for an invalid server_id
+ invalid_server_id = str(uuid.uuid4())
+ self.assertRaises(exceptions.NotFound,
+ self.client.list_virtual_interfaces,
+ invalid_server_id)
+
+
+class VirtualInterfacesNegativeTestXML(VirtualInterfacesNegativeTestJSON):
+ _interface = 'xml'
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs.py b/tempest/api/compute/v3/keypairs/test_keypairs.py
index b36595c..029633f 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs.py
@@ -20,17 +20,17 @@
from tempest import test
-class KeyPairsTestJSON(base.BaseV2ComputeTest):
+class KeyPairsV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(KeyPairsTestJSON, cls).setUpClass()
+ super(KeyPairsV3TestJSON, cls).setUpClass()
cls.client = cls.keypairs_client
def _delete_keypair(self, keypair_name):
resp, _ = self.client.delete_keypair(keypair_name)
- self.assertEqual(202, resp.status)
+ self.assertEqual(204, resp.status)
def _create_keypair(self, keypair_name, pub_key=None):
resp, body = self.client.create_keypair(keypair_name, pub_key)
@@ -49,7 +49,7 @@
# as the keypair dicts from list API doesn't have them.
keypair.pop('private_key')
keypair.pop('user_id')
- self.assertEqual(200, resp.status)
+ self.assertEqual(201, resp.status)
key_list.append(keypair)
# Fetch all keypairs and verify the list
# has all created keypairs
@@ -72,7 +72,7 @@
# Keypair should be created, verified and deleted
k_name = data_utils.rand_name('keypair-')
resp, keypair = self._create_keypair(k_name)
- self.assertEqual(200, resp.status)
+ self.assertEqual(201, resp.status)
private_key = keypair['private_key']
key_name = keypair['name']
self.assertEqual(key_name, k_name,
@@ -111,7 +111,7 @@
"XcPojYN56tI0OlrGqojbediJYD0rUsJu4weZpbn8vilb3JuDY+jws"
"snSA8wzBx3A/8y9Pp1B nova@ubuntu")
resp, keypair = self._create_keypair(k_name, pub_key)
- self.assertEqual(200, resp.status)
+ self.assertEqual(201, resp.status)
self.assertFalse('private_key' in keypair,
"Field private_key is not empty!")
key_name = keypair['name']
@@ -120,5 +120,5 @@
"to the requested name!")
-class KeyPairsTestXML(KeyPairsTestJSON):
+class KeyPairsV3TestXML(KeyPairsV3TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
index 621487c..edc0c26 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
@@ -22,12 +22,12 @@
from tempest import test
-class KeyPairsNegativeTestJSON(base.BaseV2ComputeTest):
+class KeyPairsNegativeV3TestJSON(base.BaseV3ComputeTest):
_interface = 'json'
@classmethod
def setUpClass(cls):
- super(KeyPairsNegativeTestJSON, cls).setUpClass()
+ super(KeyPairsNegativeV3TestJSON, cls).setUpClass()
cls.client = cls.keypairs_client
def _create_keypair(self, keypair_name, pub_key=None):
@@ -70,12 +70,11 @@
# Keypairs with duplicate names should not be created
k_name = data_utils.rand_name('keypair-')
resp, _ = self.client.create_keypair(k_name)
- self.assertEqual(200, resp.status)
+ self.addCleanup(self.client.delete_keypair, k_name)
+ self.assertEqual(201, resp.status)
# Now try the same keyname to create another key
self.assertRaises(exceptions.Conflict, self._create_keypair,
k_name)
- resp, _ = self.client.delete_keypair(k_name)
- self.assertEqual(202, resp.status)
@test.attr(type=['negative', 'gate'])
def test_create_keypair_with_empty_name_string(self):
@@ -98,5 +97,5 @@
k_name)
-class KeyPairsNegativeTestXML(KeyPairsNegativeTestJSON):
+class KeyPairsNegativeV3TestXML(KeyPairsNegativeV3TestJSON):
_interface = 'xml'
diff --git a/tempest/clients.py b/tempest/clients.py
index 3333b9b..a38f915 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -60,6 +60,8 @@
HypervisorV3ClientJSON
from tempest.services.compute.v3.json.interfaces_client import \
InterfacesV3ClientJSON
+from tempest.services.compute.v3.json.keypairs_client import \
+ KeyPairsV3ClientJSON
from tempest.services.compute.v3.json.servers_client import \
ServersV3ClientJSON
from tempest.services.compute.v3.json.services_client import \
@@ -76,6 +78,7 @@
HypervisorV3ClientXML
from tempest.services.compute.v3.xml.interfaces_client import \
InterfacesV3ClientXML
+from tempest.services.compute.v3.xml.keypairs_client import KeyPairsV3ClientXML
from tempest.services.compute.v3.xml.servers_client import ServersV3ClientXML
from tempest.services.compute.v3.xml.services_client import \
ServicesV3ClientXML
@@ -91,6 +94,7 @@
from tempest.services.compute.xml.flavors_client import FlavorsClientXML
from tempest.services.compute.xml.floating_ips_client import \
FloatingIPsClientXML
+from tempest.services.compute.xml.hosts_client import HostsClientXML
from tempest.services.compute.xml.hypervisor_client import HypervisorClientXML
from tempest.services.compute.xml.images_client import ImagesClientXML
from tempest.services.compute.xml.instance_usage_audit_log_client import \
@@ -220,6 +224,7 @@
self.servers_v3_client = ServersV3ClientXML(*client_args)
self.limits_client = LimitsClientXML(*client_args)
self.images_client = ImagesClientXML(*client_args)
+ self.keypairs_v3_client = KeyPairsV3ClientXML(*client_args)
self.keypairs_client = KeyPairsClientXML(*client_args)
self.quotas_client = QuotasClientXML(*client_args)
self.flavors_client = FlavorsClientXML(*client_args)
@@ -252,6 +257,7 @@
*client_args)
self.tenant_usages_client = TenantUsagesClientXML(*client_args)
self.policy_client = PolicyClientXML(*client_args)
+ self.hosts_client = HostsClientXML(*client_args)
self.hypervisor_v3_client = HypervisorV3ClientXML(*client_args)
self.hypervisor_client = HypervisorClientXML(*client_args)
self.token_v3_client = V3TokenClientXML(*client_args)
@@ -275,6 +281,7 @@
self.servers_v3_client = ServersV3ClientJSON(*client_args)
self.limits_client = LimitsClientJSON(*client_args)
self.images_client = ImagesClientJSON(*client_args)
+ self.keypairs_v3_client = KeyPairsV3ClientJSON(*client_args)
self.keypairs_client = KeyPairsClientJSON(*client_args)
self.quotas_client = QuotasClientJSON(*client_args)
self.flavors_client = FlavorsClientJSON(*client_args)
@@ -307,6 +314,7 @@
*client_args)
self.tenant_usages_client = TenantUsagesClientJSON(*client_args)
self.policy_client = PolicyClientJSON(*client_args)
+ self.hosts_client = HostsClientJSON(*client_args)
self.hypervisor_v3_client = HypervisorV3ClientJSON(*client_args)
self.hypervisor_client = HypervisorClientJSON(*client_args)
self.token_v3_client = V3TokenClientJSON(*client_args)
@@ -326,7 +334,6 @@
raise exceptions.InvalidConfiguration(msg)
# common clients
- self.hosts_client = HostsClientJSON(*client_args)
self.account_client = AccountClient(*client_args)
if CONF.service_available.glance:
self.image_client = ImageClientJSON(*client_args)
diff --git a/tempest/services/compute/v3/json/keypairs_client.py b/tempest/services/compute/v3/json/keypairs_client.py
index 5e1900c..500aa0e 100644
--- a/tempest/services/compute/v3/json/keypairs_client.py
+++ b/tempest/services/compute/v3/json/keypairs_client.py
@@ -20,15 +20,15 @@
from tempest.common.rest_client import RestClient
-class KeyPairsClientJSON(RestClient):
+class KeyPairsV3ClientJSON(RestClient):
def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(KeyPairsClientJSON, self).__init__(config, username, password,
- auth_url, tenant_name)
- self.service = self.config.compute.catalog_type
+ super(KeyPairsV3ClientJSON, self).__init__(config, username, password,
+ auth_url, tenant_name)
+ self.service = self.config.compute.catalog_v3_type
def list_keypairs(self):
- resp, body = self.get("os-keypairs")
+ resp, body = self.get("keypairs")
body = json.loads(body)
# Each returned keypair is embedded within an unnecessary 'keypair'
# element which is a deviation from other resources like floating-ips,
@@ -38,7 +38,7 @@
return resp, body['keypairs']
def get_keypair(self, key_name):
- resp, body = self.get("os-keypairs/%s" % str(key_name))
+ resp, body = self.get("keypairs/%s" % str(key_name))
body = json.loads(body)
return resp, body['keypair']
@@ -47,10 +47,10 @@
if pub_key:
post_body['keypair']['public_key'] = pub_key
post_body = json.dumps(post_body)
- resp, body = self.post("os-keypairs",
+ resp, body = self.post("keypairs",
headers=self.headers, body=post_body)
body = json.loads(body)
return resp, body['keypair']
def delete_keypair(self, key_name):
- return self.delete("os-keypairs/%s" % str(key_name))
+ return self.delete("keypairs/%s" % str(key_name))
diff --git a/tempest/services/compute/v3/xml/keypairs_client.py b/tempest/services/compute/v3/xml/keypairs_client.py
index 0157245..d87daff 100644
--- a/tempest/services/compute/v3/xml/keypairs_client.py
+++ b/tempest/services/compute/v3/xml/keypairs_client.py
@@ -24,21 +24,21 @@
from tempest.services.compute.xml.common import xml_to_json
-class KeyPairsClientXML(RestClientXML):
+class KeyPairsV3ClientXML(RestClientXML):
def __init__(self, config, username, password, auth_url, tenant_name=None):
- super(KeyPairsClientXML, self).__init__(config, username, password,
- auth_url, tenant_name)
- self.service = self.config.compute.catalog_type
+ super(KeyPairsV3ClientXML, self).__init__(config, username, password,
+ auth_url, tenant_name)
+ self.service = self.config.compute.catalog_v3_type
def list_keypairs(self):
- resp, body = self.get("os-keypairs", self.headers)
+ resp, body = self.get("keypairs", self.headers)
node = etree.fromstring(body)
body = [{'keypair': xml_to_json(x)} for x in node.getchildren()]
return resp, body
def get_keypair(self, key_name):
- resp, body = self.get("os-keypairs/%s" % str(key_name), self.headers)
+ resp, body = self.get("keypairs/%s" % str(key_name), self.headers)
body = xml_to_json(etree.fromstring(body))
return resp, body
@@ -60,10 +60,10 @@
doc.append(keypair_element)
- resp, body = self.post("os-keypairs",
+ resp, body = self.post("keypairs",
headers=self.headers, body=str(doc))
body = xml_to_json(etree.fromstring(body))
return resp, body
def delete_keypair(self, key_name):
- return self.delete("os-keypairs/%s" % str(key_name))
+ return self.delete("keypairs/%s" % str(key_name))
diff --git a/tempest/services/compute/xml/hosts_client.py b/tempest/services/compute/xml/hosts_client.py
index f7d7b0a..519798e 100644
--- a/tempest/services/compute/xml/hosts_client.py
+++ b/tempest/services/compute/xml/hosts_client.py
@@ -47,18 +47,16 @@
resp, body = self.get("os-hosts/%s" % str(hostname), self.headers)
node = etree.fromstring(body)
- body = [xml_to_json(x) for x in node.getchildren()]
+ body = [xml_to_json(node)]
return resp, body
- def update_host(self, hostname, status=None, maintenance_mode=None,
- **kwargs):
+ def update_host(self, hostname, **kwargs):
"""Update a host."""
- request_body = Element(status=status,
- maintenance_mode=maintenance_mode)
+ request_body = Element("updates")
if kwargs:
- for k, v in kwargs.iteritem():
- request_body.add_attr(k, v)
+ for k, v in kwargs.iteritems():
+ request_body.append(Element(k, v))
resp, body = self.put("os-hosts/%s" % str(hostname),
str(Document(request_body)),
self.headers)
diff --git a/tempest/test.py b/tempest/test.py
index 56c0554..342846f 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -112,15 +112,24 @@
@param bug: bug number causing the test to skip
@param condition: optional condition to be True for the skip to have place
+ @param interface: skip the test if it is the same as self._interface
"""
def decorator(f):
@functools.wraps(f)
- def wrapper(*func_args, **func_kwargs):
- if "bug" in kwargs:
- if "condition" not in kwargs or kwargs["condition"] is True:
- msg = "Skipped until Bug: %s is resolved." % kwargs["bug"]
- raise testtools.TestCase.skipException(msg)
- return f(*func_args, **func_kwargs)
+ def wrapper(self, *func_args, **func_kwargs):
+ skip = False
+ if "condition" in kwargs:
+ if kwargs["condition"] is True:
+ skip = True
+ elif "interface" in kwargs:
+ if kwargs["interface"] == self._interface:
+ skip = True
+ else:
+ skip = True
+ if "bug" in kwargs and skip is True:
+ msg = "Skipped until Bug: %s is resolved." % kwargs["bug"]
+ raise testtools.TestCase.skipException(msg)
+ return f(self, *func_args, **func_kwargs)
return wrapper
return decorator