Merge "Quantum client should not be conditional"
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
new file mode 100644
index 0000000..00a5955
--- /dev/null
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -0,0 +1,112 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corporation
+# 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.
+
+from tempest.api.compute import base
+from tempest import exceptions
+from tempest.test import attr
+
+
+class HypervisorAdminTestJSON(base.BaseComputeAdminTest):
+
+ """
+ Tests Hypervisors API that require admin privileges
+ """
+
+ _interface = 'json'
+
+ @classmethod
+ def setUpClass(cls):
+ super(HypervisorAdminTestJSON, cls).setUpClass()
+ cls.client = cls.os_adm.hypervisor_client
+ cls.non_adm_client = cls.hypervisor_client
+
+ def _list_hypervisors(self):
+ # List of hypervisors
+ resp, hypers = self.client.get_hypervisor_list()
+ self.assertEqual(200, resp.status)
+ return hypers
+
+ @attr(type=['positive', 'gate'])
+ def test_get_hypervisor_list(self):
+ # List of hypervisor and available hypervisors hostname
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ @attr(type=['positive', '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)
+
+ @attr(type=['positive', 'gate'])
+ def test_get_hypervisor_show_details(self):
+ # Display the details of the specified hypervisor
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ resp, details = (self.client.
+ get_hypervisor_show_details(hypers[0]['id']))
+ self.assertEqual(200, resp.status)
+ self.assertTrue(len(details) > 0)
+ self.assertEqual(details['hypervisor_hostname'],
+ hypers[0]['hypervisor_hostname'])
+
+ @attr(type=['positive', 'gate'])
+ def test_get_hypervisor_show_servers(self):
+ # Show instances about the specific hypervisors
+ hypers = self._list_hypervisors()
+ self.assertTrue(len(hypers) > 0)
+
+ hostname = hypers[0]['hypervisor_hostname']
+ resp, hypervisors = self.client.get_hypervisor_servers(hostname)
+ self.assertEqual(200, resp.status)
+ self.assertTrue(len(hypervisors) > 0)
+
+ @attr(type=['positive', 'gate'])
+ def test_get_hypervisor_stats(self):
+ # Verify the stats of the all hypervisor
+ resp, stats = self.client.get_hypervisor_stats()
+ self.assertEqual(200, resp.status)
+ self.assertTrue(len(stats) > 0)
+
+ @attr(type=['positive', 'gate'])
+ def test_get_hypervisor_uptime(self):
+ # 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)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_hypervisor_list_with_non_admin_user(self):
+ # List of hypervisor and available services with non admin user
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_list)
+
+ @attr(type=['negative', 'gate'])
+ def test_get_hypervisor_list_details_with_non_admin_user(self):
+ # List of hypervisor details and available services with non admin user
+ self.assertRaises(
+ exceptions.Unauthorized,
+ self.non_adm_client.get_hypervisor_list_details)
+
+
+class HypervisorAdminTestXML(HypervisorAdminTestJSON):
+ _interface = 'xml'
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 48ef296..0fa5a84 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -64,6 +64,7 @@
cls.availability_zone_client = os.availability_zone_client
cls.aggregates_client = os.aggregates_client
cls.services_client = os.services_client
+ cls.hypervisor_client = os.hypervisor_client
cls.build_interval = cls.config.compute.build_interval
cls.build_timeout = cls.config.compute.build_timeout
cls.ssh_user = cls.config.compute.ssh_user
diff --git a/tempest/clients.py b/tempest/clients.py
index e85809f..e778dc1 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -30,6 +30,8 @@
from tempest.services.compute.json.floating_ips_client import \
FloatingIPsClientJSON
from tempest.services.compute.json.hosts_client import HostsClientJSON
+from tempest.services.compute.json.hypervisor_client import \
+ HypervisorClientJSON
from tempest.services.compute.json.images_client import ImagesClientJSON
from tempest.services.compute.json.interfaces_client import \
InterfacesClientJSON
@@ -52,6 +54,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.hypervisor_client import HypervisorClientXML
from tempest.services.compute.xml.images_client import ImagesClientXML
from tempest.services.compute.xml.interfaces_client import \
InterfacesClientXML
@@ -231,6 +234,11 @@
"xml": PolicyClientXML,
}
+HYPERVISOR_CLIENT = {
+ "json": HypervisorClientJSON,
+ "xml": HypervisorClientXML,
+}
+
class Manager(object):
@@ -317,6 +325,7 @@
self.tenant_usages_client = \
TENANT_USAGES_CLIENT[interface](*client_args)
self.policy_client = POLICY_CLIENT[interface](*client_args)
+ self.hypervisor_client = HYPERVISOR_CLIENT[interface](*client_args)
if client_args_v3_auth:
self.servers_client_v3_auth = SERVERS_CLIENTS[interface](
diff --git a/tempest/manager.py b/tempest/manager.py
index 25e80ad..762bc18 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -22,6 +22,7 @@
from tempest.services.compute.json import extensions_client
from tempest.services.compute.json import flavors_client
from tempest.services.compute.json import floating_ips_client
+from tempest.services.compute.json import hypervisor_client
from tempest.services.compute.json import images_client
from tempest.services.compute.json import keypairs_client
from tempest.services.compute.json import limits_client
@@ -46,6 +47,7 @@
VolumesClient = volumes_client.VolumesClientJSON
SnapshotsClient = snapshots_client.SnapshotsClientJSON
QuotasClient = quotas_client.QuotasClientJSON
+HypervisorClient = hypervisor_client.HypervisorClientJSON
LOG = logging.getLogger(__name__)
@@ -132,6 +134,7 @@
self.snapshots_client = SnapshotsClient(*client_args)
self.quotas_client = QuotasClient(*client_args)
self.network_client = NetworkClient(*client_args)
+ self.hypervisor_client = HypervisorClient(*client_args)
class ComputeFuzzClientAltManager(Manager):
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
new file mode 100644
index 0000000..e2e5c7b
--- /dev/null
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -0,0 +1,65 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corporation.
+# 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 json
+
+from tempest.common.rest_client import RestClient
+
+
+class HypervisorClientJSON(RestClient):
+
+ def __init__(self, config, username, password, auth_url, tenant_name=None):
+ super(HypervisorClientJSON, self).__init__(config, username,
+ password, auth_url,
+ tenant_name)
+ self.service = self.config.compute.catalog_type
+
+ def get_hypervisor_list(self):
+ """List hypervisors information."""
+ resp, body = self.get('os-hypervisors')
+ body = json.loads(body)
+ return resp, body['hypervisors']
+
+ def get_hypervisor_list_details(self):
+ """Show detailed hypervisors information."""
+ resp, body = self.get('os-hypervisors/detail')
+ body = json.loads(body)
+ return resp, body['hypervisors']
+
+ def get_hypervisor_show_details(self, hyper_id):
+ """Display the details of the specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s' % hyper_id)
+ body = json.loads(body)
+ return resp, body['hypervisor']
+
+ def get_hypervisor_servers(self, hyper_name):
+ """List instances belonging to the specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s/servers' % hyper_name)
+ body = json.loads(body)
+ return resp, body['hypervisors']
+
+ def get_hypervisor_stats(self):
+ """Get hypervisor statistics over all compute nodes."""
+ resp, body = self.get('os-hypervisors/statistics')
+ body = json.loads(body)
+ return resp, body['hypervisor_statistics']
+
+ def get_hypervisor_uptime(self, hyper_id):
+ """Display the uptime of the specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id)
+ body = json.loads(body)
+ return resp, body['hypervisor']
diff --git a/tempest/services/compute/xml/hypervisor_client.py b/tempest/services/compute/xml/hypervisor_client.py
new file mode 100644
index 0000000..3c4f2b8
--- /dev/null
+++ b/tempest/services/compute/xml/hypervisor_client.py
@@ -0,0 +1,72 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corporation
+# 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.
+
+from lxml import etree
+
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import xml_to_json
+
+
+class HypervisorClientXML(RestClientXML):
+
+ def __init__(self, config, username, password, auth_url, tenant_name=None):
+ super(HypervisorClientXML, self).__init__(config, username,
+ password, auth_url,
+ tenant_name)
+ self.service = self.config.compute.catalog_type
+
+ def _parse_array(self, node):
+ return [xml_to_json(x) for x in node]
+
+ def get_hypervisor_list(self):
+ """List hypervisors information."""
+ resp, body = self.get('os-hypervisors', self.headers)
+ hypervisors = self._parse_array(etree.fromstring(body))
+ return resp, hypervisors
+
+ def get_hypervisor_list_details(self):
+ """Show detailed hypervisors information."""
+ resp, body = self.get('os-hypervisors/detail', self.headers)
+ hypervisors = self._parse_array(etree.fromstring(body))
+ return resp, hypervisors
+
+ def get_hypervisor_show_details(self, hyper_id):
+ """Display the details of the specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s' % hyper_id,
+ self.headers)
+ hypervisor = xml_to_json(etree.fromstring(body))
+ return resp, hypervisor
+
+ def get_hypervisor_servers(self, hyper_name):
+ """List instances belonging to the specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s/servers' % hyper_name,
+ self.headers)
+ hypervisors = self._parse_array(etree.fromstring(body))
+ return resp, hypervisors
+
+ def get_hypervisor_stats(self):
+ """Get hypervisor statistics over all compute nodes."""
+ resp, body = self.get('os-hypervisors/statistics', self.headers)
+ stats = xml_to_json(etree.fromstring(body))
+ return resp, stats
+
+ def get_hypervisor_uptime(self, hyper_id):
+ """Display the uptime of the specified hypervisor."""
+ resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id,
+ self.headers)
+ uptime = xml_to_json(etree.fromstring(body))
+ return resp, uptime