~ubuntu-branches/ubuntu/saucy/heat/saucy-updates

« back to all changes in this revision

Viewing changes to heat/tests/test_signal.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-08 15:23:59 UTC
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20130808152359-187gmaw0nx1oduxy
Tags: upstream-2013.2~b2.a186.g2b4b248
ImportĀ upstreamĀ versionĀ 2013.2~b2.a186.g2b4b248

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
4
#    not use this file except in compliance with the License. You may obtain
 
5
#    a copy of the License at
 
6
#
 
7
#         http://www.apache.org/licenses/LICENSE-2.0
 
8
#
 
9
#    Unless required by applicable law or agreed to in writing, software
 
10
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
11
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
12
#    License for the specific language governing permissions and limitations
 
13
#    under the License.
 
14
 
 
15
import datetime
 
16
 
 
17
from oslo.config import cfg
 
18
 
 
19
from heat.tests import generic_resource
 
20
from heat.tests import fakes
 
21
from heat.tests.common import HeatTestCase
 
22
from heat.tests import utils
 
23
from heat.tests.utils import reset_dummy_db
 
24
 
 
25
from heat.common import context
 
26
from heat.common import exception
 
27
from heat.common import template_format
 
28
 
 
29
from heat.engine import parser
 
30
from heat.engine import resource
 
31
from heat.engine import signal_responder as sr
 
32
 
 
33
 
 
34
test_template_signal = '''
 
35
{
 
36
  "AWSTemplateFormatVersion" : "2010-09-09",
 
37
  "Description" : "Just a test.",
 
38
  "Parameters" : {},
 
39
  "Resources" : {
 
40
    "signal_handler" : {"Type" : "SignalResourceType"},
 
41
    "resource_X" : {"Type" : "GenericResourceType"}
 
42
  },
 
43
  "Outputs": {
 
44
    "signed_url": {"Fn::GetAtt": ["signal_handler", "AlarmUrl"]}
 
45
  }
 
46
}
 
47
'''
 
48
 
 
49
 
 
50
class SignalTest(HeatTestCase):
 
51
 
 
52
    def setUp(self):
 
53
        super(SignalTest, self).setUp()
 
54
        utils.setup_dummy_db()
 
55
 
 
56
        resource._register_class('SignalResourceType',
 
57
                                 generic_resource.SignalResource)
 
58
        resource._register_class('GenericResourceType',
 
59
                                 generic_resource.GenericResource)
 
60
 
 
61
        cfg.CONF.set_default('heat_waitcondition_server_url',
 
62
                             'http://127.0.0.1:8000/v1/waitcondition')
 
63
 
 
64
        self.stack_id = 'STACKABCD1234'
 
65
        self.fc = fakes.FakeKeystoneClient()
 
66
 
 
67
    def tearDown(self):
 
68
        super(SignalTest, self).tearDown()
 
69
        reset_dummy_db()
 
70
 
 
71
    # Note tests creating a stack should be decorated with @stack_delete_after
 
72
    # to ensure the stack is properly cleaned up
 
73
    def create_stack(self, stack_name='test_stack', stub=True):
 
74
        temp = template_format.parse(test_template_signal)
 
75
        template = parser.Template(temp)
 
76
        ctx = context.get_admin_context()
 
77
        ctx.tenant_id = 'test_tenant'
 
78
        stack = parser.Stack(ctx, stack_name, template,
 
79
                             disable_rollback=True)
 
80
 
 
81
        # Stub out the stack ID so we have a known value
 
82
        with utils.UUIDStub(self.stack_id):
 
83
            stack.store()
 
84
 
 
85
        if stub:
 
86
            self.m.StubOutWithMock(sr.SignalResponder, 'keystone')
 
87
            sr.SignalResponder.keystone().MultipleTimes().AndReturn(
 
88
                self.fc)
 
89
        return stack
 
90
 
 
91
    @utils.stack_delete_after
 
92
    def test_FnGetAtt_Alarm_Url(self):
 
93
        self.stack = self.create_stack()
 
94
 
 
95
        self.m.ReplayAll()
 
96
        self.stack.create()
 
97
 
 
98
        rsrc = self.stack.resources['signal_handler']
 
99
        created_time = datetime.datetime(2012, 11, 29, 13, 49, 37)
 
100
        rsrc.created_time = created_time
 
101
        self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
 
102
 
 
103
        expected_url = "".join([
 
104
            'http://127.0.0.1:8000/v1/signal/',
 
105
            'arn%3Aopenstack%3Aheat%3A%3Atest_tenant%3Astacks%2F',
 
106
            'test_stack%2FSTACKABCD1234%2Fresources%2F',
 
107
            'signal_handler?',
 
108
            'Timestamp=2012-11-29T13%3A49%3A37Z&',
 
109
            'SignatureMethod=HmacSHA256&',
 
110
            'AWSAccessKeyId=4567&',
 
111
            'SignatureVersion=2&',
 
112
            'Signature=',
 
113
            'MJIFh7LKCpVlK6pCxe2WfYrRsfO7FU3Wt%2BzQFo2rYSY%3D'])
 
114
 
 
115
        self.assertEqual(expected_url, rsrc.FnGetAtt('AlarmUrl'))
 
116
        self.m.VerifyAll()
 
117
 
 
118
    @utils.stack_delete_after
 
119
    def test_signal(self):
 
120
        test_d = {'Data': 'foo', 'Reason': 'bar',
 
121
                  'Status': 'SUCCESS', 'UniqueId': '123'}
 
122
 
 
123
        self.stack = self.create_stack()
 
124
 
 
125
        # to confirm we get a call to handle_signal
 
126
        self.m.StubOutWithMock(generic_resource.SignalResource,
 
127
                               'handle_signal')
 
128
        generic_resource.SignalResource.handle_signal(test_d).AndReturn(None)
 
129
 
 
130
        self.m.ReplayAll()
 
131
        self.stack.create()
 
132
 
 
133
        rsrc = self.stack.resources['signal_handler']
 
134
        self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
 
135
 
 
136
        rsrc.signal(details=test_d)
 
137
 
 
138
        self.m.VerifyAll()
 
139
 
 
140
    @utils.stack_delete_after
 
141
    def test_signal_wrong_resource(self):
 
142
        # assert that we get the correct exception when calling a
 
143
        # resource.signal() that does not have a handle_signal()
 
144
        self.stack = self.create_stack()
 
145
 
 
146
        self.m.ReplayAll()
 
147
        self.stack.create()
 
148
 
 
149
        rsrc = self.stack.resources['resource_X']
 
150
        self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
 
151
 
 
152
        err_metadata = {'Data': 'foo', 'Status': 'SUCCESS', 'UniqueId': '123'}
 
153
        self.assertRaises(exception.ResourceFailure, rsrc.signal,
 
154
                          details=err_metadata)
 
155
 
 
156
        self.m.VerifyAll()
 
157
 
 
158
    @utils.stack_delete_after
 
159
    def test_signal_reception_wrong_state(self):
 
160
        # assert that we get the correct exception when calling a
 
161
        # resource.signal() that is in having a destructive action.
 
162
        self.stack = self.create_stack()
 
163
 
 
164
        self.m.ReplayAll()
 
165
        self.stack.create()
 
166
 
 
167
        rsrc = self.stack.resources['signal_handler']
 
168
        self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
 
169
        # manually override the action to DELETE
 
170
        rsrc.action = rsrc.DELETE
 
171
 
 
172
        err_metadata = {'Data': 'foo', 'Status': 'SUCCESS', 'UniqueId': '123'}
 
173
        self.assertRaises(exception.ResourceFailure, rsrc.signal,
 
174
                          details=err_metadata)
 
175
 
 
176
        self.m.VerifyAll()
 
177
 
 
178
    @utils.stack_delete_after
 
179
    def test_signal_reception_failed_call(self):
 
180
        # assert that we get the correct exception from resource.signal()
 
181
        # when resource.handle_signal() raises an exception.
 
182
        self.stack = self.create_stack()
 
183
 
 
184
        test_d = {'Data': 'foo', 'Reason': 'bar',
 
185
                  'Status': 'SUCCESS', 'UniqueId': '123'}
 
186
 
 
187
        # to confirm we get a call to handle_signal
 
188
        self.m.StubOutWithMock(generic_resource.SignalResource,
 
189
                               'handle_signal')
 
190
        generic_resource.SignalResource.handle_signal(test_d).AndRaise(
 
191
            ValueError)
 
192
 
 
193
        self.m.ReplayAll()
 
194
        self.stack.create()
 
195
 
 
196
        rsrc = self.stack.resources['signal_handler']
 
197
        self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
 
198
 
 
199
        self.assertRaises(exception.ResourceFailure,
 
200
                          rsrc.signal, details=test_d)
 
201
 
 
202
        self.m.VerifyAll()