cinder/cinder/tests/unit/scheduler/test_rpcapi.py
XinXiaohui b67a416bb9 Calculate virtual free capacity and notify
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
2016-12-02 02:00:00 +00:00

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')