Merge "Added some test cases for node operations (engine)"

This commit is contained in:
Jenkins 2015-03-20 01:38:26 +00:00 committed by Gerrit Code Review
commit 07514e4294
4 changed files with 321 additions and 13 deletions

View File

@ -694,6 +694,11 @@ class EngineService(service.Service):
def node_list(self, context, cluster_id=None, show_deleted=False,
limit=None, marker=None, sort_keys=None, sort_dir=None,
filters=None, tenant_safe=True):
limit = utils.parse_int_param('limit', limit)
tenant_safe = utils.parse_bool_param('tenant_safe', tenant_safe)
show_deleted = utils.parse_bool_param('show_deleted', show_deleted)
# Maybe the cluster_id is a name or a short ID
if cluster_id is not None:
db_cluster = self.cluster_find(context, cluster_id)
@ -710,18 +715,12 @@ class EngineService(service.Service):
@request_context
def node_create(self, context, name, profile_id, cluster_id=None,
role=None, tags=None):
db_profile = self.profile_find(context, profile_id)
node_profile = self.profile_find(context, profile_id)
if cluster_id is not None:
db_cluster = self.cluster_find(context, cluster_id)
cluster_id = db_cluster.id
if context.project_id != db_cluster.project:
msg = _('Node and cluster are from different project, '
'operation is disallowed.')
raise exception.ProjectNotMatch(message=msg)
if profile_id != db_cluster.profile_id:
node_profile = self.profile_find(context, profile_id)
cluster_profile = self.profile_find(context,
db_cluster.profile_id)
if node_profile.type != cluster_profile.type:
@ -733,7 +732,7 @@ class EngineService(service.Service):
# Create a node instance
tags = tags or {}
node = node_mod.Node(name, db_profile.id, cluster_id, context,
node = node_mod.Node(name, node_profile.id, cluster_id, context,
role=role, tags=tags)
node.store(context)

View File

@ -70,6 +70,7 @@ def dummy_context(user='test_username', tenant_id='test_tenant_id',
roles = roles or []
return context.RequestContext.from_dict({
'tenant_id': tenant_id,
'project_id': tenant_id,
'tenant': 'test_tenant',
'username': user,
'user_id': user_id,

View File

@ -150,7 +150,8 @@ class ClusterTest(base.SenlinTestCase):
self.assertIsNotNone(result)
self.assertEqual(self.profile['id'], result['profile_id'])
self.eng.cluster_create(self.ctx, 'c-2', 0, self.profile['name'])
result = self.eng.cluster_create(self.ctx, 'c-2', 0,
self.profile['name'])
self.assertIsNotNone(result)
self.assertEqual(self.profile['id'], result['profile_id'])
@ -176,10 +177,10 @@ class ClusterTest(base.SenlinTestCase):
self.assertIsInstance(result, list)
names = [c['name'] for c in result]
ids = [c['id'] for c in result]
self.assertIn(c1['name'], names[0])
self.assertIn(c2['name'], names[1])
self.assertIn(c1['id'], ids[0])
self.assertIn(c2['id'], ids[1])
self.assertEqual(c1['name'], names[0])
self.assertEqual(c2['name'], names[1])
self.assertEqual(c1['id'], ids[0])
self.assertEqual(c2['id'], ids[1])
@mock.patch.object(dispatcher, 'notify')
def test_cluster_list_with_limit_marker(self, notify):

View File

@ -0,0 +1,307 @@
# 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 mock
from oslo_messaging.rpc import dispatcher as rpc
import six
from senlin.common import exception
from senlin.db import api as db_api
from senlin.engine.actions import base as action_mod
from senlin.engine import dispatcher
from senlin.engine import environment
from senlin.engine import service
from senlin.tests.common import base
from senlin.tests.common import utils
from senlin.tests import fakes
class NodeTest(base.SenlinTestCase):
def setUp(self):
super(NodeTest, self).setUp()
self.ctx = utils.dummy_context(tenant_id='node_test_tenant')
self.eng = service.EngineService('host-a', 'topic-a')
self.eng.init_tgm()
self.eng.dispatcher = mock.Mock()
env = environment.global_env()
env.register_profile('TestProfile', fakes.TestProfile)
self.profile = self.eng.profile_create(
self.ctx, 'p-test', 'TestProfile',
spec={'INT': 10, 'STR': 'string'}, perm='1111')
def _verify_action(self, obj, action, name, target, cause, inputs=None):
if inputs is None:
inputs = {}
self.assertEqual(action, obj['action'])
self.assertEqual(name, obj['name'])
self.assertEqual(target, obj['target'])
self.assertEqual(cause, obj['cause'])
self.assertEqual(inputs, obj['inputs'])
@mock.patch.object(dispatcher, 'notify')
def test_node_create_default(self, notify):
node = self.eng.node_create(self.ctx, 'n-1', self.profile['id'])
self.assertIsNotNone(node)
self.assertEqual('n-1', node['name'])
self.assertEqual(-1, node['index'])
self.assertEqual(self.profile['id'], node['profile_id'])
self.assertIsNone(node['cluster_id'])
self.assertIsNone(node['role'])
self.assertEqual({}, node['tags'])
action_id = node['action']
action = db_api.action_get(self.ctx, action_id)
self.assertIsNotNone(action)
self._verify_action(action, 'NODE_CREATE',
'node_create_%s' % node['id'][:8],
node['id'],
cause=action_mod.CAUSE_RPC)
notify.assert_called_once_with(self.ctx,
self.eng.dispatcher.NEW_ACTION,
None, action_id=action_id)
def test_node_create_profile_not_found(self):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.ctx, 'n-1', 'Bogus')
self.assertEqual(exception.ProfileNotFound, ex.exc_info[0])
@mock.patch.object(dispatcher, 'notify')
def test_cluster_create_with_role_and_tags(self, notify):
node = self.eng.node_create(self.ctx, 'n-1', self.profile['id'],
role='master', tags={'k': 'v'})
self.assertIsNotNone(node)
self.assertEqual('n-1', node['name'])
self.assertEqual('master', node['role'])
self.assertEqual({'k': 'v'}, node['tags'])
@mock.patch.object(dispatcher, 'notify')
def test_node_create_with_profile_name_or_short_id(self, notify):
node = self.eng.node_create(self.ctx, 'n-1', self.profile['id'][:8])
self.assertIsNotNone(node)
self.assertEqual(self.profile['id'], node['profile_id'])
node = self.eng.node_create(self.ctx, 'n-2', self.profile['name'])
self.assertIsNotNone(node)
self.assertEqual(self.profile['id'], node['profile_id'])
def test_node_create_with_cluster_id_not_found(self):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.ctx, 'n-1', self.profile['id'],
cluster_id='Bogus')
self.assertEqual(exception.ClusterNotFound, ex.exc_info[0])
self.assertEqual("The cluster (Bogus) could not be found.",
six.text_type(ex.exc_info[1]))
@mock.patch.object(dispatcher, 'notify')
def test_node_create_project_not_match(self, notify):
ctx_cluster = utils.dummy_context(tenant_id='a-different-tenant')
cluster = self.eng.cluster_create(ctx_cluster, 'c-1', 0,
self.profile['id'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.ctx, 'n-1', self.profile['id'],
cluster_id=cluster['id'])
self.assertEqual(exception.ClusterNotFound, ex.exc_info[0])
self.assertEqual("The cluster (%s) could not be found."
"" % cluster['id'],
six.text_type(ex.exc_info[1]))
@mock.patch.object(dispatcher, 'notify')
def test_node_create_profile_type_not_match(self, notify):
env = environment.global_env()
env.register_profile('SecondProfile', fakes.TestProfile)
cluster_profile = self.eng.profile_create(
self.ctx, 'cluster-profile', 'SecondProfile',
spec={'INT': 20, 'STR': 'string'})
cluster = self.eng.cluster_create(self.ctx, 'c-1', 0,
cluster_profile['id'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.ctx, 'n-1', self.profile['id'],
cluster_id=cluster['id'])
self.assertEqual(exception.ProfileTypeNotMatch, ex.exc_info[0])
self.assertEqual("Node and cluster have different profile type, "
"operation aborted.",
six.text_type(ex.exc_info[1]))
@mock.patch.object(dispatcher, 'notify')
def test_node_get(self, notify):
node = self.eng.node_create(self.ctx, 'n-1', self.profile['id'])
for identity in [node['id'], node['id'][:6], 'n-1']:
result = self.eng.node_get(self.ctx, identity)
self.assertIsInstance(result, dict)
self.assertEqual(node['id'], result['id'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_get, self.ctx, 'Bogus')
self.assertEqual(exception.NodeNotFound, ex.exc_info[0])
@mock.patch.object(dispatcher, 'notify')
def test_node_list(self, notify):
node1 = self.eng.node_create(self.ctx, 'n1', self.profile['id'])
node2 = self.eng.node_create(self.ctx, 'n2', self.profile['id'])
result = self.eng.node_list(self.ctx)
self.assertIsInstance(result, list)
names = [n['name'] for n in result]
ids = [n['id'] for n in result]
self.assertEqual(node1['name'], names[0])
self.assertEqual(node2['name'], names[1])
self.assertEqual(node1['id'], ids[0])
self.assertEqual(node2['id'], ids[1])
@mock.patch.object(dispatcher, 'notify')
def test_node_list_with_limit_marker(self, notify):
node1 = self.eng.node_create(self.ctx, 'n1', self.profile['id'])
node2 = self.eng.node_create(self.ctx, 'n2', self.profile['id'])
result = self.eng.node_list(self.ctx, limit=0)
self.assertEqual(0, len(result))
result = self.eng.node_list(self.ctx, limit=1)
self.assertEqual(1, len(result))
result = self.eng.node_list(self.ctx, limit=2)
self.assertEqual(2, len(result))
result = self.eng.node_list(self.ctx, limit=3)
self.assertEqual(2, len(result))
result = self.eng.node_list(self.ctx, marker=node1['id'])
self.assertEqual(1, len(result))
result = self.eng.node_list(self.ctx, marker=node2['id'])
self.assertEqual(0, len(result))
self.eng.node_create(self.ctx, 'n3', self.profile['id'])
result = self.eng.node_list(self.ctx, limit=1, marker=node1['id'])
self.assertEqual(1, len(result))
result = self.eng.node_list(self.ctx, limit=2, marker=node1['id'])
self.assertEqual(2, len(result))
@mock.patch.object(dispatcher, 'notify')
def test_node_list_with_sort_keys(self, notify):
node1 = self.eng.node_create(self.ctx, 'CC', self.profile['id'])
node2 = self.eng.node_create(self.ctx, 'BB', self.profile['id'])
# default by created_time
result = self.eng.node_list(self.ctx)
self.assertEqual(node1['id'], result[0]['id'])
self.assertEqual(node2['id'], result[1]['id'])
# use name for sorting
result = self.eng.node_list(self.ctx, sort_keys=['name'])
self.assertEqual(node2['id'], result[0]['id'])
self.assertEqual(node1['id'], result[1]['id'])
# unknown keys will be ignored
result = self.eng.node_list(self.ctx, sort_keys=['duang'])
self.assertIsNotNone(result)
@mock.patch.object(dispatcher, 'notify')
def test_node_list_with_sort_dir(self, notify):
node1 = self.eng.node_create(self.ctx, 'BB', self.profile['id'])
node2 = self.eng.node_create(self.ctx, 'AA', self.profile['id'])
node3 = self.eng.node_create(self.ctx, 'CC', self.profile['id'])
# default by created_time, ascending
result = self.eng.node_list(self.ctx)
self.assertEqual(node1['id'], result[0]['id'])
self.assertEqual(node2['id'], result[1]['id'])
# sort by created_time, descending
result = self.eng.node_list(self.ctx, sort_dir='desc')
self.assertEqual(node3['id'], result[0]['id'])
self.assertEqual(node2['id'], result[1]['id'])
# use name for sorting, descending
result = self.eng.node_list(self.ctx, sort_keys=['name'],
sort_dir='desc')
self.assertEqual(node3['id'], result[0]['id'])
self.assertEqual(node1['id'], result[1]['id'])
# use permission for sorting
ex = self.assertRaises(ValueError,
self.eng.node_list, self.ctx,
sort_dir='Bogus')
self.assertEqual("Unknown sort direction, must be "
"'desc' or 'asc'", six.text_type(ex))
@mock.patch.object(dispatcher, 'notify')
def test_node_list_show_deleted(self, notify):
node = self.eng.node_create(self.ctx, 'n1', self.profile['id'])
result = self.eng.node_list(self.ctx)
self.assertEqual(1, len(result))
self.assertEqual(node['id'], result[0]['id'])
db_api.node_delete(self.ctx, node['id'])
result = self.eng.node_list(self.ctx)
self.assertEqual(0, len(result))
result = self.eng.node_list(self.ctx, show_deleted=True)
self.assertEqual(1, len(result))
self.assertEqual(node['id'], result[0]['id'])
@mock.patch.object(dispatcher, 'notify')
def test_cluster_list_with_cluster_id(self, notify):
c = self.eng.cluster_create(self.ctx, 'c-1', 0, self.profile['id'])
node = self.eng.node_create(self.ctx, 'n1', self.profile['id'],
cluster_id=c['id'])
result = self.eng.node_list(self.ctx, cluster_id=c['id'])
self.assertEqual(1, len(result))
self.assertEqual(node['id'], result[0]['id'])
@mock.patch.object(dispatcher, 'notify')
def test_node_list_with_filters(self, notify):
self.eng.node_create(self.ctx, 'BB', self.profile['id'])
self.eng.node_create(self.ctx, 'AA', self.profile['id'])
self.eng.node_create(self.ctx, 'CC', self.profile['id'])
result = self.eng.node_list(self.ctx, filters={'name': 'BB'})
self.assertEqual(1, len(result))
self.assertEqual('BB', result[0]['name'])
result = self.eng.node_list(self.ctx, filters={'name': 'DD'})
self.assertEqual(0, len(result))
def test_cluster_list_bad_param(self):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_list, self.ctx, limit='no')
self.assertEqual(exception.InvalidParameter, ex.exc_info[0])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_list, self.ctx,
show_deleted='no')
self.assertEqual(exception.InvalidParameter, ex.exc_info[0])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_list, self.ctx,
tenant_safe='no')
self.assertEqual(exception.InvalidParameter, ex.exc_info[0])
def test_cluster_list_empty(self):
result = self.eng.node_list(self.ctx)
self.assertIsInstance(result, list)
self.assertEqual(0, len(result))