
It calculates virtual free capacity for pool and backend which reports definite values. It will also notify various capacity info to Ceilometer service. The notification only occurs when volume status is updated. It will give users a bit knowledge about the current storage usage. As there are multiple schedulers and volumes, the patch contains the logic only to send changed capacity info to ceilometer as possible as. It adds a new rpc call named notify_service_capabilities() which fanout=false in volume manager. This means that only one scheduler will receive it and send the notification. Co-Authored-By: Gorka Eguileor <geguileo@redhat.com> Co-Authored-By: lisali <xiaoyan.li@intel.com> DocImpact Implements: blueprint capacity-headroom Change-Id: Iff033d1b591fb3d9c0a5b9732c0c17d96ddbf712
174 lines
7.3 KiB
Python
174 lines
7.3 KiB
Python
|
|
# Copyright 2012, Red Hat, 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.
|
|
|
|
"""
|
|
Unit Tests for cinder.scheduler.rpcapi
|
|
"""
|
|
|
|
import mock
|
|
|
|
from cinder import context
|
|
from cinder.scheduler import rpcapi as scheduler_rpcapi
|
|
from cinder import test
|
|
from cinder.tests.unit import fake_constants
|
|
from cinder.tests.unit import fake_volume
|
|
|
|
|
|
class SchedulerRpcAPITestCase(test.TestCase):
|
|
|
|
def setUp(self):
|
|
super(SchedulerRpcAPITestCase, self).setUp()
|
|
self.context = context.RequestContext('fake_user', 'fake_project')
|
|
self.volume_id = fake_constants.VOLUME_ID
|
|
|
|
def _test_scheduler_api(self, method, rpc_method,
|
|
fanout=False, **kwargs):
|
|
ctxt = self.context
|
|
rpcapi = scheduler_rpcapi.SchedulerAPI()
|
|
expected_retval = 'foo' if rpc_method == 'call' else None
|
|
|
|
target = {
|
|
"fanout": fanout,
|
|
"version": kwargs.pop('version', rpcapi.RPC_API_VERSION)
|
|
}
|
|
|
|
expected_msg = kwargs.copy()
|
|
|
|
self.fake_args = None
|
|
self.fake_kwargs = None
|
|
|
|
def _fake_prepare_method(*args, **kwds):
|
|
for kwd in kwds:
|
|
self.assertEqual(target[kwd], kwds[kwd])
|
|
return rpcapi.client
|
|
|
|
def _fake_rpc_method(*args, **kwargs):
|
|
self.fake_args = args
|
|
self.fake_kwargs = kwargs
|
|
if expected_retval:
|
|
return expected_retval
|
|
|
|
with mock.patch.object(rpcapi.client, "prepare") as mock_prepared:
|
|
mock_prepared.side_effect = _fake_prepare_method
|
|
|
|
with mock.patch.object(rpcapi.client, rpc_method) as mock_method:
|
|
mock_method.side_effect = _fake_rpc_method
|
|
retval = getattr(rpcapi, method)(ctxt, **kwargs)
|
|
self.assertEqual(expected_retval, retval)
|
|
expected_args = [ctxt, method, expected_msg]
|
|
for arg, expected_arg in zip(self.fake_args, expected_args):
|
|
self.assertEqual(expected_arg, arg)
|
|
|
|
for kwarg, value in self.fake_kwargs.items():
|
|
self.assertEqual(expected_msg[kwarg], value)
|
|
|
|
def test_update_service_capabilities(self):
|
|
self._test_scheduler_api('update_service_capabilities',
|
|
rpc_method='cast',
|
|
service_name='fake_name',
|
|
host='fake_host',
|
|
capabilities='fake_capabilities',
|
|
fanout=True,
|
|
version='3.0')
|
|
|
|
def test_create_volume(self):
|
|
volume = fake_volume.fake_volume_obj(self.context)
|
|
create_worker_mock = self.mock_object(volume, 'create_worker')
|
|
self._test_scheduler_api('create_volume',
|
|
rpc_method='cast',
|
|
snapshot_id='snapshot_id',
|
|
image_id='image_id',
|
|
request_spec='fake_request_spec',
|
|
filter_properties='filter_properties',
|
|
volume=volume,
|
|
version='3.0')
|
|
create_worker_mock.assert_called_once()
|
|
|
|
def test_notify_service_capabilities(self):
|
|
capabilities = {'host': 'fake_host',
|
|
'total': '10.01', }
|
|
self._test_scheduler_api('notify_service_capabilities',
|
|
rpc_method='cast',
|
|
service_name='fake_name',
|
|
host='fake_host',
|
|
capabilities=capabilities,
|
|
version='3.1')
|
|
|
|
def test_create_volume_serialization(self):
|
|
volume = fake_volume.fake_volume_obj(self.context)
|
|
create_worker_mock = self.mock_object(volume, 'create_worker')
|
|
self._test_scheduler_api('create_volume',
|
|
rpc_method='cast',
|
|
snapshot_id='snapshot_id',
|
|
image_id='image_id',
|
|
request_spec={'volume_type': {}},
|
|
filter_properties='filter_properties',
|
|
volume=volume,
|
|
version='3.0')
|
|
create_worker_mock.assert_called_once()
|
|
|
|
def test_migrate_volume_to_host(self):
|
|
volume = fake_volume.fake_volume_obj(self.context)
|
|
create_worker_mock = self.mock_object(volume, 'create_worker')
|
|
self._test_scheduler_api('migrate_volume_to_host',
|
|
rpc_method='cast',
|
|
host='host',
|
|
force_host_copy=True,
|
|
request_spec='fake_request_spec',
|
|
filter_properties='filter_properties',
|
|
volume=volume,
|
|
version='3.0')
|
|
create_worker_mock.assert_not_called()
|
|
|
|
def test_retype(self):
|
|
volume = fake_volume.fake_volume_obj(self.context)
|
|
create_worker_mock = self.mock_object(volume, 'create_worker')
|
|
self._test_scheduler_api('retype',
|
|
rpc_method='cast',
|
|
request_spec='fake_request_spec',
|
|
filter_properties='filter_properties',
|
|
volume=volume,
|
|
version='3.0')
|
|
create_worker_mock.assert_not_called()
|
|
|
|
def test_manage_existing(self):
|
|
volume = fake_volume.fake_volume_obj(self.context)
|
|
create_worker_mock = self.mock_object(volume, 'create_worker')
|
|
self._test_scheduler_api('manage_existing',
|
|
rpc_method='cast',
|
|
request_spec='fake_request_spec',
|
|
filter_properties='filter_properties',
|
|
volume=volume,
|
|
version='3.0')
|
|
create_worker_mock.assert_not_called()
|
|
|
|
def test_get_pools(self):
|
|
self._test_scheduler_api('get_pools',
|
|
rpc_method='call',
|
|
filters=None,
|
|
version='3.0')
|
|
|
|
def test_create_group(self):
|
|
self._test_scheduler_api('create_group',
|
|
rpc_method='cast',
|
|
group='group',
|
|
group_spec='group_spec_p',
|
|
request_spec_list=['fake_request_spec_list'],
|
|
group_filter_properties=
|
|
'fake_group_filter_properties',
|
|
filter_properties_list=
|
|
['fake_filter_properties_list'],
|
|
version='3.0')
|