Merge "tests: Add API sample tests for os-services API"
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"host": "host1",
|
||||
"binary": "cinder-volume",
|
||||
"disabled_reason": "test2"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"disabled": true,
|
||||
"disabled_reason": "test2",
|
||||
"host": "host1",
|
||||
"service": "",
|
||||
"status": "disabled"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"host": "host1",
|
||||
"binary": "cinder-volume"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"disabled": true,
|
||||
"host": "host1",
|
||||
"service": "",
|
||||
"status": "disabled"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"host": "host1",
|
||||
"binary": "cinder-volume"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"disabled": false,
|
||||
"host": "host1",
|
||||
"service": "",
|
||||
"status": "enabled"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"host": "host1"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"host": "host1"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"host": "host1"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"server": "devstack@lvmdriver-1",
|
||||
"prefix": "cinder.volume"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"log_levels": [
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"host": "host2",
|
||||
"levels": {
|
||||
"cinder.volume.api": "DEBUG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"host": "host2",
|
||||
"levels": {
|
||||
"cinder.volume.api": "DEBUG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"host": "host2",
|
||||
"levels": {
|
||||
"cinder.volume.api": "DEBUG"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"server": "devstack@lvmdriver-1",
|
||||
"prefix": "cinder.volume",
|
||||
"level": "ERROR"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"services": [
|
||||
{
|
||||
"binary": "cinder-scheduler",
|
||||
"cluster": null,
|
||||
"disabled_reason": "test1",
|
||||
"host": "host1",
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-10-29T13:42:02.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": null,
|
||||
"disabled_reason": "test2",
|
||||
"frozen": false,
|
||||
"host": "host1",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-10-29T13:42:05.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"binary": "cinder-scheduler",
|
||||
"cluster": "cluster1",
|
||||
"disabled_reason": "",
|
||||
"host": "host2",
|
||||
"state": "down",
|
||||
"status": "enabled",
|
||||
"updated_at": "2012-09-19T06:55:34.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": "cluster1",
|
||||
"disabled_reason": "test4",
|
||||
"frozen": false,
|
||||
"host": "host2",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-09-18T08:03:38.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": "cluster2",
|
||||
"disabled_reason": "test5",
|
||||
"frozen": false,
|
||||
"host": "host2",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-10-29T13:42:05.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": "cluster2",
|
||||
"disabled_reason": "",
|
||||
"frozen": false,
|
||||
"host": "host2",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "enabled",
|
||||
"updated_at": "2012-09-18T08:03:38.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"binary": "cinder-scheduler",
|
||||
"cluster": null,
|
||||
"disabled_reason": "",
|
||||
"host": "host2",
|
||||
"state": "down",
|
||||
"status": "enabled",
|
||||
"updated_at": null,
|
||||
"zone": "cinder"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -127,6 +127,8 @@ class ServiceController(wsgi.Controller):
|
||||
except exception.ServiceNotFound as ex:
|
||||
raise exception.InvalidInput(ex.msg)
|
||||
|
||||
# TODO: This currently returns HTTP 200 but it should return HTTP 204 since
|
||||
# there's no content
|
||||
@validation.schema(os_services.freeze_and_thaw)
|
||||
def _freeze(self, req, context, body):
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
@@ -134,6 +136,8 @@ class ServiceController(wsgi.Controller):
|
||||
return self._volume_api_proxy(self.volume_api.freeze_host, context,
|
||||
host, cluster_name)
|
||||
|
||||
# TODO: This currently returns HTTP 200 but it should return HTTP 204 since
|
||||
# there's no content
|
||||
@validation.schema(os_services.freeze_and_thaw)
|
||||
def _thaw(self, req, context, body):
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"host": "%(host)s",
|
||||
"binary": "%(binary)s",
|
||||
"disabled_reason": "%(disabled_reason)s"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"disabled": true,
|
||||
"disabled_reason": "test2",
|
||||
"host": "host1",
|
||||
"service": "",
|
||||
"status": "disabled"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"host": "%(host)s",
|
||||
"binary": "%(binary)s"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"disabled": true,
|
||||
"host": "host1",
|
||||
"service": "",
|
||||
"status": "disabled"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"host": "%(host)s",
|
||||
"binary": "%(binary)s"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"disabled": false,
|
||||
"host": "host1",
|
||||
"service": "",
|
||||
"status": "enabled"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"host": "%(host)s"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"host": "%(host)s"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"host": "%(host)s"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"server": "%(host)s",
|
||||
"prefix": "cinder.volume"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"log_levels": [
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"host": "host2",
|
||||
"levels": {
|
||||
"cinder.volume.api": "DEBUG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"host": "host2",
|
||||
"levels": {
|
||||
"cinder.volume.api": "DEBUG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"host": "host2",
|
||||
"levels": {
|
||||
"cinder.volume.api": "DEBUG"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"binary": "cinder-volume",
|
||||
"server": "devstack@lvmdriver-1",
|
||||
"prefix": "cinder.volume",
|
||||
"level": "ERROR"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"services": [
|
||||
{
|
||||
"binary": "cinder-scheduler",
|
||||
"cluster": null,
|
||||
"disabled_reason": "test1",
|
||||
"host": "host1",
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-10-29T13:42:02.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": null,
|
||||
"disabled_reason": "test2",
|
||||
"frozen": false,
|
||||
"host": "host1",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-10-29T13:42:05.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"binary": "cinder-scheduler",
|
||||
"cluster": "cluster1",
|
||||
"disabled_reason": "",
|
||||
"host": "host2",
|
||||
"state": "down",
|
||||
"status": "enabled",
|
||||
"updated_at": "2012-09-19T06:55:34.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": "cluster1",
|
||||
"disabled_reason": "test4",
|
||||
"frozen": false,
|
||||
"host": "host2",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-09-18T08:03:38.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": "cluster2",
|
||||
"disabled_reason": "test5",
|
||||
"frozen": false,
|
||||
"host": "host2",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "disabled",
|
||||
"updated_at": "2012-10-29T13:42:05.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"active_backend_id": null,
|
||||
"backend_state": null,
|
||||
"binary": "cinder-volume",
|
||||
"cluster": "cluster2",
|
||||
"disabled_reason": "",
|
||||
"frozen": false,
|
||||
"host": "host2",
|
||||
"replication_status": null,
|
||||
"state": "down",
|
||||
"status": "enabled",
|
||||
"updated_at": "2012-09-18T08:03:38.000000",
|
||||
"zone": "cinder"
|
||||
},
|
||||
{
|
||||
"binary": "cinder-scheduler",
|
||||
"cluster": null,
|
||||
"disabled_reason": "",
|
||||
"host": "host2",
|
||||
"state": "down",
|
||||
"status": "enabled",
|
||||
"updated_at": null,
|
||||
"zone": "cinder"
|
||||
}
|
||||
]
|
||||
}
|
||||
159
cinder/tests/functional/api_sample_tests/test_services.py
Normal file
159
cinder/tests/functional/api_sample_tests/test_services.py
Normal file
@@ -0,0 +1,159 @@
|
||||
# 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 cinder.api import microversions as mv
|
||||
from cinder import context
|
||||
from cinder import objects
|
||||
from cinder.tests.functional import api_samples_test_base as test_base
|
||||
from cinder.tests.unit.api.contrib import test_services
|
||||
|
||||
|
||||
def fake_volume_api_freeze_host(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def fake_volume_api_thaw_host(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def fake_volume_api_failover(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def fake_volume_rpc_api_get_log_levels(*args, **kwargs):
|
||||
fake_context = context.RequestContext('user', 'project')
|
||||
return objects.LogLevelList(
|
||||
fake_context,
|
||||
objects=[
|
||||
objects.LogLevel(
|
||||
fake_context, prefix="cinder.volume.api", level='DEBUG',
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class ServicesSampleJsonTest(test_base.ApiSampleTestBase):
|
||||
sample_dir = 'os-services'
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.stub_out(
|
||||
'cinder.db.sqlalchemy.api.service_get_all',
|
||||
test_services.fake_db_api_service_get_all,
|
||||
)
|
||||
self.stub_out(
|
||||
'cinder.db.sqlalchemy.api.service_get',
|
||||
test_services.fake_db_api_service_get,
|
||||
)
|
||||
self.stub_out(
|
||||
'cinder.db.sqlalchemy.api.service_update',
|
||||
test_services.fake_db_api_service_update,
|
||||
)
|
||||
self.stub_out(
|
||||
'cinder.volume.api.API.freeze_host',
|
||||
fake_volume_api_freeze_host,
|
||||
)
|
||||
self.stub_out(
|
||||
'cinder.volume.api.API.thaw_host',
|
||||
fake_volume_api_thaw_host,
|
||||
)
|
||||
self.stub_out(
|
||||
'cinder.volume.api.API.failover',
|
||||
fake_volume_api_failover,
|
||||
)
|
||||
self.stub_out(
|
||||
'cinder.volume.rpcapi.VolumeAPI.get_log_levels',
|
||||
fake_volume_rpc_api_get_log_levels,
|
||||
)
|
||||
self.subs = {}
|
||||
|
||||
@test_base.VolumesSampleBase.override_mv(mv.BACKEND_STATE_REPORT)
|
||||
def test_service_list(self):
|
||||
response = self._do_get('os-services')
|
||||
self._verify_response(
|
||||
'services-list-response', {}, response, 200
|
||||
)
|
||||
|
||||
def test_service_enable(self):
|
||||
subs = {'host': 'host1', 'binary': 'cinder-volume'}
|
||||
response = self._do_put(
|
||||
'os-services/enable', 'service-enable-request', subs
|
||||
)
|
||||
self._verify_response(
|
||||
'service-enable-response', subs, response, 200
|
||||
)
|
||||
|
||||
def test_service_disable(self):
|
||||
subs = {'host': 'host1', 'binary': 'cinder-volume'}
|
||||
response = self._do_put(
|
||||
'os-services/disable', 'service-disable-request', subs
|
||||
)
|
||||
self._verify_response(
|
||||
'service-disable-response', subs, response, 200
|
||||
)
|
||||
|
||||
def test_service_disable_log_reason(self):
|
||||
subs = {
|
||||
'host': 'host1',
|
||||
'binary': 'cinder-volume',
|
||||
'disabled_reason': 'test2',
|
||||
}
|
||||
response = self._do_put(
|
||||
'os-services/disable-log-reason',
|
||||
'service-disable-log-reason-request',
|
||||
subs
|
||||
)
|
||||
self._verify_response(
|
||||
'service-disable-log-reason-response', subs, response, 200
|
||||
)
|
||||
|
||||
def test_service_freeze(self):
|
||||
subs = {'host': 'host1'}
|
||||
response = self._do_put(
|
||||
'os-services/freeze', 'service-freeze-request', subs
|
||||
)
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual('', response.text)
|
||||
|
||||
def test_service_thaw(self):
|
||||
subs = {'host': 'host1'}
|
||||
response = self._do_put(
|
||||
'os-services/thaw', 'service-thaw-request', subs
|
||||
)
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual('', response.text)
|
||||
|
||||
def test_service_failover_host(self):
|
||||
subs = {'host': 'host1'}
|
||||
response = self._do_put(
|
||||
'os-services/failover_host', 'service-failover-host-request', subs
|
||||
)
|
||||
self.assertEqual(202, response.status_code)
|
||||
self.assertEqual('', response.text)
|
||||
|
||||
@test_base.VolumesSampleBase.override_mv(mv.LOG_LEVEL)
|
||||
def test_service_set_log(self):
|
||||
response = self._do_put(
|
||||
'os-services/set-log', 'service-set-log-request'
|
||||
)
|
||||
self.assertEqual(202, response.status_code)
|
||||
self.assertEqual('', response.text)
|
||||
|
||||
@test_base.VolumesSampleBase.override_mv(mv.LOG_LEVEL)
|
||||
def test_service_get_log(self):
|
||||
subs = {'host': 'host2'}
|
||||
response = self._do_put(
|
||||
'os-services/get-log', 'service-get-log-request', subs
|
||||
)
|
||||
self._verify_response(
|
||||
'service-get-log-response', {}, response, 200
|
||||
)
|
||||
@@ -145,12 +145,26 @@ class FakeRequestWithHostBinary(FakeRequestWithBinary):
|
||||
super(FakeRequestWithHostBinary, self).__init__(**kwargs)
|
||||
|
||||
|
||||
def fake_service_get_all(context, **filters):
|
||||
def fake_db_api_service_get_all(context, backend_match_level=None, **filters):
|
||||
result = []
|
||||
host = filters.pop('host', None)
|
||||
host_or_cluster = filters.pop('host_or_cluster', None)
|
||||
filters.pop('is_up', None)
|
||||
for service in fake_services_list:
|
||||
if (host and service['host'] != host and
|
||||
not service['host'].startswith(host + '@')):
|
||||
if (
|
||||
host and service['host'] != host and
|
||||
not service['host'].startswith(host + '@')
|
||||
):
|
||||
continue
|
||||
|
||||
if (
|
||||
host_or_cluster and (
|
||||
(
|
||||
service['host'] != host_or_cluster and
|
||||
not service['host'].startswith(host_or_cluster + '@')
|
||||
) and service['cluster_name'] != host_or_cluster
|
||||
)
|
||||
):
|
||||
continue
|
||||
|
||||
if all(v is None or service.get(k) == v for k, v in filters.items()):
|
||||
@@ -158,22 +172,24 @@ def fake_service_get_all(context, **filters):
|
||||
return result
|
||||
|
||||
|
||||
def fake_service_get(context, service_id=None, **filters):
|
||||
result = fake_service_get_all(context, id=service_id, **filters)
|
||||
def fake_db_api_service_get(
|
||||
context, service_id=None, backend_match_level=None, **filters
|
||||
):
|
||||
result = fake_db_api_service_get_all(context, id=service_id, **filters)
|
||||
if not result:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
return result[0]
|
||||
|
||||
|
||||
def fake_service_get_by_id(value):
|
||||
def fake_db_api_service_get_by_id(value):
|
||||
for service in fake_services_list:
|
||||
if service['id'] == value:
|
||||
return service
|
||||
return None
|
||||
|
||||
|
||||
def fake_service_update(context, service_id, values, retry=True):
|
||||
service = fake_service_get_by_id(service_id)
|
||||
def fake_db_api_service_update(context, service_id, values, retry=True):
|
||||
service = fake_db_api_service_get_by_id(service_id)
|
||||
if service is None:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
else:
|
||||
@@ -198,10 +214,11 @@ def fake_get_pools(ctxt, filters=None):
|
||||
|
||||
@ddt.ddt
|
||||
@mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.get_pools', fake_get_pools)
|
||||
@mock.patch('cinder.db.service_get_all', fake_service_get_all)
|
||||
@mock.patch('cinder.db.service_get', fake_service_get)
|
||||
@mock.patch('cinder.db.service_get_all', fake_db_api_service_get_all)
|
||||
@mock.patch('cinder.db.service_get', fake_db_api_service_get)
|
||||
@mock.patch('oslo_utils.timeutils.utcnow', fake_utcnow)
|
||||
@mock.patch('cinder.db.sqlalchemy.api.service_update', fake_service_update)
|
||||
@mock.patch(
|
||||
'cinder.db.sqlalchemy.api.service_update', fake_db_api_service_update)
|
||||
@mock.patch('cinder.policy.authorize', fake_policy_authorize)
|
||||
class ServicesTest(test.TestCase):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user