diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py index 78dac2135c..3b3c6ce6d4 100644 --- a/tempest/api/compute/admin/test_services.py +++ b/tempest/api/compute/admin/test_services.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2013 NEC Corporation +# Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -36,17 +37,91 @@ class ServicesAdminTestJSON(base.BaseComputeAdminTest): @attr(type='gate') def test_list_services(self): - # List Compute services resp, services = self.client.list_services() self.assertEqual(200, resp.status) - self.assertTrue(len(services) >= 2) + self.assertNotEqual(0, len(services)) @attr(type=['negative', 'gate']) def test_list_services_with_non_admin_user(self): - # List Compute service with non admin user self.assertRaises(exceptions.Unauthorized, self.non_admin_client.list_services) + @attr(type='gate') + def test_get_service_by_service_binary_name(self): + binary_name = 'nova-compute' + params = {'binary': binary_name} + resp, services = self.client.list_services(params) + self.assertEqual(200, resp.status) + self.assertNotEqual(0, len(services)) + for service in services: + self.assertEqual(binary_name, service['binary']) + + @attr(type='gate') + def test_get_service_by_host_name(self): + resp, services = self.client.list_services() + host_name = services[0]['host'] + services_on_host = [service for service in services if + service['host'] == host_name] + params = {'host': host_name} + resp, services = self.client.list_services(params) + self.assertEqual(services_on_host, services) + + @attr(type=['negative', 'gate']) + def test_get_service_by_invalid_params(self): + #return all services if send the request with invalid parameter + resp, services = self.client.list_services() + params = {'xxx': 'nova-compute'} + resp, services_xxx = self.client.list_services(params) + self.assertEqual(200, resp.status) + self.assertEqual(len(services), len(services_xxx)) + + @attr(type='gate') + def test_get_service_by_service_and_host_name(self): + resp, services = self.client.list_services() + host_name = services[0]['host'] + binary_name = services[0]['binary'] + params = {'host': host_name, 'binary': binary_name} + resp, services = self.client.list_services(params) + self.assertEqual(200, resp.status) + self.assertEqual(1, len(services)) + self.assertEqual(host_name, services[0]['host']) + self.assertEqual(binary_name, services[0]['binary']) + + @attr(type=['negative', 'gate']) + def test_get_service_by_invalid_service_and_valid_host(self): + resp, services = self.client.list_services() + host_name = services[0]['host'] + params = {'host': host_name, 'binary': 'xxx'} + resp, services = self.client.list_services(params) + self.assertEqual(200, resp.status) + self.assertEqual(0, len(services)) + + @attr(type=['negative', 'gate']) + def test_get_service_with_valid_service_and_invalid_host(self): + resp, services = self.client.list_services() + binary_name = services[0]['binary'] + params = {'host': 'xxx', 'binary': binary_name} + resp, services = self.client.list_services(params) + self.assertEqual(200, resp.status) + self.assertEqual(0, len(services)) + + @attr(type='gate') + def test_service_enable_disable(self): + resp, services = self.client.list_services() + host_name = services[0]['host'] + binary_name = services[0]['binary'] + + resp, service = self.client.disable_service(host_name, binary_name) + self.assertEqual(200, resp.status) + params = {'host': host_name, 'binary': binary_name} + resp, services = self.client.list_services(params) + self.assertEqual('disabled', services[0]['status']) + + resp, service = self.client.enable_service(host_name, binary_name) + self.assertEqual(200, resp.status) + resp, services = self.client.list_services(params) + self.assertEqual('enabled', services[0]['status']) + class ServicesAdminTestXML(ServicesAdminTestJSON): _interface = 'xml' diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py index d054f72e09..4db75962be 100644 --- a/tempest/services/compute/json/services_client.py +++ b/tempest/services/compute/json/services_client.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2013 NEC Corporation +# Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -16,6 +17,7 @@ # under the License. import json +import urllib from tempest.common.rest_client import RestClient @@ -27,7 +29,33 @@ class ServicesClientJSON(RestClient): auth_url, tenant_name) self.service = self.config.compute.catalog_type - def list_services(self): - resp, body = self.get("os-services") + def list_services(self, params=None): + url = 'os-services' + if params: + url += '?%s' % urllib.urlencode(params) + + resp, body = self.get(url) body = json.loads(body) return resp, body['services'] + + def enable_service(self, host_name, binary): + """ + Enable service on a host + host_name: Name of host + binary: Service binary + """ + post_body = json.dumps({'binary': binary, 'host': host_name}) + resp, body = self.put('os-services/enable', post_body, self.headers) + body = json.loads(body) + return resp, body['service'] + + def disable_service(self, host_name, binary): + """ + Disable service on a host + host_name: Name of host + binary: Service binary + """ + post_body = json.dumps({'binary': binary, 'host': host_name}) + resp, body = self.put('os-services/disable', post_body, self.headers) + body = json.loads(body) + return resp, body['service'] diff --git a/tempest/services/compute/xml/services_client.py b/tempest/services/compute/xml/services_client.py index ce23403123..ac304e2b22 100644 --- a/tempest/services/compute/xml/services_client.py +++ b/tempest/services/compute/xml/services_client.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2013 NEC Corporation +# Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -15,8 +16,12 @@ # License for the specific language governing permissions and limitations # under the License. +import urllib + from lxml import etree from tempest.common.rest_client import RestClientXML +from tempest.services.compute.xml.common import Document +from tempest.services.compute.xml.common import Element from tempest.services.compute.xml.common import xml_to_json @@ -27,8 +32,42 @@ class ServicesClientXML(RestClientXML): auth_url, tenant_name) self.service = self.config.compute.catalog_type - def list_services(self): - resp, body = self.get("os-services", self.headers) + def list_services(self, params=None): + url = 'os-services' + if params: + url += '?%s' % urllib.urlencode(params) + + resp, body = self.get(url, self.headers) node = etree.fromstring(body) body = [xml_to_json(x) for x in node.getchildren()] return resp, body + + def enable_service(self, host_name, binary): + """ + Enable service on a host + host_name: Name of host + binary: Service binary + """ + post_body = Element("service") + post_body.add_attr('binary', binary) + post_body.add_attr('host', host_name) + + resp, body = self.put('os-services/enable', str(Document(post_body)), + self.headers) + body = xml_to_json(etree.fromstring(body)) + return resp, body + + def disable_service(self, host_name, binary): + """ + Disable service on a host + host_name: Name of host + binary: Service binary + """ + post_body = Element("service") + post_body.add_attr('binary', binary) + post_body.add_attr('host', host_name) + + resp, body = self.put('os-services/disable', str(Document(post_body)), + self.headers) + body = xml_to_json(etree.fromstring(body)) + return resp, body