13
13
# under the License.
16
from eventlet.support import greenlets as greenlet
18
17
from heat.common import exception
18
from heat.engine import dependencies
19
19
from heat.engine import parser
20
20
from heat.engine import resource
21
21
from heat.engine import scheduler
22
from heat.engine import template
23
from heat.engine import environment
22
24
from heat.openstack.common import uuidutils
23
25
import heat.db.api as db_api
25
27
from heat.tests import generic_resource as generic_rsrc
26
28
from heat.tests.common import HeatTestCase
27
from heat.tests.utils import dummy_context
28
from heat.tests.utils import setup_dummy_db
29
from heat.tests import utils
31
32
class ResourceTest(HeatTestCase):
33
34
super(ResourceTest, self).setUp()
35
self.stack = parser.Stack(dummy_context(), 'test_stack',
35
utils.setup_dummy_db()
37
resource._register_class('GenericResourceType',
38
generic_rsrc.GenericResource)
40
env = environment.Environment()
41
env.load({u'resource_registry':
42
{u'OS::Test::GenericResource': u'GenericResourceType'}})
44
self.stack = parser.Stack(utils.dummy_context(), 'test_stack',
45
parser.Template({}), env=env,
37
46
stack_id=uuidutils.generate_uuid())
39
resource._register_class('GenericResourceType',
40
generic_rsrc.GenericResource)
42
48
def test_get_class_ok(self):
43
49
cls = resource.get_class('GenericResourceType')
44
50
self.assertEqual(cls, generic_rsrc.GenericResource)
422
457
resume = scheduler.TaskRunner(res.resume)
423
458
self.assertRaises(exception.ResourceFailure, resume)
425
def test_suspend_fail_exit(self):
426
tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
427
res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack)
428
scheduler.TaskRunner(res.create)()
429
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
431
self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_suspend')
432
generic_rsrc.GenericResource.handle_suspend().AndRaise(
433
greenlet.GreenletExit())
436
suspend = scheduler.TaskRunner(res.suspend)
437
self.assertRaises(greenlet.GreenletExit, suspend)
438
self.assertEqual((res.SUSPEND, res.FAILED), res.state)
440
def test_resume_fail_exit(self):
441
tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
442
res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack)
443
scheduler.TaskRunner(res.create)()
444
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
446
self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_resume')
447
generic_rsrc.GenericResource.handle_resume().AndRaise(
448
greenlet.GreenletExit())
451
res.state_set(res.SUSPEND, res.COMPLETE)
453
resume = scheduler.TaskRunner(res.resume)
454
self.assertRaises(greenlet.GreenletExit, resume)
455
self.assertEqual((res.RESUME, res.FAILED), res.state)
457
460
def test_suspend_fail_exception(self):
458
461
tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}}
459
462
res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack)
460
463
scheduler.TaskRunner(res.create)()
461
464
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
463
self.m.StubOutWithMock(generic_rsrc.GenericResource, 'handle_suspend')
464
generic_rsrc.GenericResource.handle_suspend().AndRaise(Exception())
466
self.m.StubOutWithMock(generic_rsrc.ResourceWithProps,
468
generic_rsrc.ResourceWithProps.handle_suspend().AndRaise(Exception())
465
469
self.m.ReplayAll()
467
471
suspend = scheduler.TaskRunner(res.suspend)
570
class ResourceDependenciesTest(HeatTestCase):
572
super(ResourceDependenciesTest, self).setUp()
573
utils.setup_dummy_db()
575
resource._register_class('GenericResourceType',
576
generic_rsrc.GenericResource)
577
resource._register_class('ResourceWithPropsType',
578
generic_rsrc.ResourceWithProps)
580
self.deps = dependencies.Dependencies()
582
def test_no_deps(self):
583
tmpl = template.Template({
585
'foo': {'Type': 'GenericResourceType'},
588
stack = parser.Stack(None, 'test', tmpl)
591
res.add_dependencies(self.deps)
592
graph = self.deps.graph()
594
self.assertIn(res, graph)
597
tmpl = template.Template({
599
'foo': {'Type': 'GenericResourceType'},
601
'Type': 'ResourceWithPropsType',
603
'Foo': {'Ref': 'foo'},
608
stack = parser.Stack(None, 'test', tmpl)
611
res.add_dependencies(self.deps)
612
graph = self.deps.graph()
614
self.assertIn(res, graph)
615
self.assertIn(stack['foo'], graph[res])
617
def test_ref_nested_dict(self):
618
tmpl = template.Template({
620
'foo': {'Type': 'GenericResourceType'},
622
'Type': 'ResourceWithPropsType',
624
'Foo': {'Fn::Base64': {'Ref': 'foo'}},
629
stack = parser.Stack(None, 'test', tmpl)
632
res.add_dependencies(self.deps)
633
graph = self.deps.graph()
635
self.assertIn(res, graph)
636
self.assertIn(stack['foo'], graph[res])
638
def test_ref_nested_deep(self):
639
tmpl = template.Template({
641
'foo': {'Type': 'GenericResourceType'},
643
'Type': 'ResourceWithPropsType',
645
'Foo': {'Fn::Join': [",", ["blarg",
652
stack = parser.Stack(None, 'test', tmpl)
655
res.add_dependencies(self.deps)
656
graph = self.deps.graph()
658
self.assertIn(res, graph)
659
self.assertIn(stack['foo'], graph[res])
661
def test_ref_fail(self):
662
tmpl = template.Template({
664
'foo': {'Type': 'GenericResourceType'},
666
'Type': 'ResourceWithPropsType',
668
'Foo': {'Ref': 'baz'},
673
ex = self.assertRaises(exception.InvalidTemplateReference,
676
self.assertIn('"baz" (in bar.Properties.Foo)', str(ex))
678
def test_getatt(self):
679
tmpl = template.Template({
681
'foo': {'Type': 'GenericResourceType'},
683
'Type': 'ResourceWithPropsType',
685
'Foo': {'Fn::GetAtt': ['foo', 'bar']},
690
stack = parser.Stack(None, 'test', tmpl)
693
res.add_dependencies(self.deps)
694
graph = self.deps.graph()
696
self.assertIn(res, graph)
697
self.assertIn(stack['foo'], graph[res])
699
def test_getatt_nested_dict(self):
700
tmpl = template.Template({
702
'foo': {'Type': 'GenericResourceType'},
704
'Type': 'ResourceWithPropsType',
706
'Foo': {'Fn::Base64': {'Fn::GetAtt': ['foo', 'bar']}},
711
stack = parser.Stack(None, 'test', tmpl)
714
res.add_dependencies(self.deps)
715
graph = self.deps.graph()
717
self.assertIn(res, graph)
718
self.assertIn(stack['foo'], graph[res])
720
def test_getatt_nested_deep(self):
721
tmpl = template.Template({
723
'foo': {'Type': 'GenericResourceType'},
725
'Type': 'ResourceWithPropsType',
727
'Foo': {'Fn::Join': [",", ["blarg",
728
{'Fn::GetAtt': ['foo',
735
stack = parser.Stack(None, 'test', tmpl)
738
res.add_dependencies(self.deps)
739
graph = self.deps.graph()
741
self.assertIn(res, graph)
742
self.assertIn(stack['foo'], graph[res])
744
def test_getatt_fail(self):
745
tmpl = template.Template({
747
'foo': {'Type': 'GenericResourceType'},
749
'Type': 'ResourceWithPropsType',
751
'Foo': {'Fn::GetAtt': ['baz', 'bar']},
756
ex = self.assertRaises(exception.InvalidTemplateReference,
759
self.assertIn('"baz" (in bar.Properties.Foo)', str(ex))
761
def test_getatt_fail_nested_deep(self):
762
tmpl = template.Template({
764
'foo': {'Type': 'GenericResourceType'},
766
'Type': 'ResourceWithPropsType',
768
'Foo': {'Fn::Join': [",", ["blarg",
769
{'Fn::GetAtt': ['foo',
772
{'Fn::GetAtt': ['baz',
778
ex = self.assertRaises(exception.InvalidTemplateReference,
781
self.assertIn('"baz" (in bar.Properties.Foo.Fn::Join[1][3])', str(ex))
783
def test_dependson(self):
784
tmpl = template.Template({
786
'foo': {'Type': 'GenericResourceType'},
788
'Type': 'GenericResourceType',
793
stack = parser.Stack(None, 'test', tmpl)
796
res.add_dependencies(self.deps)
797
graph = self.deps.graph()
799
self.assertIn(res, graph)
800
self.assertIn(stack['foo'], graph[res])
802
def test_dependson_fail(self):
803
tmpl = template.Template({
806
'Type': 'GenericResourceType',
807
'DependsOn': 'wibble',
811
ex = self.assertRaises(exception.InvalidTemplateReference,
814
self.assertIn('"wibble" (in foo)', str(ex))
566
817
class MetadataTest(HeatTestCase):
568
819
super(MetadataTest, self).setUp()