blob: 1634192125097692196da50e2287003408bbae51 [file] [log] [blame]
Rabi Mishra87be9b42016-02-15 14:15:50 +05301# 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.functional import functional_base
14
15test_template = {
16 'heat_template_version': '2013-05-23',
17 'description': 'Test template to create one instance.',
18 'resources': {
19 'bar': {
20 'type': 'OS::Heat::TestResource',
21 'properties': {
22 'value': '1234',
23 'update_replace': False,
24 }
25 }
26 }
27}
28
29env_both_restrict = {u'resource_registry': {
30 u'resources': {
31 'bar': {'restricted_actions': ['update', 'replace']}
32 }
33}
34}
35
36env_replace_restrict = {u'resource_registry': {
37 u'resources': {
38 '*ar': {'restricted_actions': 'replace'}
39 }
40}
41}
42
43reason_update_restrict = 'update is restricted for resource.'
44reason_replace_restrict = 'replace is restricted for resource.'
45
46
47class UpdateRestrictedStackTest(functional_base.FunctionalTestsBase):
48
49 def _check_for_restriction_reason(self, events,
50 reason, num_expected=1):
51 matched = [e for e in events
52 if e.resource_status_reason == reason]
53 return len(matched) == num_expected
54
55 def test_update(self):
56 stack_identifier = self.stack_create(template=test_template)
57
58 update_template = test_template.copy()
59 props = update_template['resources']['bar']['properties']
60 props['value'] = '4567'
61
62 # check update fails - with 'both' restricted
63 self.update_stack(stack_identifier, update_template,
64 env_both_restrict,
65 expected_status='UPDATE_FAILED')
66
67 self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
68 'CREATE_COMPLETE'))
69 resource_events = self.client.events.list(stack_identifier, 'bar')
70 self.assertTrue(
71 self._check_for_restriction_reason(resource_events,
72 reason_update_restrict))
73
74 # check update succeeds - with only 'replace' restricted
75 self.update_stack(stack_identifier, update_template,
76 env_replace_restrict,
77 expected_status='UPDATE_COMPLETE')
78
79 self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
80 'UPDATE_COMPLETE'))
81 resource_events = self.client.events.list(stack_identifier, 'bar')
82 self.assertFalse(
83 self._check_for_restriction_reason(resource_events,
84 reason_update_restrict, 2))
85 self.assertTrue(
86 self._check_for_restriction_reason(resource_events,
87 reason_replace_restrict, 0))
88
89 def test_replace(self):
90 stack_identifier = self.stack_create(template=test_template)
91
92 update_template = test_template.copy()
93 props = update_template['resources']['bar']['properties']
94 props['update_replace'] = True
95
96 # check replace fails - with 'both' restricted
97 self.update_stack(stack_identifier, update_template,
rabi1305de92016-06-13 12:04:10 +053098 env_both_restrict,
Rabi Mishra87be9b42016-02-15 14:15:50 +053099 expected_status='UPDATE_FAILED')
100
101 self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
102 'CREATE_COMPLETE'))
103 resource_events = self.client.events.list(stack_identifier, 'bar')
104 self.assertTrue(
105 self._check_for_restriction_reason(resource_events,
106 reason_replace_restrict))
107
108 # check replace fails - with only 'replace' restricted
109 self.update_stack(stack_identifier, update_template,
110 env_replace_restrict,
111 expected_status='UPDATE_FAILED')
112
113 self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
114 'CREATE_COMPLETE'))
115 resource_events = self.client.events.list(stack_identifier, 'bar')
116 self.assertTrue(
117 self._check_for_restriction_reason(resource_events,
118 reason_replace_restrict, 2))
119 self.assertTrue(
120 self._check_for_restriction_reason(resource_events,
121 reason_update_restrict, 0))
122
123 def test_update_type_changed(self):
124 stack_identifier = self.stack_create(template=test_template)
125
126 update_template = test_template.copy()
127 rsrc = update_template['resources']['bar']
128 rsrc['type'] = 'OS::Heat::None'
129
130 # check replace fails - with 'both' restricted
131 self.update_stack(stack_identifier, update_template,
132 env_both_restrict,
133 expected_status='UPDATE_FAILED')
134
135 self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
136 'CREATE_COMPLETE'))
137 resource_events = self.client.events.list(stack_identifier, 'bar')
138 self.assertTrue(
139 self._check_for_restriction_reason(resource_events,
140 reason_replace_restrict))
141
142 # check replace fails - with only 'replace' restricted
143 self.update_stack(stack_identifier, update_template,
144 env_replace_restrict,
145 expected_status='UPDATE_FAILED')
146
147 self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
148 'CREATE_COMPLETE'))
149 resource_events = self.client.events.list(stack_identifier, 'bar')
150 self.assertTrue(
151 self._check_for_restriction_reason(resource_events,
152 reason_replace_restrict, 2))
153 self.assertTrue(
154 self._check_for_restriction_reason(resource_events,
155 reason_update_restrict, 0))