Merge "Move 'to_dict' to cluster object"

This commit is contained in:
Jenkins 2017-02-05 02:46:16 +00:00 committed by Gerrit Code Review
commit c173fc95ce
10 changed files with 191 additions and 158 deletions

View File

@ -103,6 +103,10 @@ def node_get_all_by_cluster(context, cluster_id, project_safe=True):
project_safe=project_safe)
def node_ids_by_cluster(context, cluster_id):
return IMPL.node_ids_by_cluster(context, cluster_id)
def node_count_by_cluster(context, cluster_id, **kwargs):
return IMPL.node_count_by_cluster(context, cluster_id, **kwargs)
@ -186,6 +190,10 @@ def cluster_policy_get_all(context, cluster_id, filters=None, sort=None):
sort=sort)
def cluster_policy_ids_by_cluster(context, cluster_id):
return IMPL.cluster_policy_ids_by_cluster(context, cluster_id)
def cluster_policy_get_by_type(context, cluster_id, policy_type, filters=None):
return IMPL.cluster_policy_get_by_type(context, cluster_id, policy_type,
filters=filters)

View File

@ -276,6 +276,14 @@ def node_get_all_by_cluster(context, cluster_id, project_safe=True):
project_safe=project_safe).all()
def node_ids_by_cluster(context, cluster_id):
"""an internal API for getting node IDs."""
with session_for_read() as session:
nodes = session.query(models.Node.id).filter_by(
cluster_id=cluster_id).all()
return [n[0] for n in nodes]
def node_count_by_cluster(context, cluster_id, **kwargs):
project_safe = kwargs.pop('project_safe', True)
query = model_query(context, models.Node)
@ -616,6 +624,14 @@ def cluster_policy_get_all(context, cluster_id, filters=None, sort=None):
keys, sort_dirs=dirs).all()
def cluster_policy_ids_by_cluster(context, cluster_id):
"""an internal API for getting cluster IDs."""
with session_for_read() as session:
policies = session.query(models.ClusterPolicies.policy_id).filter_by(
cluster_id=cluster_id).all()
return [p[0] for p in policies]
def cluster_policy_get_by_type(context, cluster_id, policy_type, filters=None):
query = model_query(context, models.ClusterPolicies)

View File

@ -17,7 +17,6 @@ from oslo_utils import timeutils
from senlin.common import consts
from senlin.common import exception
from senlin.common.i18n import _, _LE
from senlin.common import utils
from senlin.engine import cluster_policy as cpm
from senlin.engine import health_manager
from senlin.engine import node as node_mod
@ -199,36 +198,6 @@ class Cluster(object):
cluster = cls._from_object(context, obj)
yield cluster
def to_dict(self):
info = {
'id': self.id,
'name': self.name,
'profile_id': self.profile_id,
'user': self.user,
'project': self.project,
'domain': self.domain,
'init_at': utils.isotime(self.init_at),
'created_at': utils.isotime(self.created_at),
'updated_at': utils.isotime(self.updated_at),
'min_size': self.min_size,
'max_size': self.max_size,
'desired_capacity': self.desired_capacity,
'timeout': self.timeout,
'status': self.status,
'status_reason': self.status_reason,
'metadata': self.metadata,
'data': self.data,
'dependents': self.dependents,
'nodes': [node.id for node in self.rt['nodes']],
'policies': [policy.id for policy in self.rt['policies']],
}
if self.rt['profile']:
info['profile_name'] = self.rt['profile'].name
else:
info['profile_name'] = None
return info
def set_status(self, context, status, reason=None, **kwargs):
"""Set status of the cluster.

View File

@ -696,8 +696,7 @@ class EngineService(service.Service):
if filters:
query['filters'] = filters
return [c.to_dict()
for c in cluster_mod.Cluster.load_all(ctx, **query)]
return [c.to_dict() for c in co.Cluster.get_all(ctx, **query)]
@request_context
def cluster_get(self, context, req):
@ -707,8 +706,7 @@ class EngineService(service.Service):
:param req: An instance of the ClusterGetRequest.
:return: A dictionary containing the details about a cluster.
"""
db_cluster = co.Cluster.find(context, req.identity)
cluster = cluster_mod.Cluster.load(context, dbcluster=db_cluster)
cluster = co.Cluster.find(context, req.identity)
return cluster.to_dict()
def check_cluster_quota(self, context):
@ -759,19 +757,24 @@ class EngineService(service.Service):
LOG.info(_LI("Creating cluster '%s'."), req.name)
kwargs = {
'min_size': req.min_size,
'max_size': req.max_size,
'timeout': req.timeout,
'metadata': req.metadata,
values = {
'name': req.name,
'profile_id': db_profile.id,
'desired_capacity': req.desired_capacity,
'min_size': req.min_size or consts.CLUSTER_DEFAULT_MIN_SIZE,
'max_size': req.max_size or consts.CLUSTER_DEFAULT_MAX_DIZE,
'next_index': 1,
'timeout': req.timeout or cfg.CONF.default_action_timeout,
'status': consts.CS_INIT,
'status_reason': 'Initializing',
'data': {},
'metadata': req.metadata or {},
'dependents': {},
'user': ctx.user,
'project': ctx.project,
'domain': ctx.domain,
}
cluster = cluster_mod.Cluster(req.name, req.desired_capacity,
db_profile.id, **kwargs)
cluster.store(ctx)
cluster = co.Cluster.create(ctx, values)
# Build an Action for cluster creation
kwargs = {
@ -797,8 +800,7 @@ class EngineService(service.Service):
:return: A dictionary containing the details about the cluster and the
ID of the action triggered by this operation.
"""
db_cluster = co.Cluster.find(ctx, req.identity)
cluster = cluster_mod.Cluster.load(ctx, dbcluster=db_cluster)
cluster = co.Cluster.find(ctx, req.identity)
if cluster.status == consts.CS_ERROR:
msg = _('Updating a cluster in error state')
LOG.error(msg)

View File

@ -12,9 +12,12 @@
"""Cluster object."""
from oslo_utils import timeutils
from oslo_utils import uuidutils
from senlin.common import context as senlin_context
from senlin.common import exception as exc
from senlin.common import utils
from senlin.db import api as db_api
from senlin.objects import base
from senlin.objects import fields
@ -50,6 +53,7 @@ class Cluster(base.SenlinObject, base.VersionedObjectDictCompat):
@classmethod
def create(cls, context, values):
values = cls._transpose_metadata(values)
values['init_at'] = timeutils.utcnow(True)
obj = db_api.cluster_create(context, values)
return cls._from_db_object(context, cls(context), obj)
@ -105,8 +109,37 @@ class Cluster(base.SenlinObject, base.VersionedObjectDictCompat):
@classmethod
def update(cls, context, obj_id, values):
values = cls._transpose_metadata(values)
values['updated_at'] = timeutils.utcnow(True)
return db_api.cluster_update(context, obj_id, values)
@classmethod
def delete(cls, context, obj_id):
db_api.cluster_delete(context, obj_id)
def to_dict(self):
context = senlin_context.get_admin_context()
profile = db_api.profile_get(context, self.profile_id,
project_safe=False)
return {
'id': self.id,
'name': self.name,
'profile_id': self.profile_id,
'user': self.user,
'project': self.project,
'domain': self.domain,
'init_at': utils.isotime(self.init_at),
'created_at': utils.isotime(self.created_at),
'updated_at': utils.isotime(self.updated_at),
'min_size': self.min_size,
'max_size': self.max_size,
'desired_capacity': self.desired_capacity,
'timeout': self.timeout,
'status': self.status,
'status_reason': self.status_reason,
'metadata': self.metadata or {},
'data': self.data or {},
'dependents': self.dependents or {},
'profile_name': profile.name,
'nodes': db_api.node_ids_by_cluster(context, self.id),
'policies': db_api.cluster_policy_ids_by_cluster(context, self.id)
}

View File

@ -301,3 +301,17 @@ class DBAPIClusterPolicyTest(base.SenlinTestCase):
results = db_api.cluster_policy_get_all(self.ctx, self.cluster.id,
filters=filters)
self.assertEqual(0, len(results))
def test_cluster_policy_ids_by_cluster(self):
# prepare
ids = []
for i in range(3):
policy_id = self.create_policy().id
ids.append(policy_id)
db_api.cluster_policy_attach(self.ctx, self.cluster.id, policy_id,
{'enabled': True})
# sorted by enabled, the 2nd and 3rd are unpredictable
results = db_api.cluster_policy_ids_by_cluster(self.ctx,
self.cluster.id)
self.assertEqual(set(ids), set(results))

View File

@ -484,6 +484,20 @@ class DBAPINodeTest(base.SenlinTestCase):
project_safe=False)
self.assertEqual(2, res)
def test_nodeids_by_cluster(self):
node0 = shared.create_node(self.ctx, None, self.profile)
node1 = shared.create_node(self.ctx, self.cluster, self.profile)
node2 = shared.create_node(self.ctx, self.cluster, self.profile)
results = db_api.node_ids_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(2, len(results))
self.assertEqual(set([node1.id, node2.id]), set(results))
# retrieve orphan nodes
results = db_api.node_ids_by_cluster(self.ctx, '')
self.assertEqual(1, len(results))
self.assertEqual(node0.id, results[0])
def test_node_update(self):
node = shared.create_node(self.ctx, self.cluster, self.profile)
new_attributes = {

View File

@ -22,7 +22,6 @@ from senlin.common.i18n import _
from senlin.common import scaleutils as su
from senlin.common import utils as common_utils
from senlin.engine.actions import base as am
from senlin.engine import cluster as cm
from senlin.engine import dispatcher
from senlin.engine import node as nm
from senlin.engine import service
@ -80,23 +79,23 @@ class ClusterTest(base.SenlinTestCase):
setattr(req_obj, k, v)
req_base.obj_from_primitive.return_value = req_obj
@mock.patch.object(cm.Cluster, 'load_all')
def test_cluster_list(self, mock_load):
@mock.patch.object(co.Cluster, 'get_all')
def test_cluster_list(self, mock_get):
x_obj_1 = mock.Mock()
x_obj_1.to_dict.return_value = {'k': 'v1'}
x_obj_2 = mock.Mock()
x_obj_2.to_dict.return_value = {'k': 'v2'}
mock_load.return_value = [x_obj_1, x_obj_2]
mock_get.return_value = [x_obj_1, x_obj_2]
req = orco.ClusterListRequest(project_safe=True)
result = self.eng.cluster_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_load.assert_called_once_with(self.ctx, project_safe=True)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@mock.patch.object(cm.Cluster, 'load_all')
def test_cluster_list_with_params(self, mock_load):
mock_load.return_value = []
@mock.patch.object(co.Cluster, 'get_all')
def test_cluster_list_with_params(self, mock_get):
mock_get.return_value = []
marker = uuidutils.generate_uuid()
req = {
'limit': 10,
@ -111,7 +110,7 @@ class ClusterTest(base.SenlinTestCase):
result = self.eng.cluster_list(self.ctx, req)
self.assertEqual([], result)
mock_load.assert_called_once_with(
mock_get.assert_called_once_with(
self.ctx, limit=10, marker=marker, sort='name:asc',
filters={'name': ['test_cluster'], 'status': ['ACTIVE']},
project_safe=True)
@ -119,7 +118,7 @@ class ClusterTest(base.SenlinTestCase):
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(su, 'check_size_params')
@mock.patch.object(am.Action, 'create')
@mock.patch("senlin.engine.cluster.Cluster")
@mock.patch.object(co.Cluster, "create")
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(dispatcher, 'start_action')
def test_cluster_create(self, notify, mock_profile, mock_cluster,
@ -142,11 +141,12 @@ class ClusterTest(base.SenlinTestCase):
mock_profile.assert_called_once_with(self.ctx, 'PROFILE')
mock_check.assert_called_once_with(None, 3, None, None, True)
mock_cluster.assert_called_once_with(
'C1', 3, 'PROFILE_ID',
min_size=0, max_size=-1, timeout=3600, metadata={},
user=self.ctx.user, project=self.ctx.project,
domain=self.ctx.domain)
x_cluster.store.assert_called_once_with(self.ctx)
self.ctx,
dict(name='C1', desired_capacity=3, profile_id='PROFILE_ID',
min_size=0, max_size=-1, timeout=3600, metadata={},
dependents={}, data={}, next_index=1, status='INIT',
status_reason='Initializing', user=self.ctx.user,
project=self.ctx.project, domain=self.ctx.domain))
mock_action.assert_called_once_with(
self.ctx,
'12345678ABC', 'CLUSTER_CREATE',
@ -226,21 +226,17 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual("INVALID.", six.text_type(ex.exc_info[1]))
mock_find.assert_called_once_with(self.ctx, 'PROFILE')
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(co.Cluster, 'find')
def test_cluster_get(self, mock_find, mock_load):
x_obj = mock.Mock()
mock_find.return_value = x_obj
def test_cluster_get(self, mock_find):
x_cluster = mock.Mock()
x_cluster.to_dict.return_value = {'foo': 'bar'}
mock_load.return_value = x_cluster
mock_find.return_value = x_cluster
req = orco.ClusterGetRequest(identity='C1')
result = self.eng.cluster_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
@mock.patch.object(co.Cluster, 'find')
def test_cluster_get_not_found(self, mock_find):
@ -255,19 +251,16 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@mock.patch.object(am.Action, 'create')
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(co.Cluster, 'find')
@mock.patch.object(dispatcher, 'start_action')
def test_cluster_update(self, notify, mock_find, mock_profile, mock_load,
def test_cluster_update(self, notify, mock_find, mock_profile,
mock_action):
x_obj = mock.Mock()
mock_find.return_value = x_obj
x_cluster = mock.Mock(id='12345678AB', status='ACTIVE',
profile_id='OLD_PROFILE',
metadata={'A': 'B'})
x_cluster.to_dict.return_value = {'foo': 'bar'}
mock_load.return_value = x_cluster
mock_find.return_value = x_cluster
old_profile = mock.Mock(type='FAKE_TYPE', id='ID_OLD')
new_profile = mock.Mock(type='FAKE_TYPE', id='ID_NEW')
mock_profile.side_effect = [old_profile, new_profile]
@ -281,7 +274,6 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
mock_profile.assert_has_calls([
mock.call(self.ctx, 'OLD_PROFILE'),
mock.call(self.ctx, 'NEW_PROFILE'),
@ -312,13 +304,10 @@ class ClusterTest(base.SenlinTestCase):
self.ctx, req)
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(co.Cluster, 'find')
def test_cluster_update_cluster_bad_status(self, mock_find, mock_load):
x_obj = mock.Mock()
mock_find.return_value = x_obj
def test_cluster_update_cluster_bad_status(self, mock_find):
x_cluster = mock.Mock(status='ERROR')
mock_load.return_value = x_cluster
mock_find.return_value = x_cluster
req = {'identity': 'CLUSTER', 'name': 'new-name'}
self._prepare_request(req)
@ -331,16 +320,11 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual('Updating a cluster in error state is not supported.',
six.text_type(ex.exc_info[1]))
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(co.Cluster, 'find')
def test_cluster_update_profile_not_found(self, mock_find, mock_load,
mock_profile):
x_obj = mock.Mock()
mock_find.return_value = x_obj
mock_load.return_value = mock.Mock(status='ACTIVE',
def test_cluster_update_profile_not_found(self, mock_find, mock_profile):
mock_find.return_value = mock.Mock(status='ACTIVE',
profile_id='OLD_ID')
mock_profile.side_effect = [
mock.Mock(type='FAKE_TYPE', id='OLD_ID'),
@ -356,21 +340,16 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual("The specified profile 'Bogus' could not be found.",
six.text_type(ex.exc_info[1]))
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
mock_profile.assert_has_calls([
mock.call(self.ctx, 'OLD_ID'),
mock.call(self.ctx, 'Bogus'),
])
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(co.Cluster, 'find')
def test_cluster_update_diff_profile_type(self, mock_find, mock_load,
mock_profile):
x_obj = mock.Mock()
def test_cluster_update_diff_profile_type(self, mock_find, mock_profile):
x_obj = mock.Mock(status='ACTIVE', profile_id='OLD_ID')
mock_find.return_value = x_obj
mock_load.return_value = mock.Mock(status='ACTIVE',
profile_id='OLD_ID')
mock_profile.side_effect = [
mock.Mock(type='FAKE_TYPE', id='OLD_ID'),
mock.Mock(type='DIFF_TYPE', id='NEW_ID'),
@ -384,26 +363,21 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual(exc.BadRequest, ex.exc_info[0])
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
mock_profile.assert_has_calls([
mock.call(self.ctx, 'OLD_ID'),
mock.call(self.ctx, 'NEW_PROFILE'),
])
@mock.patch.object(am.Action, 'create')
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(co.Cluster, 'find')
@mock.patch.object(dispatcher, 'start_action')
def test_cluster_update_same_profile(self, notify, mock_find,
mock_profile, mock_load,
mock_action):
x_obj = mock.Mock()
mock_find.return_value = x_obj
mock_profile, mock_action):
x_cluster = mock.Mock(id='12345678AB', status='ACTIVE',
profile_id='OLD_PROFILE')
x_cluster.to_dict.return_value = {'foo': 'bar'}
mock_load.return_value = x_cluster
mock_find.return_value = x_cluster
old_profile = mock.Mock(type='FAKE_TYPE', id='ID_OLD')
new_profile = mock.Mock(type='FAKE_TYPE', id='ID_OLD')
mock_profile.side_effect = [old_profile, new_profile]
@ -416,7 +390,6 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
mock_profile.assert_has_calls([
mock.call(self.ctx, 'OLD_PROFILE'),
mock.call(self.ctx, 'NEW_PROFILE'),
@ -434,17 +407,14 @@ class ClusterTest(base.SenlinTestCase):
notify.assert_called_once_with()
@mock.patch.object(am.Action, 'create')
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(co.Cluster, 'find')
@mock.patch.object(dispatcher, 'start_action')
def test_cluster_update_same_metadata(self, notify, mock_find, mock_load,
def test_cluster_update_same_metadata(self, notify, mock_find,
mock_action):
x_obj = mock.Mock()
mock_find.return_value = x_obj
x_cluster = mock.Mock(id='12345678AB', status='ACTIVE',
metadata={'K': 'V'})
x_cluster.to_dict.return_value = {'foo': 'bar'}
mock_load.return_value = x_cluster
mock_find.return_value = x_cluster
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterUpdateRequest(identity='FAKE_ID', name='NEW_NAME',
metadata={'K': 'V'})
@ -454,7 +424,6 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
mock_load.assert_called_once_with(self.ctx, dbcluster=x_obj)
mock_action.assert_called_once_with(
self.ctx, '12345678AB', 'CLUSTER_UPDATE',
name='cluster_update_12345678',
@ -467,18 +436,16 @@ class ClusterTest(base.SenlinTestCase):
)
notify.assert_called_once_with()
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(co.Cluster, 'find')
def test_cluster_update_no_property_updated(self, mock_find, mock_load):
x_obj = mock.Mock()
mock_find.return_value = x_obj
mock_load.return_value = mock.Mock(status='ACTIVE',
profile_id='OLD_ID')
def test_cluster_update_no_property_updated(self, mock_find):
x_cluster = mock.Mock(status='ACTIVE', profile_id='OLD_ID')
mock_find.return_value = x_cluster
req = orco.ClusterUpdateRequest(identity='CLUSTER')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual('', six.text_type(ex))

View File

@ -12,7 +12,6 @@
import mock
from oslo_config import cfg
from oslo_utils import timeutils
import six
from senlin.common import consts
@ -261,48 +260,6 @@ class TestCluster(base.SenlinTestCase):
mock.call(self.context, x_obj_1),
mock.call(self.context, x_obj_2)])
@mock.patch.object(cm.Cluster, '_load_runtime_data')
def test_to_dict(self, mock_load):
values = {
'id': CLUSTER_ID,
'profile_id': PROFILE_ID,
'name': 'test-cluster',
'desired_capacity': 1,
'status': 'INIT',
'init_at': timeutils.utcnow(True),
'user': self.context.user,
'project': self.context.project,
}
cluster = co.Cluster.create(self.context, values)
expected = {
'id': CLUSTER_ID,
'name': cluster.name,
'profile_id': PROFILE_ID,
'user': cluster.user,
'project': cluster.project,
'domain': cluster.domain,
'init_at': mock.ANY,
'created_at': None,
'updated_at': None,
'min_size': 0,
'max_size': -1,
'desired_capacity': 1,
'timeout': cfg.CONF.default_action_timeout,
'status': 'INIT',
'status_reason': None,
'metadata': {},
'data': None,
'dependents': {},
'nodes': [],
'policies': [],
'profile_name': None,
}
result = cm.Cluster.load(self.context, cluster_id=CLUSTER_ID)
self.assertEqual(expected, result.to_dict())
@mock.patch.object(co.Cluster, 'update')
def test_set_status_for_create(self, mock_update):
cluster = cm.Cluster('test-cluster', 0, PROFILE_ID,

View File

@ -11,18 +11,22 @@
# under the License.
import mock
from oslo_config import cfg
from oslo_utils import timeutils
from oslo_utils import uuidutils
import testtools
from senlin.common import exception as exc
from senlin.db import api as db_api
from senlin.objects import cluster as co
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class TestCluster(testtools.TestCase):
class TestCluster(base.SenlinTestCase):
def setUp(self):
super(TestCluster, self).setUp()
self.ctx = mock.Mock()
self.ctx = utils.dummy_context()
@mock.patch.object(co.Cluster, 'get')
def test_find_by_uuid(self, mock_get):
@ -91,3 +95,52 @@ class TestCluster(testtools.TestCase):
project_safe=True)
mock_get_short_id.assert_called_once_with(self.ctx, 'bogus',
project_safe=True)
@mock.patch.object(db_api, 'cluster_policy_ids_by_cluster')
@mock.patch.object(db_api, 'node_ids_by_cluster')
@mock.patch.object(db_api, 'profile_get')
def test_to_dict(self, mock_profile, mock_nodes, mock_bindings):
PROFILE_ID = '96f4df4b-889e-4184-ba8d-b5ca122f95bb'
values = {
'profile_id': PROFILE_ID,
'name': 'test-cluster',
'desired_capacity': 1,
'status': 'INIT',
'init_at': timeutils.utcnow(True),
'max_size': -1,
'min_size': 0,
'timeout': cfg.CONF.default_action_timeout,
'user': self.ctx.user,
'project': self.ctx.project,
}
cluster = co.Cluster.create(self.ctx, values)
fake_profile = mock.Mock()
fake_profile.name = 'PROFILEABC'
mock_profile.return_value = fake_profile
mock_nodes.return_value = ['N1', 'N2']
mock_bindings.return_value = ['P1', 'P2']
expected = {
'id': cluster.id,
'name': cluster.name,
'profile_id': PROFILE_ID,
'user': cluster.user,
'project': cluster.project,
'domain': cluster.domain,
'init_at': mock.ANY,
'created_at': None,
'updated_at': None,
'min_size': 0,
'max_size': -1,
'desired_capacity': 1,
'timeout': cfg.CONF.default_action_timeout,
'status': 'INIT',
'status_reason': None,
'metadata': {},
'data': {},
'dependents': {},
'nodes': ['N1', 'N2'],
'policies': ['P1', 'P2'],
'profile_name': 'PROFILEABC',
}
self.assertEqual(expected, cluster.to_dict())