feat: allow querying for services and project_ids based on status
The allowed query params for status are:
'deploy_in_progress',
'deployed',
'update_in_progress',
'delete_in_progress',
'failed'
REQUEST:
GET /v1.0/admin/services?status=failed
RESPONSE:
[
{
"service_id": "7b68485a-1ba1-464a-93b6-9f673d637531",
"project_id": "000"
}
]
200 OK
Change-Id: I37b1fbf0b1339f827b707c68266fadf63fcd61fa
This commit is contained in:
@@ -93,6 +93,13 @@ class DefaultServicesController(base.ServicesController):
|
||||
domain_name))
|
||||
return service_details
|
||||
|
||||
def get_services_by_status(self, status):
|
||||
|
||||
services_project_ids = \
|
||||
self.storage_controller.get_services_by_status(status)
|
||||
|
||||
return services_project_ids
|
||||
|
||||
def _append_defaults(self, service_json, operation='create'):
|
||||
# default origin rule
|
||||
for origin in service_json.get('origins', []):
|
||||
|
||||
13
poppy/storage/cassandra/migrations/008_service_status.cql
Normal file
13
poppy/storage/cassandra/migrations/008_service_status.cql
Normal file
@@ -0,0 +1,13 @@
|
||||
CREATE TABLE service_status (
|
||||
service_id UUID,
|
||||
project_id VARCHAR,
|
||||
status VARCHAR,
|
||||
PRIMARY KEY (service_id));
|
||||
|
||||
|
||||
CREATE INDEX status_index on service_status (status);
|
||||
|
||||
--//@UNDO
|
||||
|
||||
DROP TABLE service_status;
|
||||
DROP INDEX status_index;
|
||||
@@ -249,6 +249,28 @@ CQL_UPDATE_CERT_DETAILS = '''
|
||||
IF cert_type = %(cert_type)s AND flavor_id = %(flavor_id)s
|
||||
'''
|
||||
|
||||
CQL_SET_SERVICE_STATUS = '''
|
||||
INSERT INTO service_status (service_id,
|
||||
project_id,
|
||||
status
|
||||
)
|
||||
VALUES (%(service_id)s,
|
||||
%(project_id)s,
|
||||
%(status)s)
|
||||
'''
|
||||
|
||||
CQL_GET_SERVICE_STATUS = '''
|
||||
SELECT project_id,
|
||||
service_id
|
||||
FROM service_status
|
||||
WHERE status = %(status)s
|
||||
'''
|
||||
|
||||
CQL_DELETE_SERVICE_STATUS = '''
|
||||
DELETE FROM service_status
|
||||
WHERE service_id = %(service_id)s
|
||||
'''
|
||||
|
||||
|
||||
class ServicesController(base.ServicesController):
|
||||
|
||||
@@ -412,6 +434,42 @@ class ServicesController(base.ServicesController):
|
||||
"for project_id: {1}".format(count, project_id))
|
||||
return count
|
||||
|
||||
def get_services_by_status(self, status):
|
||||
|
||||
LOG.info("Fetching service_ids and "
|
||||
"project_ids with status: {0}".format(status))
|
||||
|
||||
args = {
|
||||
'status': status
|
||||
}
|
||||
|
||||
stmt = query.SimpleStatement(
|
||||
CQL_GET_SERVICE_STATUS,
|
||||
consistency_level=self._driver.consistency_level)
|
||||
|
||||
resultset = self.session.execute(stmt, args)
|
||||
complete_results = list(resultset)
|
||||
for result in complete_results:
|
||||
result['service_id'] = str(result['service_id'])
|
||||
|
||||
return complete_results
|
||||
|
||||
def delete_services_status(self, project_id, service_id):
|
||||
|
||||
LOG.info("Deleting service_id: {0} "
|
||||
"with project_id: {1} from service_status "
|
||||
"column family".format(service_id, project_id))
|
||||
|
||||
args = {
|
||||
'service_id': uuid.UUID(str(service_id))
|
||||
}
|
||||
|
||||
stmt = query.SimpleStatement(
|
||||
CQL_DELETE_SERVICE_STATUS,
|
||||
consistency_level=self._driver.consistency_level)
|
||||
|
||||
self.session.execute(stmt, args)
|
||||
|
||||
def get_service_limit(self, project_id):
|
||||
"""get_service_limit
|
||||
|
||||
@@ -706,7 +764,9 @@ class ServicesController(base.ServicesController):
|
||||
pds = {provider:
|
||||
json.dumps(service_obj.provider_details[provider].to_dict())
|
||||
for provider in service_obj.provider_details}
|
||||
|
||||
status = None
|
||||
for provider in service_obj.provider_details:
|
||||
status = service_obj.provider_details[provider].status
|
||||
log_delivery = json.dumps(service_obj.log_delivery.to_dict())
|
||||
# fetch current domains
|
||||
args = {
|
||||
@@ -777,6 +837,17 @@ class ServicesController(base.ServicesController):
|
||||
consistency_level=self._driver.consistency_level)
|
||||
self.session.execute(stmt, args)
|
||||
|
||||
status_args = {
|
||||
'service_id': uuid.UUID(str(service_id)),
|
||||
'project_id': project_id,
|
||||
'status': status
|
||||
}
|
||||
|
||||
stmt = query.SimpleStatement(
|
||||
CQL_SET_SERVICE_STATUS,
|
||||
consistency_level=self._driver.consistency_level)
|
||||
self.session.execute(stmt, status_args)
|
||||
|
||||
def update_state(self, project_id, service_id, state):
|
||||
"""update_state
|
||||
|
||||
@@ -822,6 +893,8 @@ class ServicesController(base.ServicesController):
|
||||
pds = result.get('provider_details', {}) or {}
|
||||
pds = {key: value for key, value in pds.items()}
|
||||
|
||||
self.delete_services_status(project_id, service_id)
|
||||
|
||||
if self._driver.archive_on_delete:
|
||||
archive_args = {
|
||||
'project_id': result.get('project_id'),
|
||||
@@ -965,7 +1038,9 @@ class ServicesController(base.ServicesController):
|
||||
:param service_id
|
||||
:param provider_details
|
||||
"""
|
||||
|
||||
provider_detail_dict = {}
|
||||
status = None
|
||||
for provider_name in sorted(provider_details.keys()):
|
||||
the_provider_detail_dict = collections.OrderedDict()
|
||||
the_provider_detail_dict["id"] = (
|
||||
@@ -974,6 +1049,7 @@ class ServicesController(base.ServicesController):
|
||||
provider_details[provider_name].access_urls)
|
||||
the_provider_detail_dict["status"] = (
|
||||
provider_details[provider_name].status)
|
||||
status = the_provider_detail_dict["status"]
|
||||
the_provider_detail_dict["name"] = (
|
||||
provider_details[provider_name].name)
|
||||
the_provider_detail_dict["domains_certificate_status"] = (
|
||||
@@ -1001,6 +1077,17 @@ class ServicesController(base.ServicesController):
|
||||
consistency_level=self._driver.consistency_level)
|
||||
self.session.execute(stmt, args)
|
||||
|
||||
args = {
|
||||
'project_id': project_id,
|
||||
'service_id': uuid.UUID(str(service_id)),
|
||||
'status': status
|
||||
}
|
||||
|
||||
stmt = query.SimpleStatement(
|
||||
CQL_SET_SERVICE_STATUS,
|
||||
consistency_level=self._driver.consistency_level)
|
||||
self.session.execute(stmt, args)
|
||||
|
||||
def update_cert_info(self, domain_name, cert_type, flavor_id,
|
||||
cert_details):
|
||||
"""update_cert_info.
|
||||
|
||||
@@ -318,11 +318,34 @@ class ServiceStatusController(base.Controller, hooks.HookController):
|
||||
|
||||
|
||||
class AdminServiceController(base.Controller, hooks.HookController):
|
||||
|
||||
__hooks__ = [poppy_hooks.Context(), poppy_hooks.Error()]
|
||||
|
||||
def __init__(self, driver):
|
||||
super(AdminServiceController, self).__init__(driver)
|
||||
self.__class__.action = OperatorServiceActionController(driver)
|
||||
self.__class__.status = ServiceStatusController(driver)
|
||||
|
||||
@pecan.expose('json')
|
||||
@pecan.expose('json')
|
||||
@decorators.validate(
|
||||
request=rule.Rule(
|
||||
helpers.is_valid_service_status(),
|
||||
helpers.abort_with_message,
|
||||
stoplight_helpers.pecan_getter)
|
||||
)
|
||||
def get(self):
|
||||
services_controller = self._driver.manager.services_controller
|
||||
|
||||
call_args = getattr(pecan.request.context,
|
||||
"call_args")
|
||||
status = call_args.pop('status')
|
||||
service_projectids = services_controller.get_services_by_status(
|
||||
status)
|
||||
|
||||
return pecan.Response(json_body=service_projectids,
|
||||
status=200)
|
||||
|
||||
|
||||
class DomainController(base.Controller, hooks.HookController):
|
||||
|
||||
|
||||
@@ -541,6 +541,31 @@ def is_valid_analytics_request(request):
|
||||
}
|
||||
|
||||
|
||||
@decorators.validation_function
|
||||
def is_valid_service_status(request):
|
||||
status = request.GET.get('status', "")
|
||||
|
||||
# NOTE(TheSriram): The statuses listed below are the currently
|
||||
# supported statuses
|
||||
|
||||
VALID_STATUSES = [
|
||||
u'deploy_in_progress',
|
||||
u'deployed',
|
||||
u'update_in_progress',
|
||||
u'delete_in_progress',
|
||||
u'failed']
|
||||
if status not in VALID_STATUSES:
|
||||
raise exceptions.ValidationFailed('Unknown status type {0} present, '
|
||||
'Valid status types '
|
||||
'are: {1}'.format(status,
|
||||
VALID_STATUSES))
|
||||
|
||||
# Update context so the decorated function can get all this parameters
|
||||
request.context.call_args = {
|
||||
'status': status
|
||||
}
|
||||
|
||||
|
||||
def abort_with_message(error_info):
|
||||
pecan.abort(400, detail=util.help_escape(
|
||||
getattr(error_info, "message", "")),
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
|
||||
@@ -34,56 +33,8 @@ class TestServiceLimits(base.TestBase):
|
||||
'Test Operator Functions is disabled in configuration')
|
||||
|
||||
self.flavor_id = self.test_flavor
|
||||
|
||||
self.caching_list = [
|
||||
{
|
||||
u"name": u"default",
|
||||
u"ttl": 3600,
|
||||
u"rules": [{
|
||||
u"name": "default",
|
||||
u"request_url": "/*"
|
||||
}]
|
||||
},
|
||||
{
|
||||
u"name": u"home",
|
||||
u"ttl": 1200,
|
||||
u"rules": [{
|
||||
u"name": u"index",
|
||||
u"request_url": u"/index.htm"
|
||||
}]
|
||||
}
|
||||
]
|
||||
self.service_list = []
|
||||
|
||||
def _service_limit_create_test_service(self, resp_code=False):
|
||||
service_name = str(uuid.uuid1())
|
||||
|
||||
domain_list = [{"domain": self.generate_random_string(
|
||||
prefix='www.api-test-domain') + '.com'}]
|
||||
|
||||
origin_list = [{"origin": self.generate_random_string(
|
||||
prefix='api-test-origin') + '.com', "port": 80, "ssl": False,
|
||||
"hostheadertype": "custom", "hostheadervalue":
|
||||
"www.customweb.com"}]
|
||||
|
||||
self.log_delivery = {"enabled": False}
|
||||
|
||||
resp = self.service_limit_user_client.create_service(
|
||||
service_name=service_name,
|
||||
domain_list=domain_list,
|
||||
origin_list=origin_list,
|
||||
caching_list=self.caching_list,
|
||||
flavor_id=self.flavor_id,
|
||||
log_delivery=self.log_delivery)
|
||||
|
||||
if resp_code:
|
||||
return resp
|
||||
|
||||
self.assertEqual(resp.status_code, 202)
|
||||
service_url = resp.headers["location"]
|
||||
|
||||
return service_url
|
||||
|
||||
@ddt.data(-1, -10000000000, 'invalid', '学校', '', None)
|
||||
def test_service_limit_parameters_invalid(self, limit):
|
||||
|
||||
@@ -101,10 +52,13 @@ class TestServiceLimits(base.TestBase):
|
||||
|
||||
self.assertEqual(resp.status_code, 201)
|
||||
|
||||
self.service_list = [self._service_limit_create_test_service()
|
||||
for _ in range(limit)]
|
||||
self.service_list = [self._service_limit_create_test_service(
|
||||
client=self.service_limit_user_client)
|
||||
for _ in range(limit)]
|
||||
|
||||
resp = self._service_limit_create_test_service(resp_code=True)
|
||||
resp = self._service_limit_create_test_service(
|
||||
client=self.service_limit_user_client,
|
||||
resp_code=True)
|
||||
self.assertEqual(resp.status_code, 403)
|
||||
|
||||
resp = self.operator_client.get_admin_service_limit(
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import ddt
|
||||
|
||||
from tests.api import base
|
||||
from tests.api.utils.schema import admin
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -29,100 +30,45 @@ class TestServiceStatus(base.TestBase):
|
||||
if self.test_config.run_operator_tests is False:
|
||||
self.skipTest(
|
||||
'Test Operator Functions is disabled in configuration')
|
||||
self.service_name = self.generate_random_string(prefix='API-Test-')
|
||||
self.flavor_id = self.test_flavor
|
||||
self.service_urls = []
|
||||
|
||||
domain = self.generate_random_string(
|
||||
prefix='www.api-test-domain') + '.com'
|
||||
self.domain_list = [
|
||||
{"domain": domain}
|
||||
]
|
||||
@ddt.data((1, u'deployed'), (1, u'failed'),
|
||||
(3, u'deployed'), (3, u'failed'),
|
||||
(5, u'deployed'), (5, u'failed'))
|
||||
def test_set_services(self, services_status):
|
||||
no_of_services, status = services_status
|
||||
self.service_urls = \
|
||||
[self._service_limit_create_test_service(client=self.client)
|
||||
for _ in range(no_of_services)]
|
||||
|
||||
origin = self.generate_random_string(
|
||||
prefix='api-test-origin') + u'.com'
|
||||
self.origin_list = [
|
||||
{
|
||||
u"origin": origin,
|
||||
u"port": 80,
|
||||
u"ssl": False,
|
||||
u"rules": [{
|
||||
u"name": u"default",
|
||||
u"request_url": u"/*"
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
self.caching_list = [
|
||||
{
|
||||
u"name": u"default",
|
||||
u"ttl": 3600,
|
||||
u"rules": [{
|
||||
u"name": "default",
|
||||
u"request_url": "/*"
|
||||
}]
|
||||
},
|
||||
{
|
||||
u"name": u"home",
|
||||
u"ttl": 1200,
|
||||
u"rules": [{
|
||||
u"name": u"index",
|
||||
u"request_url": u"/index.htm"
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
self.restrictions_list = [
|
||||
{
|
||||
u"name": u"website only",
|
||||
u"rules": [
|
||||
{
|
||||
u"name": domain,
|
||||
u"referrer": domain,
|
||||
u"request_url": "/*"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
resp = self.setup_service(
|
||||
service_name=self.service_name,
|
||||
domain_list=self.domain_list,
|
||||
origin_list=self.origin_list,
|
||||
caching_list=self.caching_list,
|
||||
restrictions_list=self.restrictions_list,
|
||||
flavor_id=self.flavor_id)
|
||||
|
||||
self.assertEqual(resp.status_code, 202)
|
||||
self.assertEqual(resp.text, '')
|
||||
self.service_url = resp.headers['location']
|
||||
|
||||
self.client.wait_for_service_status(
|
||||
location=self.service_url,
|
||||
status='deployed',
|
||||
abort_on_status='failed',
|
||||
retry_interval=self.test_config.status_check_retry_interval,
|
||||
retry_timeout=self.test_config.status_check_retry_timeout)
|
||||
|
||||
@ddt.data(u'deployed', u'failed')
|
||||
def test_set_service(self, status):
|
||||
|
||||
service_id = self.service_url.rsplit('/')[-1:][0]
|
||||
service_ids = [url.rsplit('/')[-1:][0] for url in self.service_urls]
|
||||
project_id = self.user_project_id
|
||||
|
||||
set_service_resp = self.operator_client.set_service_status(
|
||||
project_id=project_id,
|
||||
service_id=service_id,
|
||||
status=status)
|
||||
for service_id, service_url in zip(service_ids, self.service_urls):
|
||||
set_service_resp = self.operator_client.set_service_status(
|
||||
project_id=project_id,
|
||||
service_id=service_id,
|
||||
status=status)
|
||||
|
||||
self.assertEqual(set_service_resp.status_code, 201)
|
||||
self.assertEqual(set_service_resp.status_code, 201)
|
||||
|
||||
service_resp = self.client.get_service(self.service_url)
|
||||
resp_body = service_resp.json()
|
||||
resp_status = resp_body['status']
|
||||
self.assertEqual(resp_status, status)
|
||||
service_resp = self.client.get_service(service_url)
|
||||
resp_body = service_resp.json()
|
||||
resp_status = resp_body['status']
|
||||
self.assertEqual(resp_status, status)
|
||||
|
||||
get_service_resp = self.operator_client.get_by_service_status(
|
||||
status=status)
|
||||
|
||||
self.assertSchema(get_service_resp.json(),
|
||||
admin.get_service_project_status)
|
||||
self.assertIn(service_id, get_service_resp.content)
|
||||
self.assertIn(project_id, get_service_resp.content)
|
||||
|
||||
def tearDown(self):
|
||||
self.client.delete_service(location=self.service_url)
|
||||
if self.test_config.generate_flavors:
|
||||
self.client.delete_flavor(flavor_id=self.flavor_id)
|
||||
super(TestServiceStatus, self).tearDown()
|
||||
for service_url in self.service_urls:
|
||||
self.client.delete_service(location=service_url)
|
||||
if self.test_config.generate_flavors:
|
||||
self.client.delete_flavor(flavor_id=self.flavor_id)
|
||||
super(TestServiceStatus, self).tearDown()
|
||||
|
||||
@@ -178,6 +178,58 @@ class TestBase(fixtures.BaseTestFixture):
|
||||
|
||||
return resp
|
||||
|
||||
def _service_limit_create_test_service(self, client, resp_code=False):
|
||||
service_name = str(uuid.uuid1())
|
||||
|
||||
domain_list = [{"domain": self.generate_random_string(
|
||||
prefix='www.api-test-domain') + '.com'}]
|
||||
|
||||
origin_list = [{"origin": self.generate_random_string(
|
||||
prefix='api-test-origin') + '.com', "port": 80, "ssl": False,
|
||||
"hostheadertype": "custom", "hostheadervalue":
|
||||
"www.customweb.com"}]
|
||||
caching_list = [
|
||||
{
|
||||
u"name": u"default",
|
||||
u"ttl": 3600,
|
||||
u"rules": [{
|
||||
u"name": "default",
|
||||
u"request_url": "/*"
|
||||
}]
|
||||
},
|
||||
{
|
||||
u"name": u"home",
|
||||
u"ttl": 1200,
|
||||
u"rules": [{
|
||||
u"name": u"index",
|
||||
u"request_url": u"/index.htm"
|
||||
}]
|
||||
}
|
||||
]
|
||||
log_delivery = {"enabled": False}
|
||||
|
||||
resp = client.create_service(
|
||||
service_name=service_name,
|
||||
domain_list=domain_list,
|
||||
origin_list=origin_list,
|
||||
caching_list=caching_list,
|
||||
flavor_id=self.flavor_id,
|
||||
log_delivery=log_delivery)
|
||||
|
||||
if resp_code:
|
||||
return resp
|
||||
|
||||
self.assertEqual(resp.status_code, 202)
|
||||
service_url = resp.headers["location"]
|
||||
client.wait_for_service_status(
|
||||
location=service_url,
|
||||
status='DEPLOYED',
|
||||
abort_on_status='FAILED',
|
||||
retry_interval=self.test_config.status_check_retry_interval,
|
||||
retry_timeout=self.test_config.status_check_retry_timeout)
|
||||
|
||||
return service_url
|
||||
|
||||
def assert_patch_service_details(self, actual_response, expected_response):
|
||||
self.assertEqual(actual_response['name'],
|
||||
expected_response['name'])
|
||||
|
||||
@@ -274,6 +274,19 @@ class PoppyClient(client.AutoMarshallingHTTPClient):
|
||||
return self.request('POST', url, request_entity=request_object,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def get_by_service_status(self, status,
|
||||
requestslib_kwargs=None):
|
||||
"""GET Services by Status
|
||||
|
||||
:return: Response Object containing response code 200
|
||||
|
||||
GET
|
||||
/admin/services?status
|
||||
"""
|
||||
|
||||
url = '{0}/admin/services?status={1}'.format(self.url, status)
|
||||
return self.request('GET', url, requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def admin_migrate_domain(self, project_id, service_id, domain, new_cert,
|
||||
requestslib_kwargs=None):
|
||||
"""Update SAN domain
|
||||
|
||||
34
tests/api/utils/schema/admin.py
Normal file
34
tests/api/utils/schema/admin.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (c) 2016 Rackspace, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Response Schema Definition for Get Service ids and Project id by status
|
||||
|
||||
from tests.api.utils.schema.services import project_id
|
||||
from tests.api.utils.schema.services import service_id
|
||||
|
||||
get_service_project_status = {
|
||||
'type': 'array',
|
||||
'items': [
|
||||
{
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'service_id': service_id,
|
||||
'project_id': project_id,
|
||||
},
|
||||
'required': ['service_id', 'project_id'],
|
||||
'additionalProperties': False
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
# Copyright (c) 2015 Rackspace, Inc.
|
||||
#
|
||||
# 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
|
||||
|
||||
import ddt
|
||||
from hypothesis import given
|
||||
from hypothesis import strategies
|
||||
import mock
|
||||
import six
|
||||
|
||||
from poppy.manager.default.services import DefaultServicesController
|
||||
|
||||
from tests.functional.transport.pecan import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestGetServiceStatus(base.FunctionalTest):
|
||||
|
||||
@given(strategies.text())
|
||||
def test_get_service_status_invalid_queryparam(self, status):
|
||||
# invalid status field
|
||||
try:
|
||||
# NOTE(TheSriram): Py3k Hack
|
||||
if six.PY3 and type(status) == str:
|
||||
status = status.encode('utf-8')
|
||||
url = '/v1.0/admin/services?status={0}'.format(status)
|
||||
|
||||
else:
|
||||
url = '/v1.0/admin/services?status=%s' \
|
||||
% status.decode('utf-8')
|
||||
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||
pass
|
||||
else:
|
||||
response = self.app.get(url,
|
||||
headers={'Content-Type':
|
||||
'application/json',
|
||||
'X-Project-ID':
|
||||
str(uuid.uuid4())},
|
||||
expect_errors=True)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
@ddt.data('deploy_in_progress', 'deployed', 'update_in_progress',
|
||||
'delete_in_progress', 'failed')
|
||||
def test_get_service_status_valid_queryparam(self, status):
|
||||
# valid status
|
||||
with mock.patch.object(DefaultServicesController,
|
||||
'get_services_by_status'):
|
||||
response = self.app.get('/v1.0/admin/services'
|
||||
'?status={0}'.format(status),
|
||||
headers={'Content-Type':
|
||||
'application/json',
|
||||
'X-Project-ID':
|
||||
str(uuid.uuid4())})
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -231,6 +231,7 @@ class CassandraStorageServiceTests(base.TestCase):
|
||||
|
||||
# this is for update_provider_details unittest code coverage
|
||||
arg_provider_details_dict = {}
|
||||
status = None
|
||||
for provider_name in provider_details_dict:
|
||||
the_provider_detail_dict = collections.OrderedDict()
|
||||
the_provider_detail_dict["id"] = (
|
||||
@@ -239,6 +240,7 @@ class CassandraStorageServiceTests(base.TestCase):
|
||||
provider_details_dict[provider_name].access_urls)
|
||||
the_provider_detail_dict["status"] = (
|
||||
provider_details_dict[provider_name].status)
|
||||
status = the_provider_detail_dict["status"]
|
||||
the_provider_detail_dict["name"] = (
|
||||
provider_details_dict[provider_name].name)
|
||||
the_provider_detail_dict["domains_certificate_status"] = (
|
||||
@@ -251,17 +253,25 @@ class CassandraStorageServiceTests(base.TestCase):
|
||||
arg_provider_details_dict[provider_name] = json.dumps(
|
||||
the_provider_detail_dict)
|
||||
|
||||
call_args = {
|
||||
provider_details_args = {
|
||||
'project_id': self.project_id,
|
||||
'service_id': self.service_id,
|
||||
'provider_details': arg_provider_details_dict
|
||||
}
|
||||
|
||||
status_args = {
|
||||
'status': status,
|
||||
'project_id': self.project_id,
|
||||
'service_id': self.service_id
|
||||
}
|
||||
# This is to verify mock has been called with the correct arguments
|
||||
|
||||
def assert_mock_execute_args(*args):
|
||||
self.assertEqual(args[0].query_string,
|
||||
services.CQL_UPDATE_PROVIDER_DETAILS)
|
||||
self.assertEqual(args[1], call_args)
|
||||
|
||||
if args[0].query_string == services.CQL_UPDATE_PROVIDER_DETAILS:
|
||||
self.assertEqual(args[1], provider_details_args)
|
||||
elif args[0].query_string == services.CQL_SET_SERVICE_STATUS:
|
||||
self.assertEqual(args[1], status_args)
|
||||
|
||||
mock_execute.execute.side_effect = assert_mock_execute_args
|
||||
|
||||
self.sc.update_provider_details(
|
||||
|
||||
Reference in New Issue
Block a user