Produce more meaningful exception messages in nested stacks

This produces a nested exception like:
 'ValueError: resources.nested.resources.my_server: it is broken, sorry'

This re-uses the path mechanism that StackValidationFailed exception
uses.

Change-Id: Id5204c15ee96784e04522ab3c5a8e66900f9a1d3
Closes-bug: 1459837
This commit is contained in:
Angus Salkeld 2015-06-24 08:52:08 +10:00
parent beafdb8cab
commit caa1bd8602
38 changed files with 401 additions and 164 deletions

View File

@ -179,7 +179,8 @@ class CloudServersTest(common.HeatTestCase):
self.m.ReplayAll()
create = scheduler.TaskRunner(server.create)
exc = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual('Error: RackConnect automation FAILED',
self.assertEqual('Error: resources.test_rackconnect_failed: '
'RackConnect automation FAILED',
six.text_type(exc))
def test_rackconnect_unprocessable(self):
@ -210,7 +211,8 @@ class CloudServersTest(common.HeatTestCase):
self.m.ReplayAll()
create = scheduler.TaskRunner(server.create)
exc = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual('Error: Unknown RackConnect automation status: FOO',
self.assertEqual('Error: resources.test_rackconnect_unknown: '
'Unknown RackConnect automation status: FOO',
six.text_type(exc))
def test_rackconnect_deploying(self):
@ -309,7 +311,8 @@ class CloudServersTest(common.HeatTestCase):
self.m.ReplayAll()
create = scheduler.TaskRunner(server.create)
exc = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual('Error: Managed Cloud automation failed',
self.assertEqual('Error: resources.test_managed_cloud_build_error: '
'Managed Cloud automation failed',
six.text_type(exc))
def test_managed_cloud_unknown(self):
@ -323,7 +326,8 @@ class CloudServersTest(common.HeatTestCase):
self.m.ReplayAll()
create = scheduler.TaskRunner(server.create)
exc = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual('Error: Unknown Managed Cloud automation status: FOO',
self.assertEqual('Error: resources.test_managed_cloud_unknown: '
'Unknown Managed Cloud automation status: FOO',
six.text_type(exc))
def _test_server_config_drive(self, user_data, config_drive, result):

View File

@ -253,7 +253,7 @@ class StackExists(HeatException):
msg_fmt = _("The Stack (%(stack_name)s) already exists.")
class StackValidationFailed(HeatException):
class HeatExceptionWithPath(HeatException):
msg_fmt = _("%(error)s%(path)s%(message)s")
def __init__(self, error=None, path=None, message=None):
@ -275,8 +275,8 @@ class StackValidationFailed(HeatException):
result_path = path_item
self.error_message = message or ''
super(StackValidationFailed, self).__init__(
error=('%s : ' % self.error if self.error != '' else ''),
super(HeatExceptionWithPath, self).__init__(
error=('%s: ' % self.error if self.error != '' else ''),
path=('%s: ' % result_path if len(result_path) > 0 else ''),
message=self.error_message
)
@ -291,6 +291,10 @@ class StackValidationFailed(HeatException):
return self.error_message
class StackValidationFailed(HeatExceptionWithPath):
pass
class InvalidSchemaError(HeatException):
msg_fmt = _("%(message)s")
@ -333,18 +337,63 @@ class WatchRuleNotFound(HeatException):
msg_fmt = _("The Watch Rule (%(watch_name)s) could not be found.")
class ResourceFailure(HeatException):
msg_fmt = _("%(exc_type)s: %(message)s")
def __init__(self, exception, resource, action=None):
if isinstance(exception, ResourceFailure):
exception = getattr(exception, 'exc', exception)
self.exc = exception
class ResourceFailure(HeatExceptionWithPath):
def __init__(self, exception_or_error, resource, action=None):
self.resource = resource
self.action = action
exc_type = type(exception).__name__
super(ResourceFailure, self).__init__(exc_type=exc_type,
message=six.text_type(exception))
if action is None and resource is not None:
self.action = resource.action
path = []
res_path = []
if resource is not None:
res_path = [resource.stack.t.get_section_name('resources'),
resource.name]
if isinstance(exception_or_error, Exception):
if isinstance(exception_or_error, ResourceFailure):
self.exc = exception_or_error.exc
error = exception_or_error.error
message = exception_or_error.error_message
path = exception_or_error.path
else:
self.exc = exception_or_error
error = six.text_type(type(self.exc).__name__)
message = six.text_type(self.exc)
path = res_path
else:
self.exc = None
res_failed = 'Resource %s failed: ' % action.upper()
if res_failed in exception_or_error:
(error, message, new_path) = self._from_status_reason(
exception_or_error)
path = res_path + new_path
else:
path = res_path
error = None
message = exception_or_error
super(ResourceFailure, self).__init__(error=error, path=path,
message=message)
def _from_status_reason(self, status_reason):
"""Split the status_reason up into parts.
Given the following status_reason:
"Resource DELETE failed: Exception : resources.AResource: foo"
we are going to return:
("Exception", "resources.AResource", "foo")
"""
parsed = [sp.strip() for sp in status_reason.split(':')]
if len(parsed) >= 4:
error = parsed[1]
message = ': '.join(parsed[3:])
path = parsed[2].split('.')
else:
error = ''
message = status_reason
path = []
return (error, message, path)
class NotSupported(HeatException):

View File

@ -370,12 +370,12 @@ class StackResource(resource.Resource):
elif nested.status == resource.Resource.COMPLETE:
return True
elif nested.status == resource.Resource.FAILED:
raise resource.ResourceUnknownStatus(
resource_status=nested.status,
status_reason=nested.status_reason)
raise exception.ResourceFailure(nested.status_reason, self,
action=action)
else:
raise resource.ResourceUnknownStatus(
resource_status=nested.status,
status_reason=nested.status_reason,
result=_('Stack unknown status'))
def check_adopt_complete(self, cookie=None):

View File

@ -131,7 +131,7 @@ class LaunchConfigurationTest(common.HeatTestCase):
self.patchobject(nova.NovaClientPlugin, 'get_server',
side_effect=exception.EntityNotFound(
entity='Server', name='5678'))
msg = ("Property error : "
msg = ("Property error: "
"Resources.LaunchConfig.Properties.InstanceId: "
"Error validating value '5678': The Server (5678) "
"could not be found.")
@ -194,7 +194,7 @@ class LaunchConfigurationTest(common.HeatTestCase):
stack, 'LaunchConfig')
excepted_error = (
'Property error : '
'Property error: '
'Resources.LaunchConfig.Properties.BlockDeviceMappings[0]: '
'Property DeviceName not assigned')
self.assertIn(excepted_error, six.text_type(e))

View File

@ -217,7 +217,7 @@ class TestAutoScalingGroupValidation(common.HeatTestCase):
rsrc = stack['WebServerGroup']
self._stub_nova_server_get(not_found=True)
self.m.ReplayAll()
msg = ("Property error : "
msg = ("Property error: "
"Resources.WebServerGroup.Properties.InstanceId: "
"Error validating value '5678': The Server (5678) could "
"not be found.")

View File

@ -325,7 +325,7 @@ class InstancesTest(common.HeatTestCase):
exc = self.assertRaises(exception.StackValidationFailed,
instance.validate)
excepted_error = (
'Property error : '
'Property error: '
'Resources.WebServer.Properties.BlockDeviceMappings[0]: '
'Property DeviceName not assigned')
self.assertIn(excepted_error, six.text_type(exc))
@ -385,7 +385,8 @@ class InstancesTest(common.HeatTestCase):
create = scheduler.TaskRunner(instance.create)
error = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(
"StackValidationFailed: Property error : "
"StackValidationFailed: resources.instance_create_image_err: "
"Property error: "
"WebServer.Properties.ImageId: Error validating value "
"'Slackware': The Image (Slackware) could not be found.",
six.text_type(error))
@ -412,7 +413,8 @@ class InstancesTest(common.HeatTestCase):
create = scheduler.TaskRunner(instance.create)
error = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(
'StackValidationFailed: Property error : '
'StackValidationFailed: resources.instance_create_image_err: '
'Property error: '
'WebServer.Properties.ImageId: Multiple physical '
'resources were found with name (CentOS 5.2).',
six.text_type(error))
@ -436,8 +438,8 @@ class InstancesTest(common.HeatTestCase):
create = scheduler.TaskRunner(instance.create)
error = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(
'StackValidationFailed: Property error : '
'WebServer.Properties.ImageId: 404 (HTTP 404)',
'StackValidationFailed: resources.instance_create_image_err: '
'Property error: WebServer.Properties.ImageId: 404 (HTTP 404)',
six.text_type(error))
self.m.VerifyAll()
@ -711,7 +713,8 @@ class InstancesTest(common.HeatTestCase):
updater = scheduler.TaskRunner(instance.update, update_template)
error = self.assertRaises(exception.ResourceFailure, updater)
self.assertEqual(
"Error: Resizing to 'm1.small' failed, status 'ACTIVE'",
"Error: resources.ud_type_f: "
"Resizing to 'm1.small' failed, status 'ACTIVE'",
six.text_type(error))
self.assertEqual((instance.UPDATE, instance.FAILED), instance.state)
self.m.VerifyAll()

View File

@ -249,8 +249,9 @@ class s3Test(common.HeatTestCase):
rsrc = self.create_resource(t, stack, 'S3Bucket')
deleter = scheduler.TaskRunner(rsrc.delete)
ex = self.assertRaises(exception.ResourceFailure, deleter)
self.assertIn("ResourceActionNotSupported: The bucket "
"you tried to delete is not empty", six.text_type(ex))
self.assertIn("ResourceActionNotSupported: resources.test_resource: "
"The bucket you tried to delete is not empty",
six.text_type(ex))
self.m.VerifyAll()

View File

@ -203,7 +203,7 @@ class VolumeTest(vt_base.BaseVolumeTest):
ex = self.assertRaises(exception.StackValidationFailed,
self.create_volume, self.t, stack, 'DataVolume')
self.assertEqual("Property error : "
self.assertEqual("Property error: "
"Resources.DataVolume.Properties.Tags[0]: "
"Unknown Property Foo", six.text_type(ex))
@ -478,7 +478,8 @@ class VolumeTest(vt_base.BaseVolumeTest):
updater = scheduler.TaskRunner(rsrc.update, after)
ex = self.assertRaises(exception.ResourceFailure, updater)
self.assertIn("NotSupported: Update to properties "
self.assertIn("NotSupported: resources.DataVolume: "
"Update to properties "
"AvailabilityZone, Size, Tags of DataVolume "
"(AWS::EC2::Volume) is not supported",
six.text_type(ex))
@ -668,7 +669,7 @@ class VolumeTest(vt_base.BaseVolumeTest):
self.create_volume,
self.t, stack, 'DataVolume')
self.assertEqual(
"Property error : Resources.DataVolume.Properties.Size: "
"Property error: Resources.DataVolume.Properties.Size: "
"0 is out of range (min: 1, max: None)", six.text_type(error))
def test_volume_attachment_updates_not_supported(self):
@ -698,7 +699,8 @@ class VolumeTest(vt_base.BaseVolumeTest):
update_task = scheduler.TaskRunner(rsrc.update, after)
ex = self.assertRaises(exception.ResourceFailure, update_task)
self.assertIn('NotSupported: Update to properties Device, InstanceId, '
self.assertIn('NotSupported: resources.MountPoint: '
'Update to properties Device, InstanceId, '
'VolumeId of MountPoint (AWS::EC2::VolumeAttachment)',
six.text_type(ex))
self.assertEqual((rsrc.UPDATE, rsrc.FAILED), rsrc.state)

View File

@ -651,7 +651,7 @@ class WaitConditionUpdateTest(common.HeatTestCase):
updater = scheduler.TaskRunner(rsrc.update, update_snippet)
ex = self.assertRaises(exception.ResourceFailure,
updater)
self.assertEqual("WaitConditionTimeout: 0 of 5 received",
six.text_type(ex))
self.assertEqual("WaitConditionTimeout: resources.WaitForTheHandle: "
"0 of 5 received", six.text_type(ex))
self.assertEqual(5, rsrc.properties['Count'])
self.m.VerifyAll()

View File

@ -115,7 +115,8 @@ class FirewallTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.firewall: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -153,7 +154,8 @@ class FirewallTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.firewall: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -243,7 +245,8 @@ class FirewallPolicyTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.firewall_policy: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -281,7 +284,8 @@ class FirewallPolicyTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.firewall_policy: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -395,7 +399,8 @@ class FirewallRuleTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.firewall_rule: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -433,7 +438,8 @@ class FirewallRuleTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.firewall_rule: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()

View File

@ -214,7 +214,8 @@ class HealthMonitorTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.monitor: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -252,7 +253,8 @@ class HealthMonitorTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.monitor: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -456,7 +458,8 @@ class PoolTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'ResourceInError: Went to status ERROR due to "error in pool"',
'ResourceInError: resources.pool: '
'Went to status ERROR due to "error in pool"',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -493,7 +496,8 @@ class PoolTest(common.HeatTestCase):
self.m.ReplayAll()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual('ResourceUnknownStatus: Pool creation failed due to '
self.assertEqual('ResourceUnknownStatus: resources.pool: '
'Pool creation failed due to '
'vip - Unknown status SOMETHING due to "Unknown"',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
@ -522,7 +526,8 @@ class PoolTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.pool: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -714,7 +719,8 @@ class PoolTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.pool: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -731,7 +737,8 @@ class PoolTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.pool: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()

View File

@ -96,7 +96,8 @@ class MeteringLabelTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.label: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -134,7 +135,8 @@ class MeteringLabelTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.label: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -210,7 +212,8 @@ class MeteringRuleTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.rule: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -248,7 +251,8 @@ class MeteringRuleTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.rule: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()

View File

@ -506,7 +506,8 @@ class NeutronNetworkGatewayTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.network_gateway: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.assertIsNone(scheduler.TaskRunner(rsrc.delete)())

View File

@ -194,7 +194,8 @@ class VPNServiceTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.vpnservice: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -229,7 +230,8 @@ class VPNServiceTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.vpnservice: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -340,7 +342,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.ipsec_site_connection: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -375,7 +378,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.ipsec_site_connection: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -485,7 +489,8 @@ class IKEPolicyTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.ikepolicy: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -520,7 +525,8 @@ class IKEPolicyTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.ikepolicy: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -625,7 +631,8 @@ class IPsecPolicyTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.ipsecpolicy: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
@ -660,7 +667,8 @@ class IPsecPolicyTest(common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual(
'NeutronClientException: An unknown exception occurred.',
'NeutronClientException: resources.ipsecpolicy: '
'An unknown exception occurred.',
six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()

View File

@ -104,7 +104,7 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
self.create_volume,
self.t, stack, 'volume')
self.assertEqual(
"Property error : resources.volume.properties.size: "
"Property error: resources.volume.properties.size: "
"0 is out of range (min: 1, max: None)", six.text_type(error))
def test_cinder_create(self):
@ -323,7 +323,8 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
update_task = scheduler.TaskRunner(rsrc.update, after)
ex = self.assertRaises(exception.ResourceFailure, update_task)
self.assertEqual('NotSupported: Shrinking volume is not supported.',
self.assertEqual('NotSupported: resources.volume: '
'Shrinking volume is not supported.',
six.text_type(ex))
self.assertEqual((rsrc.UPDATE, rsrc.FAILED), rsrc.state)
@ -557,7 +558,8 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
# if the volume api is v1, not support to retype
update_task = scheduler.TaskRunner(rsrc.update, after)
ex = self.assertRaises(exception.ResourceFailure, update_task)
self.assertEqual('NotSupported: Using Cinder API V1, '
self.assertEqual('NotSupported: resources.volume2: '
'Using Cinder API V1, '
'volume_type update is not supported.',
six.text_type(ex))
self.assertEqual((rsrc.UPDATE, rsrc.FAILED), rsrc.state)

View File

@ -368,7 +368,7 @@ class CeilometerAlarmTest(common.HeatTestCase):
error = self.assertRaises(exception.StackValidationFailed,
rsrc.validate)
self.assertEqual(
"Property error : Resources.MEMAlarmHigh.Properties.%s: "
"Property error: Resources.MEMAlarmHigh.Properties.%s: "
"Value '60a' is not an integer" % p, six.text_type(error))
def test_mem_alarm_high_not_integer_parameters(self):
@ -383,7 +383,7 @@ class CeilometerAlarmTest(common.HeatTestCase):
error = self.assertRaises(exception.StackValidationFailed,
rsrc.validate)
self.assertEqual(
"Property error : Resources.MEMAlarmHigh.Properties.%s: "
"Property error: Resources.MEMAlarmHigh.Properties.%s: "
"int() argument must be a string or a number, not "
"'list'" % p, six.text_type(error))
@ -398,7 +398,7 @@ class CeilometerAlarmTest(common.HeatTestCase):
error = self.assertRaises(exception.StackValidationFailed,
rsrc.validate)
self.assertEqual(
"Property error : Resources.MEMAlarmHigh.Properties: "
"Property error: Resources.MEMAlarmHigh.Properties: "
"Property meter_name not assigned",
six.text_type(error))
@ -514,7 +514,7 @@ class CombinationAlarmTest(common.HeatTestCase):
error = self.assertRaises(exception.StackValidationFailed,
rsrc.validate)
self.assertEqual(
"Property error : Resources.CombinAlarm.Properties.alarm_ids: "
"Property error: Resources.CombinAlarm.Properties.alarm_ids: "
"length (0) is out of range (min: 1, max: None)",
six.text_type(error))

View File

@ -550,8 +550,8 @@ class StackCreateTest(common.HeatTestCase):
stack.store()
stack.adopt()
self.assertIsNotNone(stack['WebServer'])
expected = ('Resource ADOPT failed: Exception: Resource ID was not'
' provided.')
expected = ('Resource ADOPT failed: Exception: resources.WebServer: '
'Resource ID was not provided.')
self.assertEqual(expected, stack.status_reason)
self.assertEqual((stack.ADOPT, stack.FAILED), stack.state)

View File

@ -16,6 +16,7 @@
import fixtures
import mock
import six
from heat.common import exception
@ -49,7 +50,7 @@ class TestStackValidationFailed(common.HeatTestCase):
error='Error',
path=['some', 'path'],
message='Some message'),
expected='Error : some.path: Some message',
expected='Error: some.path: Some message',
called_error='Error',
called_path=['some', 'path'],
called_msg='Some message'
@ -67,7 +68,7 @@ class TestStackValidationFailed(common.HeatTestCase):
kwargs=dict(
error='Error',
message='Just no.'),
expected='Error : Just no.',
expected='Error: Just no.',
called_error='Error',
called_path=[],
called_msg='Just no.'
@ -76,7 +77,7 @@ class TestStackValidationFailed(common.HeatTestCase):
kwargs=dict(
error='Error',
path=['we', 'lost', 'our', 'message']),
expected='Error : we.lost.our.message: ',
expected='Error: we.lost.our.message: ',
called_error='Error',
called_path=['we', 'lost', 'our', 'message'],
called_msg=''
@ -127,3 +128,70 @@ class TestStackValidationFailed(common.HeatTestCase):
self.assertEqual(self.called_error, ex.error)
self.assertEqual(self.called_path, ex.path)
self.assertEqual(self.called_msg, ex.error_message)
class TestResourceFailure(common.HeatTestCase):
def test_status_reason_resource(self):
reason = ('Resource CREATE failed: ValueError: resources.oops: '
'Test Resource failed oops')
exc = exception.ResourceFailure(reason, None, action='CREATE')
self.assertEqual('ValueError', exc.error)
self.assertEqual(['resources', 'oops'], exc.path)
self.assertEqual('Test Resource failed oops', exc.error_message)
def test_status_reason_general(self):
reason = ('something strange happened')
exc = exception.ResourceFailure(reason, None, action='CREATE')
self.assertEqual('', exc.error)
self.assertEqual([], exc.path)
self.assertEqual('something strange happened', exc.error_message)
def test_status_reason_general_res(self):
res = mock.Mock()
res.name = 'fred'
res.stack.t.get_section_name.return_value = 'Resources'
reason = ('something strange happened')
exc = exception.ResourceFailure(reason, res, action='CREATE')
self.assertEqual('', exc.error)
self.assertEqual(['Resources', 'fred'], exc.path)
self.assertEqual('something strange happened', exc.error_message)
def test_std_exception(self):
base_exc = ValueError('sorry mom')
exc = exception.ResourceFailure(base_exc, None, action='UPDATE')
self.assertEqual('ValueError', exc.error)
self.assertEqual([], exc.path)
self.assertEqual('sorry mom', exc.error_message)
def test_std_exception_with_resource(self):
base_exc = ValueError('sorry mom')
res = mock.Mock()
res.name = 'fred'
res.stack.t.get_section_name.return_value = 'Resources'
exc = exception.ResourceFailure(base_exc, res, action='UPDATE')
self.assertEqual('ValueError', exc.error)
self.assertEqual(['Resources', 'fred'], exc.path)
self.assertEqual('sorry mom', exc.error_message)
def test_heat_exception(self):
base_exc = ValueError('sorry mom')
heat_exc = exception.ResourceFailure(base_exc, None, action='UPDATE')
exc = exception.ResourceFailure(heat_exc, None, action='UPDATE')
self.assertEqual('ValueError', exc.error)
self.assertEqual([], exc.path)
self.assertEqual('sorry mom', exc.error_message)
def test_nested_exceptions(self):
res = mock.Mock()
res.name = 'frodo'
res.stack.t.get_section_name.return_value = 'Resources'
reason = ('Resource UPDATE failed: ValueError: resources.oops: '
'Test Resource failed oops')
base_exc = exception.ResourceFailure(reason, res, action='UPDATE')
exc = exception.ResourceFailure(base_exc, res, action='UPDATE')
self.assertEqual(['Resources', 'frodo', 'resources', 'oops'], exc.path)
self.assertEqual('ValueError', exc.error)
self.assertEqual('Test Resource failed oops', exc.error_message)

View File

@ -95,7 +95,7 @@ class GlanceImageTest(common.HeatTestCase):
)
image = stack['image']
image.t['Properties']['min_disk'] = -1
error_msg = ('Property error : resources.image.properties.min_disk: '
error_msg = ('Property error: resources.image.properties.min_disk: '
'-1 is out of range (min: 0, max: None)')
self._test_validate(image, error_msg)
@ -108,7 +108,7 @@ class GlanceImageTest(common.HeatTestCase):
)
image = stack['image']
image.t['Properties']['min_ram'] = -1
error_msg = ('Property error : resources.image.properties.min_ram: '
error_msg = ('Property error: resources.image.properties.min_ram: '
'-1 is out of range (min: 0, max: None)')
self._test_validate(image, error_msg)
@ -133,7 +133,7 @@ class GlanceImageTest(common.HeatTestCase):
)
image = stack['image']
image.t['Properties']['disk_format'] = 'incorrect_format'
error_msg = ('Property error : '
error_msg = ('Property error: '
'resources.image.properties.disk_format: '
'"incorrect_format" is not an allowed value '
'[ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, iso]')
@ -160,7 +160,7 @@ class GlanceImageTest(common.HeatTestCase):
)
image = stack['image']
image.t['Properties']['container_format'] = 'incorrect_format'
error_msg = ('Property error : '
error_msg = ('Property error: '
'resources.image.properties.container_format: '
'"incorrect_format" is not an allowed value '
'[ami, ari, aki, bare, ova, ovf]')

View File

@ -114,7 +114,8 @@ class ManilaSecurityServiceTest(common.HeatTestCase):
scheduler.TaskRunner(ss.create))
expected_state = (ss.CREATE, ss.FAILED)
self.assertEqual(expected_state, ss.state)
self.assertIn('Exception: error', six.text_type(exc))
self.assertIn('Exception: resources.security_service: error',
six.text_type(exc))
def test_resource_mapping(self):
mapping = security_service.resource_mapping()

View File

@ -155,8 +155,8 @@ class ManilaShareTest(common.HeatTestCase):
share.client().shares.get.return_value = self.failed_share
exc = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(share.check))
self.assertIn("Error: 'status': expected '['available']'",
six.text_type(exc))
self.assertIn("Error: resources.test_share: 'status': expected "
"'['available']'", six.text_type(exc))
def test_share_update(self):
share = self._create_share("stack_share_update")

View File

@ -250,7 +250,7 @@ class TestMistralWorkflow(common.HeatTestCase):
self.assertEqual([], wf.FnGetAtt('executions'))
def test_direct_workflow_validation_error(self):
error_msg = ("Mistral resource validation error : "
error_msg = ("Mistral resource validation error: "
"workflow.properties.tasks.second_task.requires: "
"task second_task contains property 'requires' "
"in case of direct workflow. Only reverse workflows "
@ -258,7 +258,7 @@ class TestMistralWorkflow(common.HeatTestCase):
self._test_validation_failed(workflow_template_bad, error_msg)
def test_wrong_params_using(self):
error_msg = ("Mistral resource validation error : "
error_msg = ("Mistral resource validation error: "
"workflow.properties.params: 'task_name' is not assigned "
"in 'params' in case of reverse type workflow.")
self._test_validation_failed(workflow_template_bad_reverse, error_msg)
@ -289,7 +289,8 @@ class TestMistralWorkflow(common.HeatTestCase):
scheduler.TaskRunner(wf.create))
expected_state = (wf.CREATE, wf.FAILED)
self.assertEqual(expected_state, wf.state)
self.assertIn('Exception: boom!', six.text_type(exc))
self.assertIn('Exception: resources.workflow: boom!',
six.text_type(exc))
def test_update_replace(self):
wf = self._create_resource('workflow', self.rsrc_defn, self.stack)
@ -386,7 +387,8 @@ class TestMistralWorkflow(common.HeatTestCase):
self.mistral.executions.create.side_effect = Exception('boom!')
err = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(wf.signal, details))
self.assertEqual('Exception: boom!', six.text_type(err))
self.assertEqual('Exception: resources.create_vm: boom!',
six.text_type(err))
def test_signal_wrong_input_and_params_type(self):
tmpl = template_format.parse(workflow_template_full)
@ -399,13 +401,15 @@ class TestMistralWorkflow(common.HeatTestCase):
details = {'input': '3'}
err = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(wf.signal, details))
error_message = ("StackValidationFailed: Signal data error : Input in"
error_message = ("StackValidationFailed: resources.create_vm: "
"Signal data error: Input in"
" signal data must be a map, find a <type 'str'>")
self.assertEqual(error_message, six.text_type(err))
details = {'params': '3'}
err = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(wf.signal, details))
error_message = ("StackValidationFailed: Signal data error : Params "
error_message = ("StackValidationFailed: resources.create_vm: "
"Signal data error: Params "
"must be a map, find a <type 'str'>")
self.assertEqual(error_message, six.text_type(err))
@ -420,8 +424,8 @@ class TestMistralWorkflow(common.HeatTestCase):
details = {'input': {'1': '3'}}
err = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(wf.signal, details))
error_message = ("StackValidationFailed: Signal data error :"
" Unknown input 1")
error_message = ("StackValidationFailed: resources.create_vm: "
"Signal data error: Unknown input 1")
self.assertEqual(error_message, six.text_type(err))
@testtools.skipIf(executions is None,

View File

@ -882,7 +882,7 @@ class PropertyTest(common.HeatTestCase):
p = properties.Property({'Type': 'Map', 'Schema': map_schema})
ex = self.assertRaises(exception.StackValidationFailed,
p.get_value, {'valid': 'fish'}, True)
self.assertEqual('Property error : valid: "fish" is not a '
self.assertEqual('Property error: valid: "fish" is not a '
'valid boolean', six.text_type(ex))
def test_map_schema_missing_data(self):
@ -895,7 +895,7 @@ class PropertyTest(common.HeatTestCase):
p = properties.Property({'Type': 'Map', 'Schema': map_schema})
ex = self.assertRaises(exception.StackValidationFailed,
p.get_value, {}, True)
self.assertEqual('Property error : Property valid not assigned',
self.assertEqual('Property error: Property valid not assigned',
six.text_type(ex))
def test_list_schema_good(self):
@ -914,7 +914,7 @@ class PropertyTest(common.HeatTestCase):
ex = self.assertRaises(exception.StackValidationFailed,
p.get_value,
[{'valid': 'True'}, {'valid': 'fish'}], True)
self.assertEqual('Property error : [1].valid: "fish" is not '
self.assertEqual('Property error: [1].valid: "fish" is not '
'a valid boolean', six.text_type(ex))
def test_list_schema_int_good(self):
@ -927,7 +927,7 @@ class PropertyTest(common.HeatTestCase):
p = properties.Property({'Type': 'List', 'Schema': list_schema})
ex = self.assertRaises(exception.StackValidationFailed,
p.get_value, [42, 'fish'], True)
self.assertEqual("Property error : [1]: Value 'fish' is not "
self.assertEqual("Property error: [1]: Value 'fish' is not "
"an integer", six.text_type(ex))
@ -1539,14 +1539,14 @@ class PropertiesValidationTest(common.HeatTestCase):
schema = {'foo': {'Type': 'String'}}
props = properties.Properties(schema, {'foo': ['foo', 'bar']})
ex = self.assertRaises(exception.StackValidationFailed, props.validate)
self.assertEqual('Property error : foo: Value must be a string',
self.assertEqual('Property error: foo: Value must be a string',
six.text_type(ex))
def test_dict_instead_string(self):
schema = {'foo': {'Type': 'String'}}
props = properties.Properties(schema, {'foo': {'foo': 'bar'}})
ex = self.assertRaises(exception.StackValidationFailed, props.validate)
self.assertEqual('Property error : foo: Value must be a string',
self.assertEqual('Property error: foo: Value must be a string',
six.text_type(ex))
def test_none_string(self):
@ -1713,7 +1713,7 @@ class PropertiesValidationTest(common.HeatTestCase):
props = properties.Properties(schema, invalid_data)
ex = self.assertRaises(exception.StackValidationFailed,
props.validate)
self.assertEqual('Property error : foo[0]: Unknown Property bar',
self.assertEqual('Property error: foo[0]: Unknown Property bar',
six.text_type(ex))
def test_nested_properties_schema_invalid_property_in_map(self):
@ -1732,7 +1732,7 @@ class PropertiesValidationTest(common.HeatTestCase):
props = properties.Properties(schema, invalid_data)
ex = self.assertRaises(exception.StackValidationFailed,
props.validate)
self.assertEqual('Property error : foo.boo: Unknown Property bar',
self.assertEqual('Property error: foo.boo: Unknown Property bar',
six.text_type(ex))
def test_more_nested_properties_schema_invalid_property_in_list(self):
@ -1750,7 +1750,7 @@ class PropertiesValidationTest(common.HeatTestCase):
props = properties.Properties(schema, invalid_data)
ex = self.assertRaises(exception.StackValidationFailed,
props.validate)
self.assertEqual('Property error : foo[0].doo: Unknown Property bar',
self.assertEqual('Property error: foo[0].doo: Unknown Property bar',
six.text_type(ex))
def test_more_nested_properties_schema_invalid_property_in_map(self):
@ -1768,7 +1768,7 @@ class PropertiesValidationTest(common.HeatTestCase):
props = properties.Properties(schema, invalid_data)
ex = self.assertRaises(exception.StackValidationFailed,
props.validate)
self.assertEqual('Property error : foo.boo.doo: Unknown Property bar',
self.assertEqual('Property error: foo.boo.doo: Unknown Property bar',
six.text_type(ex))
def test_schema_to_template_empty_schema(self):

View File

@ -315,7 +315,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
rsrc = self.parent['remote_stack']
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
error_msg = ('ResourceInError: Went to status CREATE_FAILED due to '
error_msg = ('ResourceInError: resources.remote_stack: '
'Went to status CREATE_FAILED due to '
'"Remote stack creation failed"')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
@ -360,7 +361,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
remote_stack_id = rsrc.resource_id
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
error_msg = ('ResourceInError: Went to status DELETE_FAILED due to '
error_msg = ('ResourceInError: resources.remote_stack: '
'Went to status DELETE_FAILED due to '
'"Remote stack deletion failed"')
self.assertIn(error_msg, six.text_type(error))
self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
@ -481,7 +483,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
self.heat.actions.resume = mock.MagicMock()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.check))
error_msg = ('ResourceInError: Went to status CHECK_FAILED due to '
error_msg = ('ResourceInError: resources.remote_stack: '
'Went to status CHECK_FAILED due to '
'"Remote stack check failed"')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.CHECK, rsrc.FAILED), rsrc.state)
@ -513,7 +516,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
self.heat.actions.resume = mock.MagicMock()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.resume))
error_msg = ('ResourceInError: Went to status RESUME_FAILED due to '
error_msg = ('ResourceInError: resources.remote_stack: '
'Went to status RESUME_FAILED due to '
'"Remote stack resume failed"')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.RESUME, rsrc.FAILED), rsrc.state)
@ -525,7 +529,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
rsrc.action = rsrc.SUSPEND
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.resume))
error_msg = 'Error: Cannot resume remote_stack, resource not found'
error_msg = ('Error: resources.remote_stack: '
'Cannot resume remote_stack, resource not found')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.RESUME, rsrc.FAILED), rsrc.state)
@ -553,7 +558,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
self.heat.actions.suspend = mock.MagicMock()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.suspend))
error_msg = ('ResourceInError: Went to status SUSPEND_FAILED due to '
error_msg = ('ResourceInError: resources.remote_stack: '
'Went to status SUSPEND_FAILED due to '
'"Remote stack suspend failed"')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.SUSPEND, rsrc.FAILED), rsrc.state)
@ -567,7 +573,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
self.heat.actions.suspend = mock.MagicMock()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.suspend))
error_msg = 'Error: Cannot suspend remote_stack, resource not found'
error_msg = ('Error: resources.remote_stack: '
'Cannot suspend remote_stack, resource not found')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.SUSPEND, rsrc.FAILED), rsrc.state)
# assert suspend was not called
@ -632,7 +639,8 @@ class RemoteStackTest(tests_common.HeatTestCase):
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.update,
update_snippet))
error_msg = _('ResourceInError: Went to status UPDATE_FAILED due to '
error_msg = _('ResourceInError: resources.remote_stack: '
'Went to status UPDATE_FAILED due to '
'"Remote stack update failed"')
self.assertEqual(error_msg, six.text_type(error))
self.assertEqual((rsrc.UPDATE, rsrc.FAILED), rsrc.state)

View File

@ -148,7 +148,8 @@ class ResourceTest(common.HeatTestCase):
ev = self.patchobject(res, '_add_event')
ex = self.assertRaises(exception.ResourceFailure,
res.signal)
self.assertEqual('Exception: Cannot signal resource during '
self.assertEqual('Exception: resources.res: '
'Cannot signal resource during '
'%s' % action, six.text_type(ex))
ev.assert_called_with(
action, status,
@ -569,7 +570,7 @@ class ResourceTest(common.HeatTestCase):
tmpl = rsrc_defn.ResourceDefinition(rname, 'Foo', {})
res = generic_rsrc.ResourceWithRequiredProps(rname, tmpl, self.stack)
estr = ('Property error : test_resource.Properties: '
estr = ('Property error: test_resource.Properties: '
'Property Foo not assigned')
create = scheduler.TaskRunner(res.create)
err = self.assertRaises(exception.ResourceFailure, create)
@ -582,8 +583,9 @@ class ResourceTest(common.HeatTestCase):
{'Food': 'abc'})
res = generic_rsrc.ResourceWithProps(rname, tmpl, self.stack)
estr = ('StackValidationFailed: Property error : '
'test_resource.Properties: Unknown Property Food')
estr = ('StackValidationFailed: resources.test_resource: '
'Property error: test_resource.Properties: '
'Unknown Property Food')
create = scheduler.TaskRunner(res.create)
err = self.assertRaises(exception.ResourceFailure, create)
self.assertIn(estr, six.text_type(err))
@ -661,7 +663,8 @@ class ResourceTest(common.HeatTestCase):
status_reason='just because'))
self.m.ReplayAll()
estr = ('ResourceInError: Went to status ERROR due to "just because"')
estr = ('ResourceInError: resources.test_resource: '
'Went to status ERROR due to "just because"')
create = scheduler.TaskRunner(res.create)
err = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(estr, six.text_type(err))
@ -1563,7 +1566,7 @@ class ResourceAdoptTest(common.HeatTestCase):
res = self.stack['foo']
adopt = scheduler.TaskRunner(res.adopt, None)
self.assertRaises(exception.ResourceFailure, adopt)
expected = 'Exception: Resource ID was not provided.'
expected = 'Exception: resources.foo: Resource ID was not provided.'
self.assertEqual(expected, res.status_reason)
@ -1775,7 +1778,7 @@ class ResourceDependenciesTest(common.HeatTestCase):
stack = parser.Stack(utils.dummy_context(), 'test', tmpl)
ex = self.assertRaises(exception.StackValidationFailed,
stack.validate)
self.assertIn("Property error : resources.bar.properties.FooInt: "
self.assertIn("Property error: resources.bar.properties.FooInt: "
"Value 'notanint' is not an integer",
six.text_type(ex))

View File

@ -117,7 +117,8 @@ class SaharaClusterTest(common.HeatTestCase):
self.cl_mgr.get.return_value = FakeCluster(status='Error')
create_task = scheduler.TaskRunner(cluster.create)
ex = self.assertRaises(exception.ResourceFailure, create_task)
expected = 'ResourceInError: Went to status Error due to "Unknown"'
expected = ('ResourceInError: resources.super-cluster: '
'Went to status Error due to "Unknown"')
self.assertEqual(expected, six.text_type(ex))
def test_cluster_delete_fails(self):
@ -125,7 +126,7 @@ class SaharaClusterTest(common.HeatTestCase):
self.cl_mgr.delete.side_effect = sahara.sahara_base.APIException()
delete_task = scheduler.TaskRunner(cluster.delete)
ex = self.assertRaises(exception.ResourceFailure, delete_task)
expected = "APIException: None"
expected = "APIException: resources.super-cluster: None"
self.assertEqual(expected, six.text_type(ex))
self.cl_mgr.delete.assert_called_once_with(self.fake_cl.id)
@ -144,7 +145,7 @@ class SaharaClusterTest(common.HeatTestCase):
self.cl_mgr.get.reset_mock()
delete_task = scheduler.TaskRunner(cluster.delete)
ex = self.assertRaises(exception.ResourceFailure, delete_task)
expected = "APIException: None"
expected = "APIException: resources.super-cluster: None"
self.assertEqual(expected, six.text_type(ex))
self.cl_mgr.delete.assert_called_once_with(self.fake_cl.id)
self.assertEqual(2, self.cl_mgr.get.call_count)
@ -157,7 +158,8 @@ class SaharaClusterTest(common.HeatTestCase):
self.cl_mgr.get.reset_mock()
delete_task = scheduler.TaskRunner(cluster.delete)
ex = self.assertRaises(exception.ResourceFailure, delete_task)
expected = 'ResourceInError: Went to status Error due to "Unknown"'
expected = ('ResourceInError: resources.super-cluster: '
'Went to status Error due to "Unknown"')
self.assertEqual(expected, six.text_type(ex))
self.cl_mgr.delete.assert_called_once_with(self.fake_cl.id)
self.assertEqual(2, self.cl_mgr.get.call_count)

View File

@ -146,7 +146,7 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
self.ngt_mgr.delete.side_effect = sahara.sahara_base.APIException()
delete_task = scheduler.TaskRunner(ngt.delete)
ex = self.assertRaises(exception.ResourceFailure, delete_task)
expected = "APIException: None"
expected = "APIException: resources.node-group: None"
self.assertEqual(expected, six.text_type(ex))
self.ngt_mgr.delete.assert_called_once_with(self.fake_ngt.id)
@ -188,7 +188,7 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
self.patchobject(ngt, 'is_using_neutron').return_value = False
ex = self.assertRaises(exception.StackValidationFailed, ngt.validate)
self.assertEqual(u"Property error : "
self.assertEqual(u"Property error: "
u"resources.node-group.properties.flavor: "
u"Error validating value u'm1.large'",
six.text_type(ex))
@ -262,7 +262,7 @@ class SaharaClusterTemplateTest(common.HeatTestCase):
self.ct_mgr.delete.side_effect = sahara.sahara_base.APIException()
delete_task = scheduler.TaskRunner(ct.delete)
ex = self.assertRaises(exception.ResourceFailure, delete_task)
expected = "APIException: None"
expected = "APIException: resources.cluster-template: None"
self.assertEqual(expected, six.text_type(ex))
self.ct_mgr.delete.assert_called_once_with(self.fake_ct.id)

View File

@ -430,7 +430,7 @@ class ServersTest(common.HeatTestCase):
create = scheduler.TaskRunner(server.create)
error = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(
"StackValidationFailed: Property error : "
"StackValidationFailed: resources.WebServer: Property error: "
"WebServer.Properties.image: Error validating value 'Slackware': "
"The Image (Slackware) could not be found.",
six.text_type(error))
@ -455,7 +455,7 @@ class ServersTest(common.HeatTestCase):
create = scheduler.TaskRunner(server.create)
error = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(
'StackValidationFailed: Property error : '
'StackValidationFailed: resources.WebServer: Property error: '
'WebServer.Properties.image: Multiple physical '
'resources were found with name (CentOS 5.2).',
six.text_type(error))
@ -480,7 +480,7 @@ class ServersTest(common.HeatTestCase):
create = scheduler.TaskRunner(server.create)
error = self.assertRaises(exception.ResourceFailure, create)
self.assertEqual(
"StackValidationFailed: Property error : "
"StackValidationFailed: resources.WebServer: Property error: "
"WebServer.Properties.image: Error validating value '1': "
"The Image (1) could not be found.",
six.text_type(error))
@ -1055,7 +1055,7 @@ class ServersTest(common.HeatTestCase):
error = self.assertRaises(exception.StackValidationFailed,
server.validate)
self.assertEqual(
"Property error : Resources.WebServer.Properties.key_name: "
"Property error: Resources.WebServer.Properties.key_name: "
"Error validating value 'test2': The Key (test2) could not "
"be found.", six.text_type(error))
self.m.VerifyAll()
@ -1547,8 +1547,8 @@ class ServersTest(common.HeatTestCase):
updater = scheduler.TaskRunner(server.update, update_template)
error = self.assertRaises(exception.ResourceFailure, updater)
self.assertEqual(
"Error: Resizing to 'm1.small' failed, status 'ACTIVE'",
six.text_type(error))
"Error: resources.srv_update2: Resizing to 'm1.small' failed, "
"status 'ACTIVE'", six.text_type(error))
self.assertEqual((server.UPDATE, server.FAILED), server.state)
self.m.VerifyAll()
@ -1714,7 +1714,8 @@ class ServersTest(common.HeatTestCase):
updater = scheduler.TaskRunner(server.update, update_template)
error = self.assertRaises(exception.ResourceFailure, updater)
self.assertEqual(
"Error: Rebuilding server failed, status 'ERROR'",
"Error: resources.srv_updrbldfail: "
"Rebuilding server failed, status 'ERROR'",
six.text_type(error))
self.assertEqual((server.UPDATE, server.FAILED), server.state)
self.m.VerifyAll()
@ -1758,7 +1759,8 @@ class ServersTest(common.HeatTestCase):
ex = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(server.suspend))
self.assertEqual('Error: Cannot suspend srv_sus1, '
self.assertEqual('Error: resources.srv_sus1: '
'Cannot suspend srv_sus1, '
'resource_id not set',
six.text_type(ex))
self.assertEqual((server.SUSPEND, server.FAILED), server.state)
@ -1779,7 +1781,8 @@ class ServersTest(common.HeatTestCase):
ex = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(server.suspend))
self.assertEqual('NotFound: Failed to find server 1234',
self.assertEqual('NotFound: resources.srv_sus2: '
'Failed to find server 1234',
six.text_type(ex))
self.assertEqual((server.SUSPEND, server.FAILED), server.state)
@ -1881,7 +1884,8 @@ class ServersTest(common.HeatTestCase):
server.state_set(server.SUSPEND, server.COMPLETE)
ex = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(server.resume))
self.assertEqual('Error: Cannot resume srv_susp_norid, '
self.assertEqual('Error: resources.srv_susp_norid: '
'Cannot resume srv_susp_norid, '
'resource_id not set',
six.text_type(ex))
self.assertEqual((server.RESUME, server.FAILED), server.state)
@ -1907,7 +1911,8 @@ class ServersTest(common.HeatTestCase):
ex = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(server.resume))
self.assertEqual('NotFound: Failed to find server 1234',
self.assertEqual('NotFound: resources.srv_res_nf: '
'Failed to find server 1234',
six.text_type(ex))
self.assertEqual((server.RESUME, server.FAILED), server.state)
@ -3226,7 +3231,8 @@ class ServersTest(common.HeatTestCase):
# update
updater = scheduler.TaskRunner(server.update, update_template)
err = self.assertRaises(exception.ResourceFailure, updater)
self.assertEqual('StackValidationFailed: Property error : '
self.assertEqual('StackValidationFailed: resources.my_server: '
'Property error: '
'WebServer.Properties.image: The Image '
'(Update Image) could not be found.',
six.text_type(err))

View File

@ -598,7 +598,8 @@ class StackTest(common.HeatTestCase):
self.assertEqual((self.stack.SUSPEND, self.stack.FAILED),
self.stack.state)
self.assertEqual('Resource SUSPEND failed: Exception: foo',
self.assertEqual('Resource SUSPEND failed: Exception: '
'resources.AResource: foo',
self.stack.status_reason)
self.m.VerifyAll()
@ -626,7 +627,8 @@ class StackTest(common.HeatTestCase):
self.assertEqual((self.stack.RESUME, self.stack.FAILED),
self.stack.state)
self.assertEqual('Resource RESUME failed: Exception: foo',
self.assertEqual('Resource RESUME failed: Exception: '
'resources.AResource: foo',
self.stack.status_reason)
self.m.VerifyAll()
@ -795,8 +797,8 @@ class StackTest(common.HeatTestCase):
self.stack.adopt()
self.assertEqual((self.stack.ADOPT, self.stack.FAILED),
self.stack.state)
expected = ('Resource ADOPT failed: Exception: Resource ID was not'
' provided.')
expected = ('Resource ADOPT failed: Exception: resources.foo: '
'Resource ID was not provided.')
self.assertEqual(expected, self.stack.status_reason)
def test_adopt_stack_rollback(self):
@ -1562,7 +1564,7 @@ class StackTest(common.HeatTestCase):
ex = self.assertRaises(exception.StackValidationFailed,
self.stack.validate)
self.assertEqual('Output validation error : '
self.assertEqual('Output validation error: '
'Outputs.Resource_attr.Value: '
'The Referenced Attribute '
'(AResource Bar) is incorrect.',
@ -1736,7 +1738,7 @@ class StackTest(common.HeatTestCase):
ex = self.assertRaises(exception.StackValidationFailed,
self.stack.validate)
self.assertEqual('Output validation error : '
self.assertEqual('Output validation error: '
'outputs.resource_attr.value: '
'The Referenced Attribute '
'(AResource Bar) is incorrect.',

View File

@ -417,7 +417,8 @@ class StackTest(common.HeatTestCase):
mock_rd.assert_called_once()
self.assertEqual((self.stack.DELETE, self.stack.FAILED),
self.stack.state)
self.assertEqual('Resource DELETE failed: Exception: foo',
self.assertEqual('Resource DELETE failed: Exception: '
'resources.AResource: foo',
self.stack.status_reason)
def test_delete_stack_with_resource_log_is_clear(self):

View File

@ -373,7 +373,7 @@ class StackResourceTest(StackResourceBaseTest):
stack = parser.Stack(utils.dummy_context(), stack_name,
templatem.Template(tmpl, files=files))
rsrc = stack['volume_server']
raise_exc_msg = ('Failed to validate : resources.volume_server: '
raise_exc_msg = ('Failed to validate: resources.volume_server: '
'The specified reference "instance" '
'(in volume_attachment.Properties.instance_uuid) '
'is incorrect.')
@ -708,6 +708,7 @@ class StackResourceCheckCompleteTest(StackResourceBaseTest):
def setUp(self):
super(StackResourceCheckCompleteTest, self).setUp()
self.nested = mock.MagicMock()
self.nested.name = 'nested-stack'
self.parent_resource.nested = mock.MagicMock(return_value=self.nested)
self.parent_resource._nested = self.nested
setattr(self.nested, self.action.upper(), self.action.upper())
@ -732,10 +733,17 @@ class StackResourceCheckCompleteTest(StackResourceBaseTest):
done but the nested stack is not in (<action>,COMPLETE) state
"""
self.nested.status = 'FAILED'
self.nested.status_reason = 'broken on purpose'
reason = ('Resource %s failed: ValueError: '
'resources.%s: broken on purpose' % (
self.action.upper(),
'child_res'))
exp_path = 'resources.test.resources.child_res'
exp = 'ValueError: %s: broken on purpose' % exp_path
self.nested.status_reason = reason
complete = getattr(self.parent_resource,
'check_%s_complete' % self.action)
self.assertRaises(resource.ResourceUnknownStatus, complete, None)
exc = self.assertRaises(exception.ResourceFailure, complete, None)
self.assertEqual(exp, six.text_type(exc))
self.parent_resource.nested.assert_called_once_with(
show_deleted=self.show_deleted, force_reload=True)

View File

@ -283,7 +283,7 @@ class swiftTest(common.HeatTestCase):
rsrc = self.create_resource(t, stack, 'SwiftContainer')
deleter = scheduler.TaskRunner(rsrc.delete)
ex = self.assertRaises(exception.ResourceFailure, deleter)
self.assertIn('ResourceActionNotSupported: '
self.assertIn('ResourceActionNotSupported: resources.test_resource: '
'Deleting non-empty container',
six.text_type(ex))

View File

@ -202,7 +202,9 @@ class SwiftSignalHandleTest(common.HeatTestCase):
rsrc = st.resources['test_wait_condition_handle']
exc = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual('ClientException: Overlimit: 413', six.text_type(exc))
self.assertEqual('ClientException: '
'resources.test_wait_condition_handle: '
'Overlimit: 413', six.text_type(exc))
@mock.patch.object(swift.SwiftClientPlugin, '_create')
@mock.patch.object(resource.Resource, 'physical_resource_name')
@ -231,7 +233,9 @@ class SwiftSignalHandleTest(common.HeatTestCase):
rsrc = st.resources['test_wait_condition_handle']
exc = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.delete))
self.assertEqual('ClientException: Overlimit: 413', six.text_type(exc))
self.assertEqual('ClientException: '
'resources.test_wait_condition_handle: '
'Overlimit: 413', six.text_type(exc))
@mock.patch.object(swift.SwiftClientPlugin, '_create')
@mock.patch.object(resource.Resource, 'physical_resource_name')
@ -386,11 +390,13 @@ class SwiftSignalTest(common.HeatTestCase):
self.addCleanup(timeutils.clear_time_override)
st.create()
self.assertIn("Resource CREATE failed: SwiftSignalTimeout",
self.assertIn("SwiftSignalTimeout: resources.test_wait_condition: "
"1 of 2 received - Signal 1 received",
st.status_reason)
wc = st['test_wait_condition']
self.assertEqual("SwiftSignalTimeout: 1 of 2 received - Signal 1 "
"received", wc.status_reason)
self.assertEqual("SwiftSignalTimeout: resources.test_wait_condition: "
"1 of 2 received - Signal 1 received",
wc.status_reason)
@mock.patch.object(swift.SwiftClientPlugin, '_create')
@mock.patch.object(resource.Resource, 'physical_resource_name')
@ -448,7 +454,8 @@ class SwiftSignalTest(common.HeatTestCase):
st.create()
self.assertEqual(('CREATE', 'FAILED'), st.state)
wc = st['test_wait_condition']
self.assertEqual("SwiftSignalFailure: foo;bar", wc.status_reason)
self.assertEqual("SwiftSignalFailure: resources.test_wait_condition: "
"foo;bar", wc.status_reason)
@mock.patch.object(swift.SwiftClientPlugin, '_create')
@mock.patch.object(resource.Resource, 'physical_resource_name')
@ -766,7 +773,8 @@ class SwiftSignalTest(common.HeatTestCase):
st.create()
self.assertEqual(('CREATE', 'FAILED'), st.state)
wc = st['test_wait_condition']
self.assertEqual('Error: Failed to parse JSON data: {"status": '
self.assertEqual('Error: resources.test_wait_condition: '
'Failed to parse JSON data: {"status": '
'"SUCCESS"', wc.status_reason)
@mock.patch.object(swift.SwiftClientPlugin, '_create')
@ -791,7 +799,8 @@ class SwiftSignalTest(common.HeatTestCase):
st.create()
self.assertEqual(('CREATE', 'FAILED'), st.state)
wc = st['test_wait_condition']
self.assertEqual('Error: Unknown status: BOO', wc.status_reason)
self.assertEqual('Error: resources.test_wait_condition: '
'Unknown status: BOO', wc.status_reason)
@mock.patch.object(swift.SwiftClientPlugin, '_create')
@mock.patch.object(resource.Resource, 'physical_resource_name')

View File

@ -160,7 +160,7 @@ class TroveClusterTest(common.HeatTestCase):
self.rsrc_defn['Properties']['instances'][0]['flavor'] = 'm1.small'
tc = trove_cluster.TroveCluster('cluster', self.rsrc_defn, self.stack)
ex = self.assertRaises(exception.StackValidationFailed, tc.validate)
error_msg = ("Property error : "
error_msg = ("Property error: "
"resources.cluster.properties.instances[0].flavor: "
"Error validating value 'm1.small': "
"The Flavor ID (m1.small) could not be found.")

View File

@ -1073,7 +1073,7 @@ class validateTest(common.HeatTestCase):
t = template_format.parse(test_template_invalid_property)
engine = service.EngineService('a', 't')
res = dict(engine.validate_template(None, t, {}))
self.assertEqual({'Error': 'Property error : WikiDatabase.Properties: '
self.assertEqual({'Error': 'Property error: WikiDatabase.Properties: '
'Unknown Property UnknownProperty'}, res)
def test_invalid_resources(self):
@ -1123,7 +1123,7 @@ class validateTest(common.HeatTestCase):
engine = service.EngineService('a', 't')
res = dict(engine.validate_template(None, t, {}))
self.assertEqual(
{'Error': 'Property error : WikiDatabase.Properties: '
{'Error': 'Property error: WikiDatabase.Properties: '
'Property SourceDestCheck not implemented yet'},
res)
@ -1407,7 +1407,7 @@ class validateTest(common.HeatTestCase):
exc = self.assertRaises(exception.StackValidationFailed,
stack.validate)
self.assertEqual(_('Parameter Groups error : '
self.assertEqual(_('Parameter Groups error: '
'parameter_groups.Database '
'Group: The InstanceType parameter must be '
'assigned to one parameter group only.'),
@ -1425,7 +1425,7 @@ class validateTest(common.HeatTestCase):
exc = self.assertRaises(exception.StackValidationFailed,
stack.validate)
self.assertEqual(_('Parameter Groups error : '
self.assertEqual(_('Parameter Groups error: '
'parameter_groups.Database Group: The grouped '
'parameter SomethingNotHere does not '
'reference a valid parameter.'),
@ -1438,7 +1438,7 @@ class validateTest(common.HeatTestCase):
exc = self.assertRaises(exception.StackValidationFailed,
stack.validate)
self.assertEqual(_('Parameter Groups error : parameter_groups.Server '
self.assertEqual(_('Parameter Groups error: parameter_groups.Server '
'Group: The parameters must be provided for each '
'parameter group.'), six.text_type(exc))
@ -1449,7 +1449,7 @@ class validateTest(common.HeatTestCase):
exc = self.assertRaises(exception.StackValidationFailed,
stack.validate)
self.assertEqual(_('Parameter Groups error : parameter_groups: '
self.assertEqual(_('Parameter Groups error: parameter_groups: '
'The parameter_groups should be '
'a list.'), six.text_type(exc))
@ -1460,7 +1460,7 @@ class validateTest(common.HeatTestCase):
exc = self.assertRaises(exception.StackValidationFailed,
stack.validate)
self.assertEqual(_('Parameter Groups error : '
self.assertEqual(_('Parameter Groups error: '
'parameter_groups.Server Group: '
'The parameters of parameter group should be '
'a list.'), six.text_type(exc))

View File

@ -137,7 +137,8 @@ class ZaqarMessageQueueTest(common.HeatTestCase):
err = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(queue.create))
self.assertEqual("Error: Message queue myqueue already exists.",
self.assertEqual("Error: resources.MyQueue2: "
"Message queue myqueue already exists.",
six.text_type(err))
self.m.VerifyAll()
@ -164,7 +165,8 @@ class ZaqarMessageQueueTest(common.HeatTestCase):
err = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(queue.create))
self.assertEqual("Error: Message queue myqueue creation failed.",
self.assertEqual("Error: resources.MyQueue2: "
"Message queue myqueue creation failed.",
six.text_type(err))
self.m.VerifyAll()

View File

@ -100,7 +100,7 @@ class TestResource(resource.Resource):
# emulate failure
if fail_prop:
raise Exception("Test Resource failed %s", self.name)
raise ValueError("Test Resource failed %s" % self.name)
def handle_update(self, json_snippet=None, tmpl_diff=None, prop_diff=None):
value = prop_diff.get(self.VALUE)

View File

@ -648,3 +648,39 @@ Outputs:
self.client.actions.check(stack_id=stack_identifier)
self._wait_for_stack_status(stack_identifier, 'CHECK_COMPLETE')
class TemplateResourceErrorMessageTest(test.HeatIntegrationTest):
"""Prove that nested stack errors don't suck."""
template = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
victim:
Type: fail.yaml
'''
nested_templ = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
oops:
Type: OS::Heat::TestResource
Properties:
fail: true
wait_secs: 2
'''
def setUp(self):
super(TemplateResourceErrorMessageTest, self).setUp()
self.client = self.orchestration_client
def test_fail(self):
stack_identifier = self.stack_create(
template=self.template,
files={'fail.yaml': self.nested_templ},
expected_status='CREATE_FAILED')
stack = self.client.stacks.get(stack_identifier)
exp_path = 'resources.victim.resources.oops'
exp_msg = 'Test Resource failed oops'
exp = 'Resource CREATE failed: ValueError: %s: %s' % (exp_path,
exp_msg)
self.assertEqual(exp, stack.stack_status_reason)