Split engine service test cases (4)

This patch separates out test cases related to stack create and
validation. The patch also replaced the existing mox calls with mock
calls.

Change-Id: I346e11d05c6e28fd178f16556e5528b47b39f47c
This commit is contained in:
tengqm 2015-05-13 04:55:58 -04:00
parent 3b5d8cc84a
commit aa7db2ab21
2 changed files with 339 additions and 309 deletions

View File

@ -0,0 +1,337 @@
#
# 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_config import cfg
from oslo_messaging.rpc import dispatcher
import six
from heat.common import exception
from heat.engine.clients.os import glance
from heat.engine.clients.os import nova
from heat.engine import environment
from heat.engine import properties
from heat.engine import resource as res
from heat.engine import service
from heat.engine import stack
from heat.engine import template as templatem
from heat.openstack.common import threadgroup
from heat.tests import common
from heat.tests.engine import tools
from heat.tests import generic_resource as generic_rsrc
from heat.tests.nova import fakes as fakes_nova
from heat.tests import utils
class StackCreateTest(common.HeatTestCase):
def setUp(self):
super(StackCreateTest, self).setUp()
self.ctx = utils.dummy_context()
self.man = service.EngineService('a-host', 'a-topic')
self.man.create_periodic_tasks()
@mock.patch.object(threadgroup, 'ThreadGroup')
@mock.patch.object(stack.Stack, 'validate')
def _test_stack_create(self, stack_name, mock_validate, mock_tg):
mock_tg.return_value = tools.DummyThreadGroup()
params = {'foo': 'bar'}
template = '{ "Template": "data" }'
stk = tools.get_stack(stack_name, self.ctx)
mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
mock_env = self.patchobject(environment, 'Environment',
return_value=stk.env)
mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
result = self.man.create_stack(self.ctx, stack_name,
template, params, None, {})
self.assertEqual(stk.identifier(), result)
self.assertIsInstance(result, dict)
self.assertTrue(result['stack_id'])
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(self.ctx, stack_name, stk.t,
owner_id=None, nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None)
mock_validate.assert_called_once()
def test_stack_create(self):
stack_name = 'service_create_test_stack'
self._test_stack_create(stack_name)
def test_stack_create_equals_max_per_tenant(self):
cfg.CONF.set_override('max_stacks_per_tenant', 1)
stack_name = 'service_create_test_stack_equals_max'
self._test_stack_create(stack_name)
def test_stack_create_exceeds_max_per_tenant(self):
cfg.CONF.set_override('max_stacks_per_tenant', 0)
stack_name = 'service_create_test_stack_exceeds_max'
ex = self.assertRaises(dispatcher.ExpectedException,
self._test_stack_create, stack_name)
self.assertEqual(exception.RequestLimitExceeded, ex.exc_info[0])
self.assertIn("You have reached the maximum stacks per tenant",
six.text_type(ex.exc_info[1]))
@mock.patch.object(stack.Stack, 'validate')
def test_stack_create_verify_err(self, mock_validate):
mock_validate.side_effect = exception.StackValidationFailed(message='')
stack_name = 'service_create_verify_err_test_stack'
params = {'foo': 'bar'}
template = '{ "Template": "data" }'
stk = tools.get_stack(stack_name, self.ctx)
mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
mock_env = self.patchobject(environment, 'Environment',
return_value=stk.env)
mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name, template, params,
None, {})
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(self.ctx, stack_name, stk.t,
owner_id=None, nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None)
def test_stack_create_invalid_stack_name(self):
stack_name = 'service_create_test_stack_invalid_name'
stack = tools.get_stack('test_stack', self.ctx)
self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name, stack.t.t, {}, None, {})
def test_stack_create_invalid_resource_name(self):
stack_name = 'stack_create_invalid_resource_name'
stk = tools.get_stack(stack_name, self.ctx)
tmpl = dict(stk.t)
tmpl['resources']['Web/Server'] = tmpl['resources']['WebServer']
del tmpl['resources']['WebServer']
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name,
stk.t.t, {}, None, {})
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
@mock.patch.object(stack.Stack, 'create_stack_user_project_id')
def test_stack_create_authorization_failure(self, mock_create):
stack_name = 'stack_create_authorization_failure'
stk = tools.get_stack(stack_name, self.ctx)
mock_create.side_effect = exception.AuthorizationFailure
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name,
stk.t.t, {}, None, {})
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
def test_stack_create_no_credentials(self):
cfg.CONF.set_default('deferred_auth_method', 'password')
stack_name = 'test_stack_create_no_credentials'
params = {'foo': 'bar'}
template = '{ "Template": "data" }'
stk = tools.get_stack(stack_name, self.ctx)
# force check for credentials on create
stk['WebServer'].requires_deferred_auth = True
mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
mock_env = self.patchobject(environment, 'Environment',
return_value=stk.env)
mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
# test stack create using context without password
ctx_no_pwd = utils.dummy_context(password=None)
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
ctx_no_pwd, stack_name,
template, params, None, {}, None)
self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
self.assertEqual('Missing required credential: X-Auth-Key',
six.text_type(ex.exc_info[1]))
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(ctx_no_pwd, stack_name, stk.t,
owner_id=None, nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None)
mock_tmpl.reset_mock()
mock_env.reset_mock()
mock_stack.reset_mock()
# test stack create using context without user
ctx_no_pwd = utils.dummy_context(password=None)
ctx_no_user = utils.dummy_context(user=None)
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
ctx_no_user, stack_name,
template, params, None, {})
self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
self.assertEqual('Missing required credential: X-Auth-User',
six.text_type(ex.exc_info[1]))
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(ctx_no_user, stack_name, stk.t,
owner_id=None, nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None)
def test_stack_create_total_resources_equals_max(self):
stack_name = 'stack_create_total_resources_equals_max'
params = {}
res._register_class('FakeResourceType', generic_rsrc.GenericResource)
tpl = {
'heat_template_version': '2014-10-16',
'resources': {
'A': {'type': 'FakeResourceType'},
'B': {'type': 'FakeResourceType'},
'C': {'type': 'FakeResourceType'}
}
}
template = templatem.Template(tpl)
stk = stack.Stack(self.ctx, stack_name, template)
mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
mock_env = self.patchobject(environment, 'Environment',
return_value=stk.env)
mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
cfg.CONF.set_override('max_resources_per_stack', 3)
result = self.man.create_stack(self.ctx, stack_name, template, params,
None, {})
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(self.ctx, stack_name, stk.t,
owner_id=None, nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None)
self.assertEqual(stk.identifier(), result)
self.assertEqual(3, stk.total_resources())
self.man.thread_group_mgr.groups[stk.id].wait()
stk.delete()
def test_stack_create_total_resources_exceeds_max(self):
stack_name = 'stack_create_total_resources_exceeds_max'
params = {}
res._register_class('FakeResourceType', generic_rsrc.GenericResource)
tpl = {
'heat_template_version': '2014-10-16',
'resources': {
'A': {'type': 'FakeResourceType'},
'B': {'type': 'FakeResourceType'},
'C': {'type': 'FakeResourceType'}
}
}
cfg.CONF.set_override('max_resources_per_stack', 2)
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack, self.ctx, stack_name,
tpl, params, None, {})
self.assertEqual(exception.RequestLimitExceeded, ex.exc_info[0])
self.assertIn(exception.StackResourceLimitExceeded.msg_fmt,
six.text_type(ex.exc_info[1]))
def test_stack_validate(self):
stack_name = 'stack_create_test_validate'
stk = tools.get_stack(stack_name, self.ctx)
fc = fakes_nova.FakeClient()
self.patchobject(nova.NovaClientPlugin, '_create', return_value=fc)
self.patchobject(glance.GlanceClientPlugin, 'get_image_id',
return_value=744)
resource = stk['WebServer']
resource.properties = properties.Properties(
resource.properties_schema,
{
'ImageId': 'CentOS 5.2',
'KeyName': 'test',
'InstanceType': 'm1.large'
},
context=self.ctx)
stk.validate()
resource.properties = properties.Properties(
resource.properties_schema,
{
'KeyName': 'test',
'InstanceType': 'm1.large'
},
context=self.ctx)
self.assertRaises(exception.StackValidationFailed, stk.validate)
def test_validate_deferred_auth_context_trusts(self):
stk = tools.get_stack('test_deferred_auth', self.ctx)
stk['WebServer'].requires_deferred_auth = True
ctx = utils.dummy_context(user=None, password=None)
cfg.CONF.set_default('deferred_auth_method', 'trusts')
# using trusts, no username or password required
self.man._validate_deferred_auth_context(ctx, stk)
def test_validate_deferred_auth_context_not_required(self):
stk = tools.get_stack('test_deferred_auth', self.ctx)
stk['WebServer'].requires_deferred_auth = False
ctx = utils.dummy_context(user=None, password=None)
cfg.CONF.set_default('deferred_auth_method', 'password')
# stack performs no deferred operations, so no username or
# password required
self.man._validate_deferred_auth_context(ctx, stk)
def test_validate_deferred_auth_context_missing_credentials(self):
stk = tools.get_stack('test_deferred_auth', self.ctx)
stk['WebServer'].requires_deferred_auth = True
cfg.CONF.set_default('deferred_auth_method', 'password')
# missing username
ctx = utils.dummy_context(user=None)
ex = self.assertRaises(exception.MissingCredentialError,
self.man._validate_deferred_auth_context,
ctx, stk)
self.assertEqual('Missing required credential: X-Auth-User',
six.text_type(ex))
# missing password
ctx = utils.dummy_context(password=None)
ex = self.assertRaises(exception.MissingCredentialError,
self.man._validate_deferred_auth_context,
ctx, stk)
self.assertEqual('Missing required credential: X-Auth-Key',
six.text_type(ex))

View File

@ -31,7 +31,6 @@ from heat.common import service_utils
from heat.common import template_format
from heat.engine import dependencies
from heat.engine import environment
from heat.engine import properties
from heat.engine import resource as res
from heat.engine.resources.aws.ec2 import instance as instances
from heat.engine import service
@ -556,105 +555,15 @@ class StackCreateTest(common.HeatTestCase):
self.assertEqual('COMPLETE', db_s.status, )
class StackServiceCreateUpdateDeleteTest(common.HeatTestCase):
class StackServiceAdoptUpdateDeleteTest(common.HeatTestCase):
def setUp(self):
super(StackServiceCreateUpdateDeleteTest, self).setUp()
super(StackServiceAdoptUpdateDeleteTest, self).setUp()
self.ctx = utils.dummy_context()
self.patch('heat.engine.service.warnings')
self.man = service.EngineService('a-host', 'a-topic')
self.man.create_periodic_tasks()
def _test_stack_create(self, stack_name):
params = {'foo': 'bar'}
template = '{ "Template": "data" }'
stack = tools.get_stack(stack_name, self.ctx)
self.m.StubOutWithMock(templatem, 'Template')
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t, owner_id=None,
nested_depth=0, user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None).AndReturn(stack)
self.m.StubOutWithMock(stack, 'validate')
stack.validate().AndReturn(None)
self.m.StubOutWithMock(threadgroup, 'ThreadGroup')
threadgroup.ThreadGroup().AndReturn(tools.DummyThreadGroup())
self.m.ReplayAll()
result = self.man.create_stack(self.ctx, stack_name,
template, params, None, {})
self.assertEqual(stack.identifier(), result)
self.assertIsInstance(result, dict)
self.assertTrue(result['stack_id'])
self.m.VerifyAll()
def test_stack_create(self):
stack_name = 'service_create_test_stack'
self._test_stack_create(stack_name)
def test_stack_create_equals_max_per_tenant(self):
cfg.CONF.set_override('max_stacks_per_tenant', 1)
stack_name = 'service_create_test_stack_equals_max'
self._test_stack_create(stack_name)
def test_stack_create_exceeds_max_per_tenant(self):
cfg.CONF.set_override('max_stacks_per_tenant', 0)
stack_name = 'service_create_test_stack_exceeds_max'
ex = self.assertRaises(dispatcher.ExpectedException,
self._test_stack_create, stack_name)
self.assertEqual(exception.RequestLimitExceeded, ex.exc_info[0])
self.assertIn("You have reached the maximum stacks per tenant",
six.text_type(ex.exc_info[1]))
def test_stack_create_verify_err(self):
stack_name = 'service_create_verify_err_test_stack'
params = {'foo': 'bar'}
template = '{ "Template": "data" }'
stack = tools.get_stack(stack_name, self.ctx)
self.m.StubOutWithMock(templatem, 'Template')
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t,
owner_id=None,
nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None).AndReturn(stack)
self.m.StubOutWithMock(stack, 'validate')
stack.validate().AndRaise(exception.StackValidationFailed(
message='fubar'))
self.m.ReplayAll()
ex = self.assertRaises(
dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name,
template, params, None, {})
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
self.m.VerifyAll()
def _get_stack_adopt_data_and_template(self, environment=None):
template = {
"heat_template_version": "2013-05-23",
@ -744,182 +653,6 @@ class StackServiceCreateUpdateDeleteTest(common.HeatTestCase):
self.assertEqual(exception.NotSupported, ex.exc_info[0])
self.assertIn('Stack Adopt', six.text_type(ex.exc_info[1]))
def test_stack_create_invalid_stack_name(self):
stack_name = 'service_create_test_stack_invalid_name'
stack = tools.get_stack('test_stack', self.ctx)
self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name, stack.t.t, {}, None, {})
def test_stack_create_invalid_resource_name(self):
stack_name = 'service_create_test_stack_invalid_res'
stack = tools.get_stack(stack_name, self.ctx)
tmpl = dict(stack.t)
tmpl['resources']['Web/Server'] = tmpl['resources']['WebServer']
del tmpl['resources']['WebServer']
self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name,
stack.t.t, {}, None, {})
def test_stack_create_AuthorizationFailure(self):
stack_name = 'service_create_test_stack_AuthorizationFailure'
stack = tools.get_stack(stack_name, self.ctx)
self.m.StubOutWithMock(parser.Stack, 'create_stack_user_project_id')
parser.Stack.create_stack_user_project_id().AndRaise(
exception.AuthorizationFailure)
self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
self.ctx, stack_name,
stack.t.t, {}, None, {})
def test_stack_create_no_credentials(self):
cfg.CONF.set_default('deferred_auth_method', 'password')
stack_name = 'test_stack_create_no_credentials'
params = {'foo': 'bar'}
template = '{ "Template": "data" }'
stack = tools.get_stack(stack_name, self.ctx)
# force check for credentials on create
stack['WebServer'].requires_deferred_auth = True
self.m.StubOutWithMock(templatem, 'Template')
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
ctx_no_pwd = utils.dummy_context(password=None)
ctx_no_user = utils.dummy_context(user=None)
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(ctx_no_pwd, stack.name,
stack.t, owner_id=None,
nested_depth=0, user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None).AndReturn(stack)
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(ctx_no_user, stack.name,
stack.t, owner_id=None,
nested_depth=0, user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None).AndReturn(stack)
self.m.ReplayAll()
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
ctx_no_pwd, stack_name,
template, params, None, {}, None)
self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
self.assertEqual(
'Missing required credential: X-Auth-Key',
six.text_type(ex.exc_info[1]))
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack,
ctx_no_user, stack_name,
template, params, None, {})
self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
self.assertEqual(
'Missing required credential: X-Auth-User',
six.text_type(ex.exc_info[1]))
def test_stack_create_total_resources_equals_max(self):
stack_name = 'service_create_stack_total_resources_equals_max'
params = {}
res._register_class('GenericResourceType',
generic_rsrc.GenericResource)
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
'Resources': {
'A': {'Type': 'GenericResourceType'},
'B': {'Type': 'GenericResourceType'},
'C': {'Type': 'GenericResourceType'}}}
template = templatem.Template(tpl)
stack = parser.Stack(self.ctx, stack_name, template)
self.m.StubOutWithMock(templatem, 'Template')
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t,
owner_id=None,
nested_depth=0,
user_creds_id=None,
stack_user_project_id=None,
convergence=False,
parent_resource=None).AndReturn(stack)
self.m.ReplayAll()
cfg.CONF.set_override('max_resources_per_stack', 3)
result = self.man.create_stack(self.ctx, stack_name, template, params,
None, {})
self.m.VerifyAll()
self.assertEqual(stack.identifier(), result)
self.assertEqual(3, stack.total_resources())
self.man.thread_group_mgr.groups[stack.id].wait()
stack.delete()
def test_stack_create_total_resources_exceeds_max(self):
stack_name = 'service_create_stack_total_resources_exceeds_max'
params = {}
res._register_class('GenericResourceType',
generic_rsrc.GenericResource)
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
'Resources': {
'A': {'Type': 'GenericResourceType'},
'B': {'Type': 'GenericResourceType'},
'C': {'Type': 'GenericResourceType'}}}
cfg.CONF.set_override('max_resources_per_stack', 2)
ex = self.assertRaises(dispatcher.ExpectedException,
self.man.create_stack, self.ctx, stack_name,
tpl, params, None, {})
self.assertEqual(exception.RequestLimitExceeded, ex.exc_info[0])
self.assertIn(exception.StackResourceLimitExceeded.msg_fmt,
six.text_type(ex.exc_info[1]))
def test_stack_validate(self):
stack_name = 'service_create_test_validate'
stack = tools.get_stack(stack_name, self.ctx)
tools.setup_mocks(self.m, stack, mock_image_constraint=False)
resource = stack['WebServer']
tools.setup_mock_for_image_constraint(self.m, 'CentOS 5.2')
self.m.ReplayAll()
resource.properties = properties.Properties(
resource.properties_schema,
{
'ImageId': 'CentOS 5.2',
'KeyName': 'test',
'InstanceType': 'm1.large'
},
context=self.ctx)
stack.validate()
resource.properties = properties.Properties(
resource.properties_schema,
{
'KeyName': 'test',
'InstanceType': 'm1.large'
},
context=self.ctx)
self.assertRaises(exception.StackValidationFailed, stack.validate)
def test_stack_delete(self):
stack_name = 'service_delete_test_stack'
stack = tools.get_stack(stack_name, self.ctx)
@ -1583,46 +1316,6 @@ class StackServiceCreateUpdateDeleteTest(common.HeatTestCase):
self.m.VerifyAll()
def test_validate_deferred_auth_context_trusts(self):
stack = tools.get_stack('test_deferred_auth', self.ctx)
stack['WebServer'].requires_deferred_auth = True
ctx = utils.dummy_context(user=None, password=None)
cfg.CONF.set_default('deferred_auth_method', 'trusts')
# using trusts, no username or password required
self.man._validate_deferred_auth_context(ctx, stack)
def test_validate_deferred_auth_context_not_required(self):
stack = tools.get_stack('test_deferred_auth', self.ctx)
stack['WebServer'].requires_deferred_auth = False
ctx = utils.dummy_context(user=None, password=None)
cfg.CONF.set_default('deferred_auth_method', 'password')
# stack performs no deferred operations, so no username or
# password required
self.man._validate_deferred_auth_context(ctx, stack)
def test_validate_deferred_auth_context_missing_credentials(self):
stack = tools.get_stack('test_deferred_auth', self.ctx)
stack['WebServer'].requires_deferred_auth = True
cfg.CONF.set_default('deferred_auth_method', 'password')
# missing username
ctx = utils.dummy_context(user=None)
ex = self.assertRaises(exception.MissingCredentialError,
self.man._validate_deferred_auth_context,
ctx, stack)
self.assertEqual('Missing required credential: X-Auth-User',
six.text_type(ex))
# missing password
ctx = utils.dummy_context(password=None)
ex = self.assertRaises(exception.MissingCredentialError,
self.man._validate_deferred_auth_context,
ctx, stack)
self.assertEqual('Missing required credential: X-Auth-Key',
six.text_type(ex))
class StackConvergenceServiceCreateUpdateTest(common.HeatTestCase):