blob: 19da01bc240012add7f435f837f5ae6cf02d189e [file] [log] [blame]
Angus Salkeldcecb8ed2015-08-05 13:19:45 +10001# 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
13from heat_integrationtests.common import test
14from heatclient import exc
15import six
16
17
18class StackPreviewTest(test.HeatIntegrationTest):
19 template = '''
20heat_template_version: 2015-04-30
21parameters:
22 incomming:
23 type: string
24resources:
25 one:
26 type: OS::Heat::TestResource
27 properties:
28 value: fred
29 two:
30 type: OS::Heat::TestResource
31 properties:
32 value: {get_param: incomming}
33 depends_on: one
34outputs:
35 main_out:
36 value: {get_attr: [two, output]}
37 '''
38 env = '''
39parameters:
40 incomming: abc
41 '''
42
43 def setUp(self):
44 super(StackPreviewTest, self).setUp()
45 self.client = self.orchestration_client
46 self.project_id = self.identity_client.auth_ref.project_id
47
48 def _assert_resource(self, res, stack_name):
49 self.assertEqual(stack_name, res['stack_name'])
50 self.assertEqual('INIT', res['resource_action'])
51 self.assertEqual('COMPLETE', res['resource_status'])
52 for field in ('resource_status_reason', 'physical_resource_id',
53 'description'):
54 self.assertIn(field, res)
55 self.assertEqual('', res[field])
huangtianhuacce999a2015-08-03 16:13:25 +080056 # 'creation_time' and 'updated_time' are None when preview
Angus Salkeldcecb8ed2015-08-05 13:19:45 +100057 for field in ('creation_time', 'updated_time'):
58 self.assertIn(field, res)
huangtianhuacce999a2015-08-03 16:13:25 +080059 self.assertIsNone(res[field])
Angus Salkeldcecb8ed2015-08-05 13:19:45 +100060 self.assertIn('output', res['attributes'])
61
62 # resource_identity
63 self.assertEqual(stack_name,
64 res['resource_identity']['stack_name'])
65 self.assertEqual('None', res['resource_identity']['stack_id'])
66 self.assertEqual(self.project_id,
67 res['resource_identity']['tenant'])
68 self.assertEqual('/resources/%s' % res['resource_name'],
69 res['resource_identity']['path'])
70 # stack_identity
71 self.assertEqual(stack_name,
72 res['stack_identity']['stack_name'])
73 self.assertEqual('None', res['stack_identity']['stack_id'])
74 self.assertEqual(self.project_id,
75 res['stack_identity']['tenant'])
76 self.assertEqual('', res['stack_identity']['path'])
77
78 def _assert_results(self, result, stack_name):
79 # global stuff.
80 self.assertEqual(stack_name, result['stack_name'])
81 self.assertTrue(result['disable_rollback'])
82 self.assertEqual('None', result['id'])
83 self.assertIsNone(result['parent'])
84 self.assertEqual('No description', result['template_description'])
85
86 # parameters
87 self.assertEqual('None', result['parameters']['OS::stack_id'])
88 self.assertEqual(stack_name, result['parameters']['OS::stack_name'])
89 self.assertEqual('abc', result['parameters']['incomming'])
90
91 def test_basic_pass(self):
92 stack_name = self._stack_rand_name()
93 result = self.client.stacks.preview(
94 template=self.template,
95 stack_name=stack_name,
96 disable_rollback=True,
97 environment=self.env).to_dict()
98
99 self._assert_results(result, stack_name)
100 for res in result['resources']:
101 self._assert_resource(res, stack_name)
102 self.assertEqual('OS::Heat::TestResource',
103 res['resource_type'])
104
105 # common properties
106 self.assertEqual(False, res['properties']['fail'])
107 self.assertEqual(0, res['properties']['wait_secs'])
108 self.assertEqual(False, res['properties']['update_replace'])
109
110 if res['resource_name'] == 'one':
111 self.assertEqual('fred', res['properties']['value'])
112 self.assertEqual(['two'], res['required_by'])
113 if res['resource_name'] == 'two':
114 self.assertEqual('abc', res['properties']['value'])
115 self.assertEqual([], res['required_by'])
116
117 def test_basic_fail(self):
118 stack_name = self._stack_rand_name()
119
120 # break the template so it fails validation.
121 wont_work = self.template.replace('get_param: incomming',
122 'get_param: missing')
123 excp = self.assertRaises(exc.HTTPBadRequest,
124 self.client.stacks.preview,
125 template=wont_work,
126 stack_name=stack_name,
127 disable_rollback=True,
128 environment=self.env)
129
130 self.assertIn('Property error: : resources.two.properties.value: '
131 ': The Parameter (missing) was not provided.',
132 six.text_type(excp))
133
134 def test_nested_pass(self):
135 """Nested stacks need to recurse down the stacks."""
136 main_template = '''
137heat_template_version: 2015-04-30
138parameters:
139 incomming:
140 type: string
141resources:
142 main:
143 type: nested.yaml
144 properties:
145 value: {get_param: incomming}
146outputs:
147 main_out:
148 value: {get_attr: [main, output]}
149 '''
150 nested_template = '''
151heat_template_version: 2015-04-30
152parameters:
153 value:
154 type: string
155resources:
156 nested:
157 type: OS::Heat::TestResource
158 properties:
159 value: {get_param: value}
160outputs:
161 output:
162 value: {get_attr: [nested, output]}
163'''
164 stack_name = self._stack_rand_name()
165 result = self.client.stacks.preview(
166 disable_rollback=True,
167 stack_name=stack_name,
168 template=main_template,
169 files={'nested.yaml': nested_template},
170 environment=self.env).to_dict()
171
172 self._assert_results(result, stack_name)
173
174 # nested resources return a list of their resources.
175 res = result['resources'][0][0]
176 nested_stack_name = '%s-%s' % (stack_name,
177 res['parent_resource'])
178
179 self._assert_resource(res, nested_stack_name)
180 self.assertEqual('OS::Heat::TestResource',
181 res['resource_type'])
182
183 self.assertEqual(False, res['properties']['fail'])
184 self.assertEqual(0, res['properties']['wait_secs'])
185 self.assertEqual(False, res['properties']['update_replace'])
186
187 self.assertEqual('abc', res['properties']['value'])
188 self.assertEqual([], res['required_by'])