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