cinder/cinder/tests/unit/objects/test_cluster.py

162 lines
7.0 KiB
Python

# Copyright (c) 2016 Red Hat, Inc.
# All Rights Reserved.
#
# 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 ddt
import mock
from oslo_utils import timeutils
import cinder.db
from cinder.db.sqlalchemy import models
from cinder import objects
from cinder.tests.unit import fake_cluster
from cinder.tests.unit import objects as test_objects
from cinder import utils
def _get_filters_sentinel():
return {'session': mock.sentinel.session,
'read_deleted': mock.sentinel.read_deleted,
'get_services': mock.sentinel.get_services,
'services_summary': mock.sentinel.services_summary,
'name': mock.sentinel.name,
'binary': mock.sentinel.binary,
'is_up': mock.sentinel.is_up,
'disabled': mock.sentinel.disabled,
'disabled_reason': mock.sentinel.disabled_reason,
'race_preventer': mock.sentinel.race_preventer,
'last_heartbeat': mock.sentinel.last_heartbeat,
'num_hosts': mock.sentinel.num_hosts,
'name_match_level': mock.sentinel.name_match_level,
'num_down_hosts': mock.sentinel.num_down_hosts}
@ddt.ddt
class TestCluster(test_objects.BaseObjectsTestCase):
"""Test Cluster Versioned Object methods."""
cluster = fake_cluster.fake_cluster_orm()
@mock.patch('cinder.db.sqlalchemy.api.cluster_get', return_value=cluster)
def test_get_by_id(self, cluster_get_mock):
filters = _get_filters_sentinel()
cluster = objects.Cluster.get_by_id(self.context,
mock.sentinel.cluster_id,
**filters)
self.assertIsInstance(cluster, objects.Cluster)
self._compare(self, self.cluster, cluster)
cluster_get_mock.assert_called_once_with(self.context,
mock.sentinel.cluster_id,
**filters)
@mock.patch('cinder.db.sqlalchemy.api.cluster_create',
return_value=cluster)
def test_create(self, cluster_create_mock):
cluster = objects.Cluster(context=self.context, name='cluster_name')
cluster.create()
self.assertEqual(self.cluster.id, cluster.id)
cluster_create_mock.assert_called_once_with(self.context,
{'name': 'cluster_name'})
@mock.patch('cinder.db.sqlalchemy.api.cluster_update',
return_value=cluster)
def test_save(self, cluster_update_mock):
cluster = fake_cluster.fake_cluster_ovo(self.context)
cluster.disabled = True
cluster.save()
cluster_update_mock.assert_called_once_with(self.context, cluster.id,
{'disabled': True})
@mock.patch('cinder.db.sqlalchemy.api.cluster_destroy')
def test_destroy(self, cluster_destroy_mock):
cluster = fake_cluster.fake_cluster_ovo(self.context)
cluster.destroy()
cluster_destroy_mock.assert_called_once_with(mock.ANY, cluster.id)
@mock.patch('cinder.db.sqlalchemy.api.cluster_get', return_value=cluster)
def test_refresh(self, cluster_get_mock):
cluster = fake_cluster.fake_cluster_ovo(self.context)
cluster.refresh()
cluster_get_mock.assert_called_once_with(self.context, cluster.id)
def test_is_up_no_last_hearbeat(self):
cluster = fake_cluster.fake_cluster_ovo(self.context,
last_heartbeat=None)
self.assertFalse(bool(cluster.is_up))
def test_is_up(self):
cluster = fake_cluster.fake_cluster_ovo(
self.context,
last_heartbeat=timeutils.utcnow(with_timezone=True))
self.assertTrue(cluster.is_up)
def test_is_up_limit(self):
limit_expired = (utils.service_expired_time(True) +
timeutils.datetime.timedelta(seconds=1))
cluster = fake_cluster.fake_cluster_ovo(self.context,
last_heartbeat=limit_expired)
self.assertTrue(cluster.is_up)
def test_is_up_down(self):
expired_time = (utils.service_expired_time(True) -
timeutils.datetime.timedelta(seconds=1))
cluster = fake_cluster.fake_cluster_ovo(self.context,
last_heartbeat=expired_time)
self.assertFalse(cluster.is_up)
@mock.patch.object(cinder.db, 'conditional_update')
def test_reset_service_replication(self, mock_update):
cluster = fake_cluster.fake_cluster_ovo(self.context)
cluster.reset_service_replication()
mock_update.assert_called_with(self.context, models.Service,
{'replication_status': 'enabled',
'active_backend_id': None},
{'cluster_name': cluster.name})
@ddt.data('1.0', '1.1')
def tests_obj_make_compatible(self, version):
new_fields = {'replication_status': 'error', 'frozen': True,
'active_backend_id': 'replication'}
cluster = objects.Cluster(self.context, **new_fields)
primitive = cluster.obj_to_primitive(version)
converted_cluster = objects.Cluster.obj_from_primitive(primitive)
for key, value in new_fields.items():
if version == '1.0':
self.assertFalse(converted_cluster.obj_attr_is_set(key))
else:
self.assertEqual(value, getattr(converted_cluster, key))
class TestClusterList(test_objects.BaseObjectsTestCase):
"""Test ClusterList Versioned Object methods."""
@mock.patch('cinder.db.sqlalchemy.api.cluster_get_all')
def test_cluster_get_all(self, cluster_get_all_mock):
orm_values = [
fake_cluster.fake_cluster_orm(),
fake_cluster.fake_cluster_orm(id=2, name='cluster_name2'),
]
cluster_get_all_mock.return_value = orm_values
filters = _get_filters_sentinel()
result = objects.ClusterList.get_all(self.context, **filters)
cluster_get_all_mock.assert_called_once_with(
self.context, filters.pop('is_up'), filters.pop('get_services'),
filters.pop('services_summary'), filters.pop('read_deleted'),
filters.pop('name_match_level'), **filters)
self.assertEqual(2, len(result))
for i in range(len(result)):
self.assertIsInstance(result[i], objects.Cluster)
self._compare(self, orm_values[i], result[i])