blob: 1b6f961896144baa965c42051106f79dcf27c80b [file] [log] [blame]
tengqmc0fffda2014-12-11 22:32:27 +08001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13import logging
Pavlo Shchelokovskyy60e0ecd2014-12-14 22:17:21 +020014
15from heatclient import exc
tengqmc0fffda2014-12-11 22:32:27 +080016import six
17
18from heat_integrationtests.common import test
tengqmc0fffda2014-12-11 22:32:27 +080019
20LOG = logging.getLogger(__name__)
21
22
23class RemoteStackTest(test.HeatIntegrationTest):
24 template = '''
25heat_template_version: 2013-05-23
26resources:
27 my_stack:
28 type: OS::Heat::Stack
29 properties:
30 context:
31 region_name: RegionOne
32 template:
33 get_file: remote_stack.yaml
34outputs:
35 key:
36 value: {get_attr: [my_stack, outputs]}
37'''
38
39 remote_template = '''
40heat_template_version: 2013-05-23
41resources:
42 random1:
43 type: OS::Heat::RandomString
44outputs:
45 remote_key:
46 value: {get_attr: [random1, value]}
47'''
48
49 def setUp(self):
50 super(RemoteStackTest, self).setUp()
51 self.client = self.orchestration_client
52
53 def test_remote_stack_alone(self):
54 stack_id = self.stack_create(template=self.remote_template)
55 expected_resources = {'random1': 'OS::Heat::RandomString'}
56 self.assertEqual(expected_resources, self.list_resources(stack_id))
57 stack = self.client.stacks.get(stack_id)
58 output_value = self._stack_output(stack, 'remote_key')
59 self.assertEqual(32, len(output_value))
60
61 def test_stack_create(self):
62 files = {'remote_stack.yaml': self.remote_template}
63 stack_id = self.stack_create(files=files)
64
65 expected_resources = {'my_stack': 'OS::Heat::Stack'}
66 self.assertEqual(expected_resources, self.list_resources(stack_id))
67
68 stack = self.client.stacks.get(stack_id)
69 output = self._stack_output(stack, 'key')
70 parent_output_value = output['remote_key']
71 self.assertEqual(32, len(parent_output_value))
72
73 rsrc = self.client.resources.get(stack_id, 'my_stack')
74 remote_id = rsrc.physical_resource_id
75 rstack = self.client.stacks.get(remote_id)
76 self.assertEqual(remote_id, rstack.id)
77 remote_output_value = self._stack_output(rstack, 'remote_key')
78 self.assertEqual(32, len(remote_output_value))
79 self.assertEqual(parent_output_value, remote_output_value)
80
81 remote_resources = {'random1': 'OS::Heat::RandomString'}
82 self.assertEqual(remote_resources, self.list_resources(remote_id))
83
84 def test_stack_create_bad_region(self):
Angus Salkeld4754f4f2015-01-07 16:17:09 +100085 stack_name = self._stack_rand_name()
tengqmc0fffda2014-12-11 22:32:27 +080086 tmpl_bad_region = self.template.replace('RegionOne', 'DARKHOLE')
87 files = {'remote_stack.yaml': self.remote_template}
88 kwargs = {
89 'stack_name': stack_name,
90 'template': tmpl_bad_region,
91 'files': files
92 }
93 ex = self.assertRaises(exc.HTTPBadRequest, self.stack_create, **kwargs)
94
95 error_msg = ('ERROR: Cannot establish connection to Heat endpoint '
96 'at region "DARKHOLE" due to "publicURL endpoint for '
97 'orchestration service in DARKHOLE region not found"')
98 self.assertEqual(error_msg, six.text_type(ex))
99
100 def test_stack_resource_validation_fail(self):
Angus Salkeld4754f4f2015-01-07 16:17:09 +1000101 stack_name = self._stack_rand_name()
tengqmc0fffda2014-12-11 22:32:27 +0800102 tmpl_bad_format = self.remote_template.replace('resources', 'resource')
103 files = {'remote_stack.yaml': tmpl_bad_format}
104 kwargs = {'stack_name': stack_name, 'files': files}
105 ex = self.assertRaises(exc.HTTPBadRequest, self.stack_create, **kwargs)
106
107 error_msg = ('ERROR: Failed validating stack template using Heat '
108 'endpoint at region "RegionOne" due to '
109 '"ERROR: The template section is invalid: resource"')
110 self.assertEqual(error_msg, six.text_type(ex))
111
112 def test_stack_update(self):
113 files = {'remote_stack.yaml': self.remote_template}
114 stack_id = self.stack_create(files=files)
115
116 expected_resources = {'my_stack': 'OS::Heat::Stack'}
117 self.assertEqual(expected_resources, self.list_resources(stack_id))
118
119 rsrc = self.client.resources.get(stack_id, 'my_stack')
120 physical_resource_id = rsrc.physical_resource_id
121 rstack = self.client.stacks.get(physical_resource_id)
122 self.assertEqual(physical_resource_id, rstack.id)
123
124 remote_resources = {'random1': 'OS::Heat::RandomString'}
125 self.assertEqual(remote_resources,
126 self.list_resources(rstack.id))
127 # do an update
128 update_template = self.remote_template.replace('random1', 'random2')
129 files = {'remote_stack.yaml': update_template}
130 self.update_stack(stack_id, self.template, files=files)
131
132 # check if the remote stack is still there with the same ID
133 self.assertEqual(expected_resources, self.list_resources(stack_id))
134 rsrc = self.client.resources.get(stack_id, 'my_stack')
135 physical_resource_id = rsrc.physical_resource_id
136 rstack = self.client.stacks.get(physical_resource_id)
137 self.assertEqual(physical_resource_id, rstack.id)
138
139 remote_resources = {'random2': 'OS::Heat::RandomString'}
140 self.assertEqual(remote_resources,
141 self.list_resources(rstack.id))
142
143 def test_stack_suspend_resume(self):
144 files = {'remote_stack.yaml': self.remote_template}
145 stack_id = self.stack_create(files=files)
146 rsrc = self.client.resources.get(stack_id, 'my_stack')
147 remote_id = rsrc.physical_resource_id
148
149 # suspend stack
150 self.client.actions.suspend(stack_id)
151 self._wait_for_stack_status(stack_id, 'SUSPEND_COMPLETE')
152 rsrc = self.client.stacks.get(remote_id)
153 self.assertEqual('SUSPEND_COMPLETE', rsrc.stack_status)
154
155 # resume stack
156 self.client.actions.resume(stack_id)
157 self._wait_for_stack_status(stack_id, 'RESUME_COMPLETE')
158 rsrc = self.client.stacks.get(remote_id)
159 self.assertEqual('RESUME_COMPLETE', rsrc.stack_status)