summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/glossary.rst7
-rw-r--r--heat/engine/resource.py14
-rw-r--r--heat/engine/resources/aws/ec2/instance.py14
-rw-r--r--heat/engine/resources/openstack/nova/server.py14
-rw-r--r--heat/tests/api/__init__.py0
-rw-r--r--heat/tests/api/aws/__init__.py0
-rw-r--r--heat/tests/api/aws/test_api_aws.py (renamed from heat/tests/test_api_aws.py)0
-rw-r--r--heat/tests/api/aws/test_api_ec2token.py (renamed from heat/tests/test_api_ec2token.py)0
-rw-r--r--heat/tests/api/cfn/__init__.py0
-rw-r--r--heat/tests/api/cfn/test_api_cfn_v1.py (renamed from heat/tests/test_api_cfn_v1.py)10
-rw-r--r--heat/tests/api/cloudwatch/__init__.py0
-rw-r--r--heat/tests/api/cloudwatch/test_api_cloudwatch.py (renamed from heat/tests/test_api_cloudwatch.py)50
-rw-r--r--heat/tests/api/middleware/__init__.py0
-rw-r--r--heat/tests/api/middleware/test_ssl_middleware.py (renamed from heat/tests/test_ssl_middleware.py)0
-rw-r--r--heat/tests/api/middleware/test_version_negotiation_middleware.py (renamed from heat/tests/test_version_negotiation_middleware.py)0
-rw-r--r--heat/tests/api/openstack/__init__.py0
-rw-r--r--heat/tests/api/openstack/test_api_openstack_v1.py (renamed from heat/tests/test_api_openstack_v1.py)0
-rw-r--r--heat/tests/api/openstack/test_api_openstack_v1_util.py (renamed from heat/tests/test_api_openstack_v1_util.py)0
-rw-r--r--heat/tests/api/openstack/test_api_openstack_v1_views_stacks_view_builder.py (renamed from heat/tests/test_api_openstack_v1_views_stacks_view_builder.py)0
-rw-r--r--heat/tests/api/openstack/test_api_openstack_v1_views_views_common.py (renamed from heat/tests/test_api_openstack_v1_views_views_common.py)0
-rw-r--r--heat/tests/api/test_wsgi.py (renamed from heat/tests/test_wsgi.py)0
-rw-r--r--heat/tests/aws/test_instance.py48
-rw-r--r--heat/tests/manila/test_manila_share.py13
-rw-r--r--heat/tests/nova/test_server.py47
-rw-r--r--heat/tests/test_resource.py38
25 files changed, 164 insertions, 91 deletions
diff --git a/doc/source/glossary.rst b/doc/source/glossary.rst
index d6ec8b1eb..f94735ffd 100644
--- a/doc/source/glossary.rst
+++ b/doc/source/glossary.rst
@@ -76,10 +76,9 @@
Nova Instance metadata
User-provided *key:value* pairs associated with a Compute
- Instance. See `Instance specific data (OpenStack Compute Admin
- Guide)`_.
+ Instance. See `Instance specific data (OpenStack Operations Guide)`_.
- .. _Instance specific data (OpenStack Compute Admin Guide): http://docs.openstack.org/grizzly/openstack-compute/admin/content/instance-data.html#inserting_metadata
+ .. _Instance specific data (OpenStack Operations Guide): http://docs.openstack.org/openstack-ops/content/instances.html#instance_specific_data
OpenStack
Open source software for building private and public clouds.
@@ -169,7 +168,7 @@
configure instances at boot time. See also `User data (OpenStack
End User Guide)`_.
- .. _User data (OpenStack End User Guide): http://docs.openstack.org/user-guide/content/user-data.html#d6e2415
+ .. _User data (OpenStack End User Guide): http://docs.openstack.org/user-guide/cli_provide_user_data_to_instances.html
.. _cloud-init: https://help.ubuntu.com/community/CloudInit
Wait condition
diff --git a/heat/engine/resource.py b/heat/engine/resource.py
index 0fc547a10..a0ca6449e 100644
--- a/heat/engine/resource.py
+++ b/heat/engine/resource.py
@@ -942,7 +942,10 @@ class Resource(object):
action = self.SUSPEND
# Don't try to suspend the resource unless it's in a stable state
- if (self.action == self.DELETE or self.status != self.COMPLETE):
+ # or if the previous suspend failed
+ if (self.action == self.DELETE or
+ (self.action != self.SUSPEND and
+ self.status != self.COMPLETE)):
exc = exception.Error(_('State %s invalid for suspend')
% six.text_type(self.state))
raise exception.ResourceFailure(exc, self, action)
@@ -957,12 +960,15 @@ class Resource(object):
'''
action = self.RESUME
- # Can't resume a resource unless it's SUSPEND_COMPLETE
- if self.state != (self.SUSPEND, self.COMPLETE):
+ # Allow resume a resource if it's SUSPEND_COMPLETE
+ # or RESUME_FAILED or RESUME_COMPLETE. Recommend to check
+ # the real state of physical resource in handle_resume()
+ if self.state not in ((self.SUSPEND, self.COMPLETE),
+ (self.RESUME, self.FAILED),
+ (self.RESUME, self.COMPLETE)):
exc = exception.Error(_('State %s invalid for resume')
% six.text_type(self.state))
raise exception.ResourceFailure(exc, self, action)
-
LOG.info(_LI('resuming %s'), six.text_type(self))
return self._do_action(action)
diff --git a/heat/engine/resources/aws/ec2/instance.py b/heat/engine/resources/aws/ec2/instance.py
index 192e1416a..c0a2719b1 100644
--- a/heat/engine/resources/aws/ec2/instance.py
+++ b/heat/engine/resources/aws/ec2/instance.py
@@ -795,8 +795,11 @@ class Instance(resource.Resource):
else:
raise
else:
- LOG.debug("suspending instance %s" % self.resource_id)
- server.suspend()
+ # if the instance has been suspended successful,
+ # no need to suspend again
+ if self.client_plugin().get_status(server) != 'SUSPENDED':
+ LOG.debug("suspending instance %s" % self.resource_id)
+ server.suspend()
return server.id
def check_suspend_complete(self, server_id):
@@ -834,8 +837,11 @@ class Instance(resource.Resource):
else:
raise
else:
- LOG.debug("resuming instance %s" % self.resource_id)
- server.resume()
+ # if the instance has been resumed successful,
+ # no need to resume again
+ if self.client_plugin().get_status(server) != 'ACTIVE':
+ LOG.debug("resuming instance %s" % self.resource_id)
+ server.resume()
return server.id
def check_resume_complete(self, server_id):
diff --git a/heat/engine/resources/openstack/nova/server.py b/heat/engine/resources/openstack/nova/server.py
index 8f00c7c1a..6b00e0342 100644
--- a/heat/engine/resources/openstack/nova/server.py
+++ b/heat/engine/resources/openstack/nova/server.py
@@ -1405,8 +1405,11 @@ class Server(stack_user.StackUser):
else:
raise
else:
- LOG.debug('suspending server %s' % self.resource_id)
- server.suspend()
+ # if the server has been suspended successful,
+ # no need to suspend again
+ if self.client_plugin().get_status(server) != 'SUSPENDED':
+ LOG.debug('suspending server %s' % self.resource_id)
+ server.suspend()
return server.id
def check_suspend_complete(self, server_id):
@@ -1444,8 +1447,11 @@ class Server(stack_user.StackUser):
else:
raise
else:
- LOG.debug('resuming server %s' % self.resource_id)
- server.resume()
+ # if the server has been resumed successful,
+ # no need to resume again
+ if self.client_plugin().get_status(server) != 'ACTIVE':
+ LOG.debug('resuming server %s' % self.resource_id)
+ server.resume()
return server.id
def check_resume_complete(self, server_id):
diff --git a/heat/tests/api/__init__.py b/heat/tests/api/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/heat/tests/api/__init__.py
diff --git a/heat/tests/api/aws/__init__.py b/heat/tests/api/aws/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/heat/tests/api/aws/__init__.py
diff --git a/heat/tests/test_api_aws.py b/heat/tests/api/aws/test_api_aws.py
index 98d199f4f..98d199f4f 100644
--- a/heat/tests/test_api_aws.py
+++ b/heat/tests/api/aws/test_api_aws.py
diff --git a/heat/tests/test_api_ec2token.py b/heat/tests/api/aws/test_api_ec2token.py
index 006dc1f92..006dc1f92 100644
--- a/heat/tests/test_api_ec2token.py
+++ b/heat/tests/api/aws/test_api_ec2token.py
diff --git a/heat/tests/api/cfn/__init__.py b/heat/tests/api/cfn/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/heat/tests/api/cfn/__init__.py
diff --git a/heat/tests/test_api_cfn_v1.py b/heat/tests/api/cfn/test_api_cfn_v1.py
index d84d27f63..cfb68ccf3 100644
--- a/heat/tests/test_api_cfn_v1.py
+++ b/heat/tests/api/cfn/test_api_cfn_v1.py
@@ -29,7 +29,7 @@ from heat.rpc import client as rpc_client
from heat.tests import common
from heat.tests import utils
-policy_path = os.path.dirname(os.path.realpath(__file__)) + "/policy/"
+policy_path = os.path.dirname(os.path.realpath(__file__)) + "/../../policy/"
class CfnStackControllerTest(common.HeatTestCase):
@@ -41,12 +41,12 @@ class CfnStackControllerTest(common.HeatTestCase):
def setUp(self):
super(CfnStackControllerTest, self).setUp()
- opts = [
+ self.opts = [
cfg.StrOpt('config_dir', default=policy_path),
cfg.StrOpt('config_file', default='foo'),
cfg.StrOpt('project', default='heat'),
]
- cfg.CONF.register_opts(opts)
+ cfg.CONF.register_opts(self.opts)
cfg.CONF.set_default('host', 'host')
self.topic = rpc_api.ENGINE_TOPIC
self.api_version = '1.0'
@@ -62,6 +62,10 @@ class CfnStackControllerTest(common.HeatTestCase):
'deny_stack_user.json')
self.addCleanup(self.m.VerifyAll)
+ def tearDown(self):
+ super(CfnStackControllerTest, self).tearDown()
+ cfg.CONF.unregister_opts(self.opts)
+
def _dummy_GET_request(self, params=None):
# Mangle the params dict into a query string
params = params or {}
diff --git a/heat/tests/api/cloudwatch/__init__.py b/heat/tests/api/cloudwatch/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/heat/tests/api/cloudwatch/__init__.py
diff --git a/heat/tests/test_api_cloudwatch.py b/heat/tests/api/cloudwatch/test_api_cloudwatch.py
index f7e7988cc..8cc85dab7 100644
--- a/heat/tests/test_api_cloudwatch.py
+++ b/heat/tests/api/cloudwatch/test_api_cloudwatch.py
@@ -32,6 +32,33 @@ class WatchControllerTest(common.HeatTestCase):
the endpoint processing API requests after they are routed
'''
+ def setUp(self):
+ super(WatchControllerTest, self).setUp()
+ self.path = os.path.dirname(os.path.realpath(__file__))
+ self.policy_path = self.path + "/../../policy/"
+ self.opts = [
+ cfg.StrOpt('config_dir', default=self.policy_path),
+ cfg.StrOpt('config_file', default='foo'),
+ cfg.StrOpt('project', default='heat'),
+ ]
+ cfg.CONF.register_opts(self.opts)
+ cfg.CONF.set_default('host', 'host')
+ self.topic = rpc_api.ENGINE_TOPIC
+ self.api_version = '1.0'
+
+ # Create WSGI controller instance
+ class DummyConfig(object):
+ bind_port = 8003
+ cfgopts = DummyConfig()
+ self.controller = watches.WatchController(options=cfgopts)
+ self.controller.policy.enforcer.policy_path = (self.policy_path +
+ 'deny_stack_user.json')
+ self.addCleanup(self.m.VerifyAll)
+
+ def tearDown(self):
+ super(WatchControllerTest, self).tearDown()
+ cfg.CONF.unregister_opts(self.opts)
+
def _dummy_GET_request(self, params=None):
# Mangle the params dict into a query string
params = params or {}
@@ -488,26 +515,3 @@ class WatchControllerTest(common.HeatTestCase):
# should raise HeatInvalidParameterValueError
result = self.controller.set_alarm_state(dummy_req)
self.assertIsInstance(result, exception.HeatInvalidParameterValueError)
-
- def setUp(self):
- super(WatchControllerTest, self).setUp()
- self.path = os.path.dirname(os.path.realpath(__file__))
- self.policy_path = self.path + "/policy/"
- opts = [
- cfg.StrOpt('config_dir', default=self.policy_path),
- cfg.StrOpt('config_file', default='foo'),
- cfg.StrOpt('project', default='heat'),
- ]
- cfg.CONF.register_opts(opts)
- cfg.CONF.set_default('host', 'host')
- self.topic = rpc_api.ENGINE_TOPIC
- self.api_version = '1.0'
-
- # Create WSGI controller instance
- class DummyConfig(object):
- bind_port = 8003
- cfgopts = DummyConfig()
- self.controller = watches.WatchController(options=cfgopts)
- self.controller.policy.enforcer.policy_path = (self.policy_path +
- 'deny_stack_user.json')
- self.addCleanup(self.m.VerifyAll)
diff --git a/heat/tests/api/middleware/__init__.py b/heat/tests/api/middleware/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/heat/tests/api/middleware/__init__.py
diff --git a/heat/tests/test_ssl_middleware.py b/heat/tests/api/middleware/test_ssl_middleware.py
index 5700f683b..5700f683b 100644
--- a/heat/tests/test_ssl_middleware.py
+++ b/heat/tests/api/middleware/test_ssl_middleware.py
diff --git a/heat/tests/test_version_negotiation_middleware.py b/heat/tests/api/middleware/test_version_negotiation_middleware.py
index b720d9601..b720d9601 100644
--- a/heat/tests/test_version_negotiation_middleware.py
+++ b/heat/tests/api/middleware/test_version_negotiation_middleware.py
diff --git a/heat/tests/api/openstack/__init__.py b/heat/tests/api/openstack/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/heat/tests/api/openstack/__init__.py
diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/api/openstack/test_api_openstack_v1.py
index 9e68b1063..9e68b1063 100644
--- a/heat/tests/test_api_openstack_v1.py
+++ b/heat/tests/api/openstack/test_api_openstack_v1.py
diff --git a/heat/tests/test_api_openstack_v1_util.py b/heat/tests/api/openstack/test_api_openstack_v1_util.py
index 9c832c317..9c832c317 100644
--- a/heat/tests/test_api_openstack_v1_util.py
+++ b/heat/tests/api/openstack/test_api_openstack_v1_util.py
diff --git a/heat/tests/test_api_openstack_v1_views_stacks_view_builder.py b/heat/tests/api/openstack/test_api_openstack_v1_views_stacks_view_builder.py
index cbf904830..cbf904830 100644
--- a/heat/tests/test_api_openstack_v1_views_stacks_view_builder.py
+++ b/heat/tests/api/openstack/test_api_openstack_v1_views_stacks_view_builder.py
diff --git a/heat/tests/test_api_openstack_v1_views_views_common.py b/heat/tests/api/openstack/test_api_openstack_v1_views_views_common.py
index 981dcc542..981dcc542 100644
--- a/heat/tests/test_api_openstack_v1_views_views_common.py
+++ b/heat/tests/api/openstack/test_api_openstack_v1_views_views_common.py
diff --git a/heat/tests/test_wsgi.py b/heat/tests/api/test_wsgi.py
index c7b32fe36..c7b32fe36 100644
--- a/heat/tests/test_wsgi.py
+++ b/heat/tests/api/test_wsgi.py
diff --git a/heat/tests/aws/test_instance.py b/heat/tests/aws/test_instance.py
index 73cd2b421..bdf7a84eb 100644
--- a/heat/tests/aws/test_instance.py
+++ b/heat/tests/aws/test_instance.py
@@ -1013,16 +1013,14 @@ class InstancesTest(common.HeatTestCase):
scheduler.TaskRunner(instance.create)()
self.assertEqual((instance.CREATE, instance.COMPLETE), instance.state)
- def test_instance_status_suspend(self):
+ def _test_instance_status_suspend(self, name,
+ state=('CREATE', 'COMPLETE')):
return_server = self.fc.servers.list()[1]
- instance = self._create_test_instance(return_server,
- 'in_suspend_wait')
+ instance = self._create_test_instance(return_server, name)
instance.resource_id = '1234'
- self.m.ReplayAll()
+ instance.state_set(state[0], state[1])
- # Override the get_servers_1234 handler status to SUSPENDED, but
- # return the ACTIVE state first (twice, so we sleep)
d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
d2 = copy.deepcopy(d1)
d1['server']['status'] = 'ACTIVE'
@@ -1039,16 +1037,28 @@ class InstancesTest(common.HeatTestCase):
self.m.VerifyAll()
- def test_instance_status_resume(self):
+ def test_instance_suspend_in_create_complete(self):
+ self._test_instance_status_suspend(
+ name='test_suspend_in_create_complete')
+
+ def test_instance_suspend_in_suspend_failed(self):
+ self._test_instance_status_suspend(
+ name='test_suspend_in_suspend_failed',
+ state=('SUSPEND', 'FAILED'))
+
+ def test_server_suspend_in_suspend_complete(self):
+ self._test_instance_status_suspend(
+ name='test_suspend_in_suspend_complete',
+ state=('SUSPEND', 'COMPLETE'))
+
+ def _test_instance_status_resume(self, name,
+ state=('SUSPEND', 'COMPLETE')):
return_server = self.fc.servers.list()[1]
- instance = self._create_test_instance(return_server,
- 'in_resume_wait')
+ instance = self._create_test_instance(return_server, name)
instance.resource_id = '1234'
- self.m.ReplayAll()
+ instance.state_set(state[0], state[1])
- # Override the get_servers_1234 handler status to ACTIVE, but
- # return the SUSPENDED state first (twice, so we sleep)
d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
d2 = copy.deepcopy(d1)
d1['server']['status'] = 'SUSPENDED'
@@ -1067,6 +1077,20 @@ class InstancesTest(common.HeatTestCase):
self.m.VerifyAll()
+ def test_instance_resume_in_suspend_complete(self):
+ self._test_instance_status_resume(
+ name='test_resume_in_suspend_complete')
+
+ def test_instance_resume_in_resume_failed(self):
+ self._test_instance_status_resume(
+ name='test_resume_in_resume_failed',
+ state=('RESUME', 'FAILED'))
+
+ def test_instance_resume_in_resume_complete(self):
+ self._test_instance_status_resume(
+ name='test_resume_in_resume_complete',
+ state=('RESUME', 'COMPLETE'))
+
def test_server_resume_other_exception(self):
return_server = self.fc.servers.list()[1]
instance = self._create_test_instance(return_server,
diff --git a/heat/tests/manila/test_manila_share.py b/heat/tests/manila/test_manila_share.py
index 2a59242eb..ab7d9e264 100644
--- a/heat/tests/manila/test_manila_share.py
+++ b/heat/tests/manila/test_manila_share.py
@@ -18,6 +18,7 @@ import six
from heat.common import exception
from heat.common import template_format
+from heat.engine import resource
from heat.engine.resources.openstack.manila import share as mshare
from heat.engine import rsrc_defn
from heat.engine import scheduler
@@ -113,18 +114,18 @@ class ManilaShareTest(common.HeatTestCase):
def test_share_create_fail(self):
share = self._init_share("stack_share_create_fail")
- share.client().shares.create.return_value = self.fake_share
share.client().shares.get.return_value = self.failed_share
- exc = self.assertRaises(exception.ResourceFailure,
- scheduler.TaskRunner(share.create))
+ exc = self.assertRaises(resource.ResourceInError,
+ share.check_create_complete,
+ self.failed_share)
self.assertIn("Error during creation", six.text_type(exc))
def test_share_create_unknown_status(self):
share = self._init_share("stack_share_create_unknown")
- share.client().shares.create.return_value = self.fake_share
share.client().shares.get.return_value = self.deleting_share
- exc = self.assertRaises(exception.ResourceFailure,
- scheduler.TaskRunner(share.create))
+ exc = self.assertRaises(resource.ResourceUnknownStatus,
+ share.check_create_complete,
+ self.deleting_share)
self.assertIn("Unknown status", six.text_type(exc))
def test_share_delete(self):
diff --git a/heat/tests/nova/test_server.py b/heat/tests/nova/test_server.py
index fa6586c9b..85fea958c 100644
--- a/heat/tests/nova/test_server.py
+++ b/heat/tests/nova/test_server.py
@@ -1905,16 +1905,13 @@ class ServersTest(common.HeatTestCase):
self.m.VerifyAll()
- def test_server_status_suspend(self):
+ def _test_server_status_suspend(self, name, state=('CREATE', 'COMPLETE')):
return_server = self.fc.servers.list()[1]
- server = self._create_test_server(return_server,
- 'srv_susp_w')
+ server = self._create_test_server(return_server, name)
server.resource_id = '1234'
- self.m.ReplayAll()
+ server.state_set(state[0], state[1])
- # Override the get_servers_1234 handler status to SUSPENDED, but
- # return the ACTIVE state first (twice, so we sleep)
d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
d2 = copy.deepcopy(d1)
d1['server']['status'] = 'ACTIVE'
@@ -1931,6 +1928,19 @@ class ServersTest(common.HeatTestCase):
self.m.VerifyAll()
+ def test_server_suspend_in_create_complete(self):
+ self._test_server_status_suspend('test_suspend_in_create_complete')
+
+ def test_server_suspend_in_suspend_failed(self):
+ self._test_server_status_suspend(
+ name='test_suspend_in_suspend_failed',
+ state=('SUSPEND', 'FAILED'))
+
+ def test_server_suspend_in_suspend_complete(self):
+ self._test_server_status_suspend(
+ name='test_suspend_in_suspend_complete',
+ state=('SUSPEND', 'COMPLETE'))
+
def test_server_status_suspend_unknown_status(self):
return_server = self.fc.servers.list()[1]
server = self._create_test_server(return_server,
@@ -1962,16 +1972,13 @@ class ServersTest(common.HeatTestCase):
self.m.VerifyAll()
- def test_server_status_resume(self):
+ def _test_server_status_resume(self, name, state=('SUSPEND', 'COMPLETE')):
return_server = self.fc.servers.list()[1]
- server = self._create_test_server(return_server,
- 'srv_res_w')
+ server = self._create_test_server(return_server, name)
server.resource_id = '1234'
- self.m.ReplayAll()
+ server.state_set(state[0], state[1])
- # Override the get_servers_1234 handler status to ACTIVE, but
- # return the SUSPENDED state first (twice, so we sleep)
d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
d2 = copy.deepcopy(d1)
d1['server']['status'] = 'SUSPENDED'
@@ -1983,13 +1990,25 @@ class ServersTest(common.HeatTestCase):
get().AndReturn((200, d2))
self.m.ReplayAll()
- server.state_set(server.SUSPEND, server.COMPLETE)
-
scheduler.TaskRunner(server.resume)()
self.assertEqual((server.RESUME, server.COMPLETE), server.state)
self.m.VerifyAll()
+ def test_server_resume_in_suspend_complete(self):
+ self._test_server_status_resume(
+ name='test_resume_in_suspend_complete')
+
+ def test_server_resume_in_resume_failed(self):
+ self._test_server_status_resume(
+ name='test_resume_in_resume_failed',
+ state=('RESUME', 'FAILED'))
+
+ def test_server_resume_in_resume_complete(self):
+ self._test_server_status_resume(
+ name='test_resume_in_resume_complete',
+ state=('RESUME', 'COMPLETE'))
+
def test_server_status_resume_no_resource_id(self):
return_server = self.fc.servers.list()[1]
server = self._create_test_server(return_server,
diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py
index 10c2acfd5..592da4220 100644
--- a/heat/tests/test_resource.py
+++ b/heat/tests/test_resource.py
@@ -980,7 +980,7 @@ class ResourceTest(common.HeatTestCase):
scheduler.TaskRunner(res.resume)()
self.assertEqual((res.RESUME, res.COMPLETE), res.state)
- def test_suspend_fail_inprogress(self):
+ def test_suspend_fail_invalid_states(self):
tmpl = rsrc_defn.ResourceDefinition('test_resource',
'GenericResourceType',
{'Foo': 'abc'})
@@ -988,19 +988,19 @@ class ResourceTest(common.HeatTestCase):
scheduler.TaskRunner(res.create)()
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
- res.state_set(res.CREATE, res.IN_PROGRESS)
- suspend = scheduler.TaskRunner(res.suspend)
- self.assertRaises(exception.ResourceFailure, suspend)
-
- res.state_set(res.UPDATE, res.IN_PROGRESS)
- suspend = scheduler.TaskRunner(res.suspend)
- self.assertRaises(exception.ResourceFailure, suspend)
+ invalid_actions = (a for a in res.ACTIONS if a != res.SUSPEND)
+ invalid_status = (s for s in res.STATUSES if s != res.COMPLETE)
+ invalid_states = [s for s in
+ itertools.product(invalid_actions, invalid_status)]
- res.state_set(res.DELETE, res.IN_PROGRESS)
- suspend = scheduler.TaskRunner(res.suspend)
- self.assertRaises(exception.ResourceFailure, suspend)
+ for state in invalid_states:
+ res.state_set(*state)
+ suspend = scheduler.TaskRunner(res.suspend)
+ expected = 'State %s invalid for suspend' % six.text_type(state)
+ exc = self.assertRaises(exception.ResourceFailure, suspend)
+ self.assertIn(expected, six.text_type(exc))
- def test_resume_fail_not_suspend_complete(self):
+ def test_resume_fail_invalid_states(self):
tmpl = rsrc_defn.ResourceDefinition('test_resource',
'GenericResourceType',
{'Foo': 'abc'})
@@ -1008,13 +1008,17 @@ class ResourceTest(common.HeatTestCase):
scheduler.TaskRunner(res.create)()
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
- non_suspended_states = [s for s in
- itertools.product(res.ACTIONS, res.STATUSES)
- if s != (res.SUSPEND, res.COMPLETE)]
- for state in non_suspended_states:
+ invalid_states = [s for s in
+ itertools.product(res.ACTIONS, res.STATUSES)
+ if s not in ((res.SUSPEND, res.COMPLETE),
+ (res.RESUME, res.FAILED),
+ (res.RESUME, res.COMPLETE))]
+ for state in invalid_states:
res.state_set(*state)
resume = scheduler.TaskRunner(res.resume)
- self.assertRaises(exception.ResourceFailure, resume)
+ expected = 'State %s invalid for resume' % six.text_type(state)
+ exc = self.assertRaises(exception.ResourceFailure, resume)
+ self.assertIn(expected, six.text_type(exc))
def test_suspend_fail_exception(self):
tmpl = rsrc_defn.ResourceDefinition('test_resource',