~ubuntu-branches/ubuntu/wily/heat/wily

1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
1
#
2
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
3
#    not use this file except in compliance with the License. You may obtain
4
#    a copy of the License at
5
#
6
#         http://www.apache.org/licenses/LICENSE-2.0
7
#
8
#    Unless required by applicable law or agreed to in writing, software
9
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
#    License for the specific language governing permissions and limitations
12
#    under the License.
13
14
import datetime
15
import json
16
import uuid
17
18
import mock
19
import mox
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
20
from oslo_config import cfg
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
21
from oslo_utils import timeutils
22
import six
23
24
from heat.common import context
25
from heat.common import exception
26
from heat.common import template_format
27
from heat.db.sqlalchemy import api as db_api
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
28
from heat.db.sqlalchemy import models
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
29
from heat.engine.clients.os import glance
30
from heat.engine.clients.os import nova
31
from heat.engine import environment
32
from heat.engine import resource as rsrc
33
from heat.engine.resources.aws.ec2 import instance as instances
34
from heat.engine import scheduler
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
35
from heat.engine import stack as parser
36
from heat.engine import template as tmpl
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
37
from heat.tests import common
1.1.25 by Chuck Short
Import upstream version 2015.1.0
38
from heat.tests.nova import fakes as fakes_nova
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
39
from heat.tests import utils
40
41
42
wp_template = '''
43
{
44
  "AWSTemplateFormatVersion" : "2010-09-09",
45
  "Description" : "WordPress",
46
  "Parameters" : {
47
    "KeyName" : {
48
      "Description" : "KeyName",
49
      "Type" : "String",
50
      "Default" : "test"
51
    }
52
  },
53
  "Resources" : {
54
    "WebServer": {
55
      "Type": "AWS::EC2::Instance",
56
      "Properties": {
57
        "ImageId" : "F17-x86_64-gold",
58
        "InstanceType"   : "m1.large",
59
        "KeyName"        : "test",
60
        "UserData"       : "wordpress"
61
      }
62
    }
63
  }
64
}
65
'''
66
67
UUIDs = (UUID1, UUID2, UUID3) = sorted([str(uuid.uuid4())
68
                                        for x in range(3)])
69
70
71
class MyResource(rsrc.Resource):
72
    properties_schema = {
73
        'ServerName': {'Type': 'String', 'Required': True},
74
        'Flavor': {'Type': 'String', 'Required': True},
75
        'ImageName': {'Type': 'String', 'Required': True},
76
        'UserData': {'Type': 'String'},
77
        'PublicKey': {'Type': 'String'}
78
    }
79
80
    @property
81
    def my_secret(self):
82
        return db_api.resource_data_get(self, 'my_secret')
83
84
    @my_secret.setter
85
    def my_secret(self, my_secret):
86
        self.data_set('my_secret', my_secret, True)
87
88
89
class SqlAlchemyTest(common.HeatTestCase):
90
    def setUp(self):
91
        super(SqlAlchemyTest, self).setUp()
1.1.25 by Chuck Short
Import upstream version 2015.1.0
92
        self.fc = fakes_nova.FakeClient()
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
93
        self.ctx = utils.dummy_context()
94
95
    def tearDown(self):
96
        super(SqlAlchemyTest, self).tearDown()
97
98
    def _mock_get_image_id_success(self, imageId_input, imageId):
99
        self.m.StubOutWithMock(glance.GlanceClientPlugin, 'get_image_id')
100
        glance.GlanceClientPlugin.get_image_id(
101
            imageId_input).MultipleTimes().AndReturn(imageId)
102
103
    def _setup_test_stack(self, stack_name, stack_id=None, owner_id=None,
104
                          stack_user_project_id=None, backup=False):
105
        t = template_format.parse(wp_template)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
106
        template = tmpl.Template(
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
107
            t, env=environment.Environment({'KeyName': 'test'}))
108
        stack_id = stack_id or str(uuid.uuid4())
109
        stack = parser.Stack(self.ctx, stack_name, template,
110
                             owner_id=owner_id,
111
                             stack_user_project_id=stack_user_project_id)
112
        with utils.UUIDStub(stack_id):
113
            stack.store(backup=backup)
114
        return (template, stack)
115
116
    def _mock_create(self, mocks):
1.1.25 by Chuck Short
Import upstream version 2015.1.0
117
        fc = fakes_nova.FakeClient()
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
118
        mocks.StubOutWithMock(instances.Instance, 'nova')
119
        instances.Instance.nova().MultipleTimes().AndReturn(fc)
120
        self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
121
        nova.NovaClientPlugin._create().AndReturn(self.fc)
122
        self._mock_get_image_id_success('F17-x86_64-gold', 744)
123
124
        mocks.StubOutWithMock(fc.servers, 'create')
125
        fc.servers.create(image=744, flavor=3, key_name='test',
126
                          name=mox.IgnoreArg(),
127
                          security_groups=None,
128
                          userdata=mox.IgnoreArg(), scheduler_hints=None,
129
                          meta=None, nics=None,
130
                          availability_zone=None,
131
                          block_device_mapping=None
132
                          ).MultipleTimes().AndReturn(fc.servers.list()[4])
133
        return fc
134
135
    def _mock_delete(self, mocks):
1.1.25 by Chuck Short
Import upstream version 2015.1.0
136
        fc = fakes_nova.FakeClient()
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
137
        mocks.StubOutWithMock(instances.Instance, 'client')
138
        instances.Instance.client().MultipleTimes().AndReturn(fc)
139
        self.patchobject(fc.servers, 'delete',
140
                         side_effect=fakes_nova.fake_exception())
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
141
142
    @mock.patch.object(db_api, '_paginate_query')
143
    def test_filter_and_page_query_paginates_query(self, mock_paginate_query):
144
        query = mock.Mock()
145
        db_api._filter_and_page_query(self.ctx, query)
146
147
        assert mock_paginate_query.called
148
149
    @mock.patch.object(db_api, '_events_paginate_query')
150
    def test_events_filter_and_page_query(self, mock_events_paginate_query):
151
        query = mock.Mock()
152
        db_api._events_filter_and_page_query(self.ctx, query)
153
154
        assert mock_events_paginate_query.called
155
156
    @mock.patch.object(db_api.db_filters, 'exact_filter')
157
    def test_filter_and_page_query_handles_no_filters(self, mock_db_filter):
158
        query = mock.Mock()
159
        db_api._filter_and_page_query(self.ctx, query)
160
161
        mock_db_filter.assert_called_once_with(mock.ANY, mock.ANY, {})
162
163
    @mock.patch.object(db_api.db_filters, 'exact_filter')
164
    def test_events_filter_and_page_query_handles_no_filters(self,
165
                                                             mock_db_filter):
166
        query = mock.Mock()
167
        db_api._events_filter_and_page_query(self.ctx, query)
168
169
        mock_db_filter.assert_called_once_with(mock.ANY, mock.ANY, {})
170
171
    @mock.patch.object(db_api.db_filters, 'exact_filter')
172
    def test_filter_and_page_query_applies_filters(self, mock_db_filter):
173
        query = mock.Mock()
174
        filters = {'foo': 'bar'}
175
        db_api._filter_and_page_query(self.ctx, query, filters=filters)
176
177
        assert mock_db_filter.called
178
179
    @mock.patch.object(db_api.db_filters, 'exact_filter')
180
    def test_events_filter_and_page_query_applies_filters(self,
181
                                                          mock_db_filter):
182
        query = mock.Mock()
183
        filters = {'foo': 'bar'}
184
        db_api._events_filter_and_page_query(self.ctx, query, filters=filters)
185
186
        assert mock_db_filter.called
187
188
    @mock.patch.object(db_api, '_paginate_query')
189
    def test_filter_and_page_query_whitelists_sort_keys(self,
190
                                                        mock_paginate_query):
191
        query = mock.Mock()
192
        sort_keys = ['stack_name', 'foo']
193
        db_api._filter_and_page_query(self.ctx, query, sort_keys=sort_keys)
194
195
        args, _ = mock_paginate_query.call_args
196
        self.assertIn(['name'], args)
197
198
    @mock.patch.object(db_api, '_events_paginate_query')
199
    def test_events_filter_and_page_query_whitelists_sort_keys(
200
            self, mock_paginate_query):
201
        query = mock.Mock()
202
        sort_keys = ['event_time', 'foo']
203
        db_api._events_filter_and_page_query(self.ctx, query,
204
                                             sort_keys=sort_keys)
205
206
        args, _ = mock_paginate_query.call_args
207
        self.assertIn(['created_at'], args)
208
209
    @mock.patch.object(db_api.utils, 'paginate_query')
210
    def test_paginate_query_default_sorts_by_created_at_and_id(
211
            self, mock_paginate_query):
212
        query = mock.Mock()
213
        model = mock.Mock()
214
        db_api._paginate_query(self.ctx, query, model, sort_keys=None)
215
        args, _ = mock_paginate_query.call_args
216
        self.assertIn(['created_at', 'id'], args)
217
218
    @mock.patch.object(db_api.utils, 'paginate_query')
219
    def test_paginate_query_default_sorts_dir_by_desc(self,
220
                                                      mock_paginate_query):
221
        query = mock.Mock()
222
        model = mock.Mock()
223
        db_api._paginate_query(self.ctx, query, model, sort_dir=None)
224
        args, _ = mock_paginate_query.call_args
225
        self.assertIn('desc', args)
226
227
    @mock.patch.object(db_api.utils, 'paginate_query')
228
    def test_paginate_query_uses_given_sort_plus_id(self,
229
                                                    mock_paginate_query):
230
        query = mock.Mock()
231
        model = mock.Mock()
232
        db_api._paginate_query(self.ctx, query, model, sort_keys=['name'])
233
        args, _ = mock_paginate_query.call_args
234
        self.assertIn(['name', 'id'], args)
235
236
    @mock.patch.object(db_api.utils, 'paginate_query')
237
    @mock.patch.object(db_api, 'model_query')
238
    def test_paginate_query_gets_model_marker(self, mock_query,
239
                                              mock_paginate_query):
240
        query = mock.Mock()
241
        model = mock.Mock()
242
        marker = mock.Mock()
243
244
        mock_query_object = mock.Mock()
245
        mock_query_object.get.return_value = 'real_marker'
246
        mock_query.return_value = mock_query_object
247
248
        db_api._paginate_query(self.ctx, query, model, marker=marker)
249
        mock_query_object.get.assert_called_once_with(marker)
250
        args, _ = mock_paginate_query.call_args
251
        self.assertIn('real_marker', args)
252
253
    @mock.patch.object(db_api.utils, 'paginate_query')
254
    def test_paginate_query_raises_invalid_sort_key(self, mock_paginate_query):
255
        query = mock.Mock()
256
        model = mock.Mock()
257
258
        mock_paginate_query.side_effect = db_api.utils.InvalidSortKey()
259
        self.assertRaises(exception.Invalid, db_api._paginate_query,
260
                          self.ctx, query, model, sort_keys=['foo'])
261
262
    def test_get_sort_keys_returns_empty_list_if_no_keys(self):
263
        sort_keys = None
264
        mapping = {}
265
266
        filtered_keys = db_api._get_sort_keys(sort_keys, mapping)
267
        self.assertEqual([], filtered_keys)
268
269
    def test_get_sort_keys_whitelists_single_key(self):
270
        sort_key = 'foo'
271
        mapping = {'foo': 'Foo'}
272
273
        filtered_keys = db_api._get_sort_keys(sort_key, mapping)
274
        self.assertEqual(['Foo'], filtered_keys)
275
276
    def test_get_sort_keys_whitelists_multiple_keys(self):
277
        sort_keys = ['foo', 'bar', 'nope']
278
        mapping = {'foo': 'Foo', 'bar': 'Bar'}
279
280
        filtered_keys = db_api._get_sort_keys(sort_keys, mapping)
281
        self.assertIn('Foo', filtered_keys)
282
        self.assertIn('Bar', filtered_keys)
283
        self.assertEqual(2, len(filtered_keys))
284
285
    def test_encryption(self):
286
        stack_name = 'test_encryption'
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
287
        (template, stack) = self._setup_test_stack(stack_name)
288
        resource_defns = template.resource_definitions(stack)
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
289
        cs = MyResource('cs_encryption',
290
                        resource_defns['WebServer'],
291
                        stack)
292
293
        # This gives the fake cloud server an id and created_time attribute
294
        cs._store_or_update(cs.CREATE, cs.IN_PROGRESS, 'test_store')
295
296
        cs.my_secret = 'fake secret'
297
        rs = db_api.resource_get_by_name_and_stack(self.ctx,
298
                                                   'cs_encryption',
299
                                                   stack.id)
300
        encrypted_key = rs.data[0]['value']
301
        self.assertNotEqual(encrypted_key, "fake secret")
302
        # Test private_key property returns decrypted value
303
        self.assertEqual("fake secret", cs.my_secret)
304
305
        # do this twice to verify that the orm does not commit the unencrypted
306
        # value.
307
        self.assertEqual("fake secret", cs.my_secret)
308
        scheduler.TaskRunner(cs.destroy)()
309
310
    def test_resource_data_delete(self):
311
        stack = self._setup_test_stack('stack', UUID1)[1]
312
        self._mock_create(self.m)
313
        self.m.ReplayAll()
314
        stack.create()
315
        resource = stack['WebServer']
316
        resource.data_set('test', 'test_data')
317
        self.assertEqual('test_data', db_api.resource_data_get(resource,
318
                                                               'test'))
319
        db_api.resource_data_delete(resource, 'test')
320
        self.assertRaises(exception.NotFound,
321
                          db_api.resource_data_get, resource, 'test')
322
323
    def test_stack_get_by_name(self):
324
        stack = self._setup_test_stack('stack', UUID1,
325
                                       stack_user_project_id=UUID2)[1]
326
327
        st = db_api.stack_get_by_name(self.ctx, 'stack')
328
        self.assertEqual(UUID1, st.id)
329
330
        self.ctx.tenant_id = UUID3
331
        st = db_api.stack_get_by_name(self.ctx, 'stack')
332
        self.assertIsNone(st)
333
334
        self.ctx.tenant_id = UUID2
335
        st = db_api.stack_get_by_name(self.ctx, 'stack')
336
        self.assertEqual(UUID1, st.id)
337
338
        stack.delete()
339
340
        st = db_api.stack_get_by_name(self.ctx, 'stack')
341
        self.assertIsNone(st)
342
343
    def test_nested_stack_get_by_name(self):
344
        stack1 = self._setup_test_stack('stack1', UUID1)[1]
345
        stack2 = self._setup_test_stack('stack2', UUID2,
346
                                        owner_id=stack1.id)[1]
347
348
        result = db_api.stack_get_by_name(self.ctx, 'stack2')
349
        self.assertEqual(UUID2, result.id)
350
351
        stack2.delete()
352
353
        result = db_api.stack_get_by_name(self.ctx, 'stack2')
354
        self.assertIsNone(result)
355
356
    def test_stack_get_by_name_and_owner_id(self):
357
        stack1 = self._setup_test_stack('stack1', UUID1,
358
                                        stack_user_project_id=UUID3)[1]
359
        stack2 = self._setup_test_stack('stack2', UUID2,
360
                                        owner_id=stack1.id,
361
                                        stack_user_project_id=UUID3)[1]
362
363
        result = db_api.stack_get_by_name_and_owner_id(self.ctx, 'stack2',
364
                                                       None)
365
        self.assertIsNone(result)
366
367
        result = db_api.stack_get_by_name_and_owner_id(self.ctx, 'stack2',
368
                                                       stack1.id)
369
370
        self.assertEqual(UUID2, result.id)
371
372
        self.ctx.tenant_id = str(uuid.uuid4())
373
        result = db_api.stack_get_by_name_and_owner_id(self.ctx, 'stack2',
374
                                                       None)
375
        self.assertIsNone(result)
376
377
        self.ctx.tenant_id = UUID3
378
        result = db_api.stack_get_by_name_and_owner_id(self.ctx, 'stack2',
379
                                                       stack1.id)
380
381
        self.assertEqual(UUID2, result.id)
382
383
        stack2.delete()
384
385
        result = db_api.stack_get_by_name_and_owner_id(self.ctx, 'stack2',
386
                                                       stack1.id)
387
        self.assertIsNone(result)
388
389
    def test_stack_get(self):
390
        stack = self._setup_test_stack('stack', UUID1)[1]
391
392
        st = db_api.stack_get(self.ctx, UUID1, show_deleted=False)
393
        self.assertEqual(UUID1, st.id)
394
395
        stack.delete()
396
        st = db_api.stack_get(self.ctx, UUID1, show_deleted=False)
397
        self.assertIsNone(st)
398
399
        st = db_api.stack_get(self.ctx, UUID1, show_deleted=True)
400
        self.assertEqual(UUID1, st.id)
401
402
    def test_stack_get_show_deleted_context(self):
403
        stack = self._setup_test_stack('stack', UUID1)[1]
404
405
        self.assertFalse(self.ctx.show_deleted)
406
        st = db_api.stack_get(self.ctx, UUID1)
407
        self.assertEqual(UUID1, st.id)
408
409
        stack.delete()
410
        st = db_api.stack_get(self.ctx, UUID1)
411
        self.assertIsNone(st)
412
413
        self.ctx.show_deleted = True
414
        st = db_api.stack_get(self.ctx, UUID1)
415
        self.assertEqual(UUID1, st.id)
416
417
    def test_stack_get_all(self):
418
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
419
420
        st_db = db_api.stack_get_all(self.ctx)
421
        self.assertEqual(3, len(st_db))
422
423
        stacks[0].delete()
424
        st_db = db_api.stack_get_all(self.ctx)
425
        self.assertEqual(2, len(st_db))
426
427
        stacks[1].delete()
428
        st_db = db_api.stack_get_all(self.ctx)
429
        self.assertEqual(1, len(st_db))
430
431
    def test_stack_get_all_show_deleted(self):
432
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
433
434
        st_db = db_api.stack_get_all(self.ctx)
435
        self.assertEqual(3, len(st_db))
436
437
        stacks[0].delete()
438
        st_db = db_api.stack_get_all(self.ctx)
439
        self.assertEqual(2, len(st_db))
440
441
        st_db = db_api.stack_get_all(self.ctx, show_deleted=True)
442
        self.assertEqual(3, len(st_db))
443
444
    def test_stack_get_all_show_nested(self):
445
        stack1 = self._setup_test_stack('stack1', UUID1)[1]
446
        stack2 = self._setup_test_stack('stack2', UUID2,
447
                                        owner_id=stack1.id)[1]
448
        # Backup stack should not be returned
449
        stack3 = self._setup_test_stack('stack1*', UUID3,
450
                                        owner_id=stack1.id,
451
                                        backup=True)[1]
452
453
        st_db = db_api.stack_get_all(self.ctx)
454
        self.assertEqual(1, len(st_db))
455
        self.assertEqual(stack1.id, st_db[0].id)
456
457
        st_db = db_api.stack_get_all(self.ctx, show_nested=True)
458
        self.assertEqual(2, len(st_db))
459
        st_ids = [s.id for s in st_db]
460
        self.assertNotIn(stack3.id, st_ids)
461
        self.assertIn(stack1.id, st_ids)
462
        self.assertIn(stack2.id, st_ids)
463
464
    def test_stack_get_all_with_filters(self):
465
        self._setup_test_stack('foo', UUID1)
466
        self._setup_test_stack('bar', UUID2)
467
468
        filters = {'name': 'foo'}
469
        results = db_api.stack_get_all(self.ctx,
470
                                       filters=filters)
471
472
        self.assertEqual(1, len(results))
473
        self.assertEqual('foo', results[0]['name'])
474
475
    def test_stack_get_all_filter_matches_in_list(self):
476
        self._setup_test_stack('foo', UUID1)
477
        self._setup_test_stack('bar', UUID2)
478
479
        filters = {'name': ['bar', 'quux']}
480
        results = db_api.stack_get_all(self.ctx,
481
                                       filters=filters)
482
483
        self.assertEqual(1, len(results))
484
        self.assertEqual('bar', results[0]['name'])
485
486
    def test_stack_get_all_returns_all_if_no_filters(self):
487
        self._setup_test_stack('foo', UUID1)
488
        self._setup_test_stack('bar', UUID2)
489
490
        filters = None
491
        results = db_api.stack_get_all(self.ctx,
492
                                       filters=filters)
493
494
        self.assertEqual(2, len(results))
495
496
    def test_stack_get_all_default_sort_keys_and_dir(self):
497
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
498
499
        st_db = db_api.stack_get_all(self.ctx)
500
        self.assertEqual(3, len(st_db))
501
        self.assertEqual(stacks[2].id, st_db[0].id)
502
        self.assertEqual(stacks[1].id, st_db[1].id)
503
        self.assertEqual(stacks[0].id, st_db[2].id)
504
505
    def test_stack_get_all_default_sort_dir(self):
506
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
507
508
        st_db = db_api.stack_get_all(self.ctx, sort_dir='asc')
509
        self.assertEqual(3, len(st_db))
510
        self.assertEqual(stacks[0].id, st_db[0].id)
511
        self.assertEqual(stacks[1].id, st_db[1].id)
512
        self.assertEqual(stacks[2].id, st_db[2].id)
513
514
    def test_stack_get_all_str_sort_keys(self):
515
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
516
517
        st_db = db_api.stack_get_all(self.ctx,
518
                                     sort_keys='creation_time')
519
        self.assertEqual(3, len(st_db))
520
        self.assertEqual(stacks[0].id, st_db[0].id)
521
        self.assertEqual(stacks[1].id, st_db[1].id)
522
        self.assertEqual(stacks[2].id, st_db[2].id)
523
524
    @mock.patch.object(db_api.utils, 'paginate_query')
525
    def test_stack_get_all_filters_sort_keys(self, mock_paginate):
526
        sort_keys = ['stack_name', 'stack_status', 'creation_time',
527
                     'updated_time', 'stack_owner']
528
        db_api.stack_get_all(self.ctx, sort_keys=sort_keys)
529
530
        args = mock_paginate.call_args[0]
531
        used_sort_keys = set(args[3])
532
        expected_keys = set(['name', 'status', 'created_at',
533
                             'updated_at', 'id'])
534
        self.assertEqual(expected_keys, used_sort_keys)
535
536
    def test_stack_get_all_marker(self):
537
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
538
539
        st_db = db_api.stack_get_all(self.ctx, marker=stacks[1].id)
540
        self.assertEqual(1, len(st_db))
541
        self.assertEqual(stacks[0].id, st_db[0].id)
542
543
    def test_stack_get_all_non_existing_marker(self):
544
        [self._setup_test_stack('stack', x)[1] for x in UUIDs]
545
546
        uuid = 'this stack doesn\'t exist'
547
        st_db = db_api.stack_get_all(self.ctx, marker=uuid)
548
        self.assertEqual(3, len(st_db))
549
550
    def test_stack_get_all_doesnt_mutate_sort_keys(self):
551
        [self._setup_test_stack('stack', x)[1] for x in UUIDs]
552
        sort_keys = ['id']
553
554
        db_api.stack_get_all(self.ctx, sort_keys=sort_keys)
555
        self.assertEqual(['id'], sort_keys)
556
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
557
    def test_stack_get_all_hidden_tags(self):
558
        cfg.CONF.set_override('hidden_stack_tags', ['hidden'])
559
560
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
561
        stacks[0].tags = ['hidden']
562
        stacks[0].store()
563
        stacks[1].tags = ['random']
564
        stacks[1].store()
565
566
        st_db = db_api.stack_get_all(self.ctx, show_hidden=True)
567
        self.assertEqual(3, len(st_db))
568
569
        st_db_visible = db_api.stack_get_all(self.ctx, show_hidden=False)
570
        self.assertEqual(2, len(st_db_visible))
571
572
        # Make sure the hidden stack isn't in the stacks returned by
573
        # stack_get_all_visible()
574
        for stack in st_db_visible:
575
            self.assertNotEqual(stacks[0].id, stack.id)
576
577
    def test_stack_get_all_by_tags(self):
578
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
579
        stacks[0].tags = ['tag1']
580
        stacks[0].store()
581
        stacks[1].tags = ['tag1', 'tag2']
582
        stacks[1].store()
583
        stacks[2].tags = ['tag1', 'tag2', 'tag3']
584
        stacks[2].store()
585
586
        st_db = db_api.stack_get_all(self.ctx, tags=['tag2'])
587
        self.assertEqual(2, len(st_db))
588
589
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1', 'tag2'])
590
        self.assertEqual(2, len(st_db))
591
592
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1', 'tag2', 'tag3'])
593
        self.assertEqual(1, len(st_db))
594
595
    def test_stack_get_all_by_tags_any(self):
596
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
597
        stacks[0].tags = ['tag2']
598
        stacks[0].store()
599
        stacks[1].tags = ['tag1', 'tag2']
600
        stacks[1].store()
601
        stacks[2].tags = ['tag1', 'tag3']
602
        stacks[2].store()
603
604
        st_db = db_api.stack_get_all(self.ctx, tags_any=['tag1'])
605
        self.assertEqual(2, len(st_db))
606
607
        st_db = db_api.stack_get_all(self.ctx, tags_any=['tag1', 'tag2',
608
                                                         'tag3'])
609
        self.assertEqual(3, len(st_db))
610
611
    def test_stack_get_all_by_not_tags(self):
612
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
613
        stacks[0].tags = ['tag1']
614
        stacks[0].store()
615
        stacks[1].tags = ['tag1', 'tag2']
616
        stacks[1].store()
617
        stacks[2].tags = ['tag1', 'tag2', 'tag3']
618
        stacks[2].store()
619
620
        st_db = db_api.stack_get_all(self.ctx, not_tags=['tag2'])
621
        self.assertEqual(1, len(st_db))
622
623
        st_db = db_api.stack_get_all(self.ctx, not_tags=['tag1', 'tag2'])
624
        self.assertEqual(1, len(st_db))
625
626
        st_db = db_api.stack_get_all(self.ctx, not_tags=['tag1', 'tag2',
627
                                                         'tag3'])
628
        self.assertEqual(2, len(st_db))
629
630
    def test_stack_get_all_by_not_tags_any(self):
631
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
632
        stacks[0].tags = ['tag2']
633
        stacks[0].store()
634
        stacks[1].tags = ['tag1', 'tag2']
635
        stacks[1].store()
636
        stacks[2].tags = ['tag1', 'tag3']
637
        stacks[2].store()
638
639
        st_db = db_api.stack_get_all(self.ctx, not_tags_any=['tag1'])
640
        self.assertEqual(1, len(st_db))
641
642
        st_db = db_api.stack_get_all(self.ctx, not_tags_any=['tag1', 'tag2',
643
                                                             'tag3'])
644
        self.assertEqual(0, len(st_db))
645
646
    def test_stack_get_all_by_tag_with_pagination(self):
647
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
648
        stacks[0].tags = ['tag1']
649
        stacks[0].store()
650
        stacks[1].tags = ['tag2']
651
        stacks[1].store()
652
        stacks[2].tags = ['tag1']
653
        stacks[2].store()
654
655
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1'])
656
        self.assertEqual(2, len(st_db))
657
658
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1'], limit=1)
659
        self.assertEqual(1, len(st_db))
660
        self.assertEqual(stacks[2].id, st_db[0].id)
661
662
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1'], limit=1,
663
                                     marker=stacks[2].id)
664
        self.assertEqual(1, len(st_db))
665
        self.assertEqual(stacks[0].id, st_db[0].id)
666
667
    def test_stack_get_all_by_tag_with_show_hidden(self):
668
        cfg.CONF.set_override('hidden_stack_tags', ['hidden'])
669
670
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
671
        stacks[0].tags = ['tag1']
672
        stacks[0].store()
673
        stacks[1].tags = ['hidden', 'tag1']
674
        stacks[1].store()
675
676
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1'],
677
                                     show_hidden=True)
678
        self.assertEqual(2, len(st_db))
679
680
        st_db = db_api.stack_get_all(self.ctx, tags=['tag1'],
681
                                     show_hidden=False)
682
        self.assertEqual(1, len(st_db))
683
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
684
    def test_stack_count_all(self):
685
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
686
687
        st_db = db_api.stack_count_all(self.ctx)
688
        self.assertEqual(3, st_db)
689
690
        stacks[0].delete()
691
        st_db = db_api.stack_count_all(self.ctx)
692
        self.assertEqual(2, st_db)
693
        # show deleted
694
        st_db = db_api.stack_count_all(self.ctx, show_deleted=True)
695
        self.assertEqual(3, st_db)
696
697
        stacks[1].delete()
698
        st_db = db_api.stack_count_all(self.ctx)
699
        self.assertEqual(1, st_db)
700
        # show deleted
701
        st_db = db_api.stack_count_all(self.ctx, show_deleted=True)
702
        self.assertEqual(3, st_db)
703
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
704
    def test_count_all_hidden_tags(self):
705
        cfg.CONF.set_override('hidden_stack_tags', ['hidden'])
706
707
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
708
        stacks[0].tags = ['hidden']
709
        stacks[0].store()
710
        stacks[1].tags = ['random']
711
        stacks[1].store()
712
713
        st_db = db_api.stack_count_all(self.ctx, show_hidden=True)
714
        self.assertEqual(3, st_db)
715
716
        st_db_visible = db_api.stack_count_all(self.ctx, show_hidden=False)
717
        self.assertEqual(2, st_db_visible)
718
719
    def test_count_all_by_tags(self):
720
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
721
        stacks[0].tags = ['tag1']
722
        stacks[0].store()
723
        stacks[1].tags = ['tag2']
724
        stacks[1].store()
725
        stacks[2].tags = ['tag2']
726
        stacks[2].store()
727
728
        st_db = db_api.stack_count_all(self.ctx, tags=['tag1'])
729
        self.assertEqual(1, st_db)
730
731
        st_db = db_api.stack_count_all(self.ctx, tags=['tag2'])
732
        self.assertEqual(2, st_db)
733
734
    def test_count_all_by_tag_with_show_hidden(self):
735
        cfg.CONF.set_override('hidden_stack_tags', ['hidden'])
736
737
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
738
        stacks[0].tags = ['tag1']
739
        stacks[0].store()
740
        stacks[1].tags = ['hidden', 'tag1']
741
        stacks[1].store()
742
743
        st_db = db_api.stack_count_all(self.ctx, tags=['tag1'],
744
                                       show_hidden=True)
745
        self.assertEqual(2, st_db)
746
747
        st_db = db_api.stack_count_all(self.ctx, tags=['tag1'],
748
                                       show_hidden=False)
749
        self.assertEqual(1, st_db)
750
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
751
    def test_stack_count_all_with_filters(self):
752
        self._setup_test_stack('foo', UUID1)
753
        self._setup_test_stack('bar', UUID2)
754
        self._setup_test_stack('bar', UUID3)
755
        filters = {'name': 'bar'}
756
757
        st_db = db_api.stack_count_all(self.ctx, filters=filters)
758
        self.assertEqual(2, st_db)
759
760
    def test_stack_count_all_show_nested(self):
761
        stack1 = self._setup_test_stack('stack1', UUID1)[1]
762
        self._setup_test_stack('stack2', UUID2,
763
                               owner_id=stack1.id)
764
        # Backup stack should not be counted
765
        self._setup_test_stack('stack1*', UUID3,
766
                               owner_id=stack1.id,
767
                               backup=True)
768
769
        st_db = db_api.stack_count_all(self.ctx)
770
        self.assertEqual(1, st_db)
771
772
        st_db = db_api.stack_count_all(self.ctx, show_nested=True)
773
        self.assertEqual(2, st_db)
774
775
    def test_event_get_all_by_stack(self):
776
        stack = self._setup_test_stack('stack', UUID1)[1]
777
778
        self._mock_create(self.m)
779
        self.m.ReplayAll()
780
        stack.create()
781
        self.m.UnsetStubs()
782
783
        events = db_api.event_get_all_by_stack(self.ctx, UUID1)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
784
        self.assertEqual(4, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
785
786
        # test filter by resource_status
787
        filters = {'resource_status': 'COMPLETE'}
788
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
789
                                               filters=filters)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
790
        self.assertEqual(2, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
791
        self.assertEqual('COMPLETE', events[0].resource_status)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
792
        self.assertEqual('COMPLETE', events[1].resource_status)
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
793
        # test filter by resource_action
794
        filters = {'resource_action': 'CREATE'}
795
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
796
                                               filters=filters)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
797
        self.assertEqual(4, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
798
        self.assertEqual('CREATE', events[0].resource_action)
799
        self.assertEqual('CREATE', events[1].resource_action)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
800
        self.assertEqual('CREATE', events[2].resource_action)
801
        self.assertEqual('CREATE', events[3].resource_action)
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
802
        # test filter by resource_type
803
        filters = {'resource_type': 'AWS::EC2::Instance'}
804
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
805
                                               filters=filters)
806
        self.assertEqual(2, len(events))
807
        self.assertEqual('AWS::EC2::Instance', events[0].resource_type)
808
        self.assertEqual('AWS::EC2::Instance', events[1].resource_type)
809
810
        filters = {'resource_type': 'OS::Nova::Server'}
811
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
812
                                               filters=filters)
813
        self.assertEqual(0, len(events))
814
        # test limit and marker
815
        events_all = db_api.event_get_all_by_stack(self.ctx, UUID1)
816
        marker = events_all[0].uuid
817
        expected = events_all[1].uuid
818
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
819
                                               limit=1, marker=marker)
820
        self.assertEqual(1, len(events))
821
        self.assertEqual(expected, events[0].uuid)
822
823
        self._mock_delete(self.m)
824
        self.m.ReplayAll()
825
        stack.delete()
826
827
        # test filter by resource_status
828
        filters = {'resource_status': 'COMPLETE'}
829
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
830
                                               filters=filters)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
831
        self.assertEqual(4, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
832
        self.assertEqual('COMPLETE', events[0].resource_status)
833
        self.assertEqual('COMPLETE', events[1].resource_status)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
834
        self.assertEqual('COMPLETE', events[2].resource_status)
835
        self.assertEqual('COMPLETE', events[3].resource_status)
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
836
        # test filter by resource_action
837
        filters = {'resource_action': 'DELETE',
838
                   'resource_status': 'COMPLETE'}
839
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
840
                                               filters=filters)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
841
        self.assertEqual(2, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
842
        self.assertEqual('DELETE', events[0].resource_action)
843
        self.assertEqual('COMPLETE', events[0].resource_status)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
844
        self.assertEqual('DELETE', events[1].resource_action)
845
        self.assertEqual('COMPLETE', events[1].resource_status)
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
846
        # test limit and marker
847
        events_all = db_api.event_get_all_by_stack(self.ctx, UUID1)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
848
        self.assertEqual(8, len(events_all))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
849
850
        marker = events_all[1].uuid
851
        events2_uuid = events_all[2].uuid
852
        events3_uuid = events_all[3].uuid
853
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
854
                                               limit=1, marker=marker)
855
        self.assertEqual(1, len(events))
856
        self.assertEqual(events2_uuid, events[0].uuid)
857
858
        events = db_api.event_get_all_by_stack(self.ctx, UUID1,
859
                                               limit=2, marker=marker)
860
        self.assertEqual(2, len(events))
861
        self.assertEqual(events2_uuid, events[0].uuid)
862
        self.assertEqual(events3_uuid, events[1].uuid)
863
864
        self.m.VerifyAll()
865
866
    def test_event_count_all_by_stack(self):
867
        stack = self._setup_test_stack('stack', UUID1)[1]
868
869
        self._mock_create(self.m)
870
        self.m.ReplayAll()
871
        stack.create()
872
        self.m.UnsetStubs()
873
874
        num_events = db_api.event_count_all_by_stack(self.ctx, UUID1)
875
        self.assertEqual(4, num_events)
876
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
877
        self._mock_delete(self.m)
878
        self.m.ReplayAll()
879
        stack.delete()
880
881
        num_events = db_api.event_count_all_by_stack(self.ctx, UUID1)
882
        self.assertEqual(8, num_events)
883
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
884
        self.m.VerifyAll()
885
886
    def test_event_get_all_by_tenant(self):
887
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
888
889
        self._mock_create(self.m)
890
        self.m.ReplayAll()
891
        [s.create() for s in stacks]
892
        self.m.UnsetStubs()
893
894
        events = db_api.event_get_all_by_tenant(self.ctx)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
895
        self.assertEqual(12, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
896
897
        self._mock_delete(self.m)
898
        self.m.ReplayAll()
899
        [s.delete() for s in stacks]
900
901
        events = db_api.event_get_all_by_tenant(self.ctx)
902
        self.assertEqual(0, len(events))
903
904
        self.m.VerifyAll()
905
906
    def test_event_get_all(self):
907
        stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
908
909
        self._mock_create(self.m)
910
        self.m.ReplayAll()
911
        [s.create() for s in stacks]
912
        self.m.UnsetStubs()
913
914
        events = db_api.event_get_all(self.ctx)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
915
        self.assertEqual(12, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
916
917
        self._mock_delete(self.m)
918
        self.m.ReplayAll()
919
        stacks[0].delete()
920
921
        events = db_api.event_get_all(self.ctx)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
922
        self.assertEqual(8, len(events))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
923
924
        self.m.VerifyAll()
925
926
    def test_user_creds_password(self):
927
        self.ctx.trust_id = None
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
928
        self.ctx.region_name = 'RegionOne'
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
929
        db_creds = db_api.user_creds_create(self.ctx)
930
        load_creds = db_api.user_creds_get(db_creds.id)
931
932
        self.assertEqual('test_username', load_creds.get('username'))
933
        self.assertEqual('password', load_creds.get('password'))
934
        self.assertEqual('test_tenant', load_creds.get('tenant'))
935
        self.assertEqual('test_tenant_id', load_creds.get('tenant_id'))
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
936
        self.assertEqual('RegionOne', load_creds.get('region_name'))
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
937
        self.assertIsNotNone(load_creds.get('created_at'))
938
        self.assertIsNone(load_creds.get('updated_at'))
939
        self.assertEqual('http://server.test:5000/v2.0',
940
                         load_creds.get('auth_url'))
941
        self.assertIsNone(load_creds.get('trust_id'))
942
        self.assertIsNone(load_creds.get('trustor_user_id'))
943
944
    def test_user_creds_password_too_long(self):
945
        self.ctx.trust_id = None
946
        self.ctx.password = 'O123456789O1234567' * 20
947
        error = self.assertRaises(exception.Error,
948
                                  db_api.user_creds_create,
949
                                  self.ctx)
950
        self.assertIn('Length of OS_PASSWORD after encryption exceeds '
951
                      'Heat limit (255 chars)', six.text_type(error))
952
953
    def test_user_creds_trust(self):
954
        self.ctx.username = None
955
        self.ctx.password = None
956
        self.ctx.trust_id = 'atrust123'
957
        self.ctx.trustor_user_id = 'atrustor123'
958
        self.ctx.tenant_id = 'atenant123'
959
        self.ctx.tenant = 'atenant'
960
        self.ctx.auth_url = 'anauthurl'
961
        self.ctx.region_name = 'aregion'
962
        db_creds = db_api.user_creds_create(self.ctx)
963
        load_creds = db_api.user_creds_get(db_creds.id)
964
965
        self.assertIsNone(load_creds.get('username'))
966
        self.assertIsNone(load_creds.get('password'))
967
        self.assertIsNotNone(load_creds.get('created_at'))
968
        self.assertIsNone(load_creds.get('updated_at'))
969
        self.assertEqual('anauthurl', load_creds.get('auth_url'))
970
        self.assertEqual('aregion', load_creds.get('region_name'))
971
        self.assertEqual('atenant123', load_creds.get('tenant_id'))
972
        self.assertEqual('atenant', load_creds.get('tenant'))
973
        self.assertEqual('atrust123', load_creds.get('trust_id'))
974
        self.assertEqual('atrustor123', load_creds.get('trustor_user_id'))
975
976
    def test_user_creds_none(self):
977
        self.ctx.username = None
978
        self.ctx.password = None
979
        self.ctx.trust_id = None
980
        self.ctx.region_name = None
981
        db_creds = db_api.user_creds_create(self.ctx)
982
        load_creds = db_api.user_creds_get(db_creds.id)
983
984
        self.assertIsNone(load_creds.get('username'))
985
        self.assertIsNone(load_creds.get('password'))
986
        self.assertIsNone(load_creds.get('trust_id'))
987
        self.assertIsNone(load_creds.get('region_name'))
988
989
    def test_software_config_create(self):
990
        tenant_id = self.ctx.tenant_id
991
        config = db_api.software_config_create(
992
            self.ctx, {'name': 'config_mysql',
993
                       'tenant': tenant_id})
994
        self.assertIsNotNone(config)
995
        self.assertEqual('config_mysql', config.name)
996
        self.assertEqual(tenant_id, config.tenant)
997
998
    def test_software_config_get(self):
999
        self.assertRaises(
1000
            exception.NotFound,
1001
            db_api.software_config_get,
1002
            self.ctx,
1003
            str(uuid.uuid4()))
1004
        conf = ('#!/bin/bash\n'
1005
                'echo "$bar and $foo"\n')
1006
        config = {
1007
            'inputs': [{'name': 'foo'}, {'name': 'bar'}],
1008
            'outputs': [{'name': 'result'}],
1009
            'config': conf,
1010
            'options': {}
1011
        }
1012
        tenant_id = self.ctx.tenant_id
1013
        values = {'name': 'config_mysql',
1014
                  'tenant': tenant_id,
1015
                  'group': 'Heat::Shell',
1016
                  'config': config}
1017
        config = db_api.software_config_create(
1018
            self.ctx, values)
1019
        config_id = config.id
1020
        config = db_api.software_config_get(self.ctx, config_id)
1021
        self.assertIsNotNone(config)
1022
        self.assertEqual('config_mysql', config.name)
1023
        self.assertEqual(tenant_id, config.tenant)
1024
        self.assertEqual('Heat::Shell', config.group)
1025
        self.assertEqual(conf, config.config['config'])
1026
        self.ctx.tenant_id = None
1027
        self.assertRaises(
1028
            exception.NotFound,
1029
            db_api.software_config_get,
1030
            self.ctx,
1031
            config_id)
1032
1033
    def test_software_config_delete(self):
1034
        tenant_id = self.ctx.tenant_id
1035
        config = db_api.software_config_create(
1036
            self.ctx, {'name': 'config_mysql',
1037
                       'tenant': tenant_id})
1038
        config_id = config.id
1039
        db_api.software_config_delete(self.ctx, config_id)
1040
        err = self.assertRaises(
1041
            exception.NotFound,
1042
            db_api.software_config_get,
1043
            self.ctx,
1044
            config_id)
1045
        self.assertIn(config_id, six.text_type(err))
1046
1047
        err = self.assertRaises(
1048
            exception.NotFound, db_api.software_config_delete,
1049
            self.ctx, config_id)
1050
        self.assertIn(config_id, six.text_type(err))
1051
1052
    def _deployment_values(self):
1053
        tenant_id = self.ctx.tenant_id
1054
        stack_user_project_id = str(uuid.uuid4())
1055
        config_id = db_api.software_config_create(
1056
            self.ctx, {'name': 'config_mysql', 'tenant': tenant_id}).id
1057
        server_id = str(uuid.uuid4())
1058
        input_values = {'foo': 'fooooo', 'bar': 'baaaaa'}
1059
        values = {
1060
            'tenant': tenant_id,
1061
            'stack_user_project_id': stack_user_project_id,
1062
            'config_id': config_id,
1063
            'server_id': server_id,
1064
            'input_values': input_values
1065
        }
1066
        return values
1067
1068
    def test_software_deployment_create(self):
1069
        values = self._deployment_values()
1070
        deployment = db_api.software_deployment_create(self.ctx, values)
1071
        self.assertIsNotNone(deployment)
1072
        self.assertEqual(values['tenant'], deployment.tenant)
1073
1074
    def test_software_deployment_get(self):
1075
        self.assertRaises(
1076
            exception.NotFound,
1077
            db_api.software_deployment_get,
1078
            self.ctx,
1079
            str(uuid.uuid4()))
1080
        values = self._deployment_values()
1081
        deployment = db_api.software_deployment_create(self.ctx, values)
1082
        self.assertIsNotNone(deployment)
1083
        deployment_id = deployment.id
1084
        deployment = db_api.software_deployment_get(self.ctx, deployment_id)
1085
        self.assertIsNotNone(deployment)
1086
        self.assertEqual(values['tenant'], deployment.tenant)
1087
        self.assertEqual(values['config_id'], deployment.config_id)
1088
        self.assertEqual(values['server_id'], deployment.server_id)
1089
        self.assertEqual(values['input_values'], deployment.input_values)
1090
        self.assertEqual(
1091
            values['stack_user_project_id'], deployment.stack_user_project_id)
1092
1093
        # assert not found with invalid context tenant
1094
        self.ctx.tenant_id = str(uuid.uuid4())
1095
        self.assertRaises(
1096
            exception.NotFound,
1097
            db_api.software_deployment_get,
1098
            self.ctx,
1099
            deployment_id)
1100
1101
        # assert found with stack_user_project_id context tenant
1102
        self.ctx.tenant_id = deployment.stack_user_project_id
1103
        deployment = db_api.software_deployment_get(self.ctx, deployment_id)
1104
        self.assertIsNotNone(deployment)
1105
        self.assertEqual(values['tenant'], deployment.tenant)
1106
1107
    def test_software_deployment_get_all(self):
1108
        self.assertEqual([], db_api.software_deployment_get_all(self.ctx))
1109
        values = self._deployment_values()
1110
        deployment = db_api.software_deployment_create(self.ctx, values)
1111
        self.assertIsNotNone(deployment)
1112
        all = db_api.software_deployment_get_all(self.ctx)
1113
        self.assertEqual(1, len(all))
1114
        self.assertEqual(deployment, all[0])
1115
        all = db_api.software_deployment_get_all(
1116
            self.ctx, server_id=values['server_id'])
1117
        self.assertEqual(1, len(all))
1118
        self.assertEqual(deployment, all[0])
1119
        all = db_api.software_deployment_get_all(
1120
            self.ctx, server_id=str(uuid.uuid4()))
1121
        self.assertEqual([], all)
1122
1123
    def test_software_deployment_update(self):
1124
        deployment_id = str(uuid.uuid4())
1125
        err = self.assertRaises(exception.NotFound,
1126
                                db_api.software_deployment_update,
1127
                                self.ctx, deployment_id, values={})
1128
        self.assertIn(deployment_id, six.text_type(err))
1129
        values = self._deployment_values()
1130
        deployment = db_api.software_deployment_create(self.ctx, values)
1131
        deployment_id = deployment.id
1132
        values = {'status': 'COMPLETED'}
1133
        deployment = db_api.software_deployment_update(
1134
            self.ctx, deployment_id, values)
1135
        self.assertIsNotNone(deployment)
1136
        self.assertEqual(values['status'], deployment.status)
1137
1138
    def test_software_deployment_delete(self):
1139
        deployment_id = str(uuid.uuid4())
1140
        err = self.assertRaises(exception.NotFound,
1141
                                db_api.software_deployment_delete,
1142
                                self.ctx, deployment_id)
1143
        self.assertIn(deployment_id, six.text_type(err))
1144
        values = self._deployment_values()
1145
        deployment = db_api.software_deployment_create(self.ctx, values)
1146
        deployment_id = deployment.id
1147
        deployment = db_api.software_deployment_get(self.ctx, deployment_id)
1148
        self.assertIsNotNone(deployment)
1149
        db_api.software_deployment_delete(self.ctx, deployment_id)
1150
1151
        err = self.assertRaises(
1152
            exception.NotFound,
1153
            db_api.software_deployment_get,
1154
            self.ctx,
1155
            deployment_id)
1156
1157
        self.assertIn(deployment_id, six.text_type(err))
1158
1159
    def test_snapshot_create(self):
1160
        template = create_raw_template(self.ctx)
1161
        user_creds = create_user_creds(self.ctx)
1162
        stack = create_stack(self.ctx, template, user_creds)
1163
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1164
                  'stack_id': stack.id}
1165
        snapshot = db_api.snapshot_create(self.ctx, values)
1166
        self.assertIsNotNone(snapshot)
1167
        self.assertEqual(values['tenant'], snapshot.tenant)
1168
1169
    def test_snapshot_create_with_name(self):
1170
        template = create_raw_template(self.ctx)
1171
        user_creds = create_user_creds(self.ctx)
1172
        stack = create_stack(self.ctx, template, user_creds)
1173
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1174
                  'stack_id': stack.id, 'name': 'snap1'}
1175
        snapshot = db_api.snapshot_create(self.ctx, values)
1176
        self.assertIsNotNone(snapshot)
1177
        self.assertEqual(values['tenant'], snapshot.tenant)
1178
        self.assertEqual('snap1', snapshot.name)
1179
1180
    def test_snapshot_get_not_found(self):
1181
        self.assertRaises(
1182
            exception.NotFound,
1183
            db_api.snapshot_get,
1184
            self.ctx,
1185
            str(uuid.uuid4()))
1186
1187
    def test_snapshot_get(self):
1188
        template = create_raw_template(self.ctx)
1189
        user_creds = create_user_creds(self.ctx)
1190
        stack = create_stack(self.ctx, template, user_creds)
1191
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1192
                  'stack_id': stack.id}
1193
        snapshot = db_api.snapshot_create(self.ctx, values)
1194
        self.assertIsNotNone(snapshot)
1195
        snapshot_id = snapshot.id
1196
        snapshot = db_api.snapshot_get(self.ctx, snapshot_id)
1197
        self.assertIsNotNone(snapshot)
1198
        self.assertEqual(values['tenant'], snapshot.tenant)
1199
        self.assertEqual(values['status'], snapshot.status)
1200
        self.assertIsNotNone(snapshot.created_at)
1201
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
1202
    def test_snapshot_get_by_another_stack(self):
1203
        template = create_raw_template(self.ctx)
1204
        user_creds = create_user_creds(self.ctx)
1205
        stack = create_stack(self.ctx, template, user_creds)
1206
        stack1 = create_stack(self.ctx, template, user_creds)
1207
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1208
                  'stack_id': stack.id}
1209
        snapshot = db_api.snapshot_create(self.ctx, values)
1210
        self.assertIsNotNone(snapshot)
1211
        snapshot_id = snapshot.id
1212
        self.assertRaises(exception.SnapshotNotFound,
1213
                          db_api.snapshot_get_by_stack,
1214
                          self.ctx, snapshot_id, stack1)
1215
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
1216
    def test_snapshot_get_not_found_invalid_tenant(self):
1217
        template = create_raw_template(self.ctx)
1218
        user_creds = create_user_creds(self.ctx)
1219
        stack = create_stack(self.ctx, template, user_creds)
1220
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1221
                  'stack_id': stack.id}
1222
        snapshot = db_api.snapshot_create(self.ctx, values)
1223
        self.ctx.tenant_id = str(uuid.uuid4())
1224
        self.assertRaises(
1225
            exception.NotFound,
1226
            db_api.snapshot_get,
1227
            self.ctx,
1228
            snapshot.id)
1229
1230
    def test_snapshot_update_not_found(self):
1231
        snapshot_id = str(uuid.uuid4())
1232
        err = self.assertRaises(exception.NotFound,
1233
                                db_api.snapshot_update,
1234
                                self.ctx, snapshot_id, values={})
1235
        self.assertIn(snapshot_id, six.text_type(err))
1236
1237
    def test_snapshot_update(self):
1238
        template = create_raw_template(self.ctx)
1239
        user_creds = create_user_creds(self.ctx)
1240
        stack = create_stack(self.ctx, template, user_creds)
1241
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1242
                  'stack_id': stack.id}
1243
        snapshot = db_api.snapshot_create(self.ctx, values)
1244
        snapshot_id = snapshot.id
1245
        values = {'status': 'COMPLETED'}
1246
        snapshot = db_api.snapshot_update(self.ctx, snapshot_id, values)
1247
        self.assertIsNotNone(snapshot)
1248
        self.assertEqual(values['status'], snapshot.status)
1249
1250
    def test_snapshot_delete_not_found(self):
1251
        snapshot_id = str(uuid.uuid4())
1252
        err = self.assertRaises(exception.NotFound,
1253
                                db_api.snapshot_delete,
1254
                                self.ctx, snapshot_id)
1255
        self.assertIn(snapshot_id, six.text_type(err))
1256
1257
    def test_snapshot_delete(self):
1258
        template = create_raw_template(self.ctx)
1259
        user_creds = create_user_creds(self.ctx)
1260
        stack = create_stack(self.ctx, template, user_creds)
1261
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1262
                  'stack_id': stack.id}
1263
        snapshot = db_api.snapshot_create(self.ctx, values)
1264
        snapshot_id = snapshot.id
1265
        snapshot = db_api.snapshot_get(self.ctx, snapshot_id)
1266
        self.assertIsNotNone(snapshot)
1267
        db_api.snapshot_delete(self.ctx, snapshot_id)
1268
1269
        err = self.assertRaises(
1270
            exception.NotFound,
1271
            db_api.snapshot_get,
1272
            self.ctx,
1273
            snapshot_id)
1274
1275
        self.assertIn(snapshot_id, six.text_type(err))
1276
1277
    def test_snapshot_get_all(self):
1278
        template = create_raw_template(self.ctx)
1279
        user_creds = create_user_creds(self.ctx)
1280
        stack = create_stack(self.ctx, template, user_creds)
1281
        values = {'tenant': self.ctx.tenant_id, 'status': 'IN_PROGRESS',
1282
                  'stack_id': stack.id}
1283
        snapshot = db_api.snapshot_create(self.ctx, values)
1284
        self.assertIsNotNone(snapshot)
1285
        [snapshot] = db_api.snapshot_get_all(self.ctx, stack.id)
1286
        self.assertIsNotNone(snapshot)
1287
        self.assertEqual(values['tenant'], snapshot.tenant)
1288
        self.assertEqual(values['status'], snapshot.status)
1289
        self.assertIsNotNone(snapshot.created_at)
1290
1291
1292
def create_raw_template(context, **kwargs):
1293
    t = template_format.parse(wp_template)
1294
    template = {
1295
        'template': t,
1296
        'files': {'foo': 'bar'}
1297
    }
1298
    template.update(kwargs)
1299
    return db_api.raw_template_create(context, template)
1300
1301
1302
def create_user_creds(ctx, **kwargs):
1303
    ctx_dict = ctx.to_dict()
1304
    ctx_dict.update(kwargs)
1305
    ctx = context.RequestContext.from_dict(ctx_dict)
1306
    return db_api.user_creds_create(ctx)
1307
1308
1309
def create_stack(ctx, template, user_creds, **kwargs):
1310
    values = {
1311
        'name': 'db_test_stack_name',
1312
        'raw_template_id': template.id,
1313
        'username': ctx.username,
1314
        'tenant': ctx.tenant_id,
1315
        'action': 'create',
1316
        'status': 'complete',
1317
        'status_reason': 'create_complete',
1318
        'parameters': {},
1319
        'user_creds_id': user_creds.id,
1320
        'owner_id': None,
1321
        'timeout': '60',
1322
        'disable_rollback': 0,
1323
        'current_traversal': 'dummy-uuid'
1324
    }
1325
    values.update(kwargs)
1326
    return db_api.stack_create(ctx, values)
1327
1328
1329
def create_resource(ctx, stack, **kwargs):
1330
    values = {
1331
        'name': 'test_resource_name',
1332
        'nova_instance': UUID1,
1333
        'action': 'create',
1334
        'status': 'complete',
1335
        'status_reason': 'create_complete',
1336
        'rsrc_metadata': json.loads('{"foo": "123"}'),
1337
        'stack_id': stack.id
1338
    }
1339
    values.update(kwargs)
1340
    return db_api.resource_create(ctx, values)
1341
1342
1343
def create_resource_data(ctx, resource, **kwargs):
1344
    values = {
1345
        'key': 'test_resource_key',
1346
        'value': 'test_value',
1347
        'redact': 0,
1348
    }
1349
    values.update(kwargs)
1350
    return db_api.resource_data_set(resource, **values)
1351
1352
1353
def create_event(ctx, **kwargs):
1354
    values = {
1355
        'stack_id': 'test_stack_id',
1356
        'resource_action': 'create',
1357
        'resource_status': 'complete',
1358
        'resource_name': 'res',
1359
        'physical_resource_id': UUID1,
1360
        'resource_status_reason': "create_complete",
1361
        'resource_properties': {'name': 'foo'}
1362
    }
1363
    values.update(kwargs)
1364
    return db_api.event_create(ctx, values)
1365
1366
1367
def create_watch_rule(ctx, stack, **kwargs):
1368
    values = {
1369
        'name': 'test_rule',
1370
        'rule': json.loads('{"foo": "123"}'),
1371
        'state': 'normal',
1372
        'last_evaluated': timeutils.utcnow(),
1373
        'stack_id': stack.id,
1374
    }
1375
    values.update(kwargs)
1376
    return db_api.watch_rule_create(ctx, values)
1377
1378
1379
def create_watch_data(ctx, watch_rule, **kwargs):
1380
    values = {
1381
        'data': json.loads('{"foo": "bar"}'),
1382
        'watch_rule_id': watch_rule.id
1383
    }
1384
    values.update(kwargs)
1385
    return db_api.watch_data_create(ctx, values)
1386
1387
1388
def create_service(ctx, **kwargs):
1389
    values = {
1390
        'id': '7079762f-c863-4954-ba61-9dccb68c57e2',
1391
        'engine_id': 'f9aff81e-bc1f-4119-941d-ad1ea7f31d19',
1392
        'host': 'engine-1',
1393
        'hostname': 'host1.devstack.org',
1394
        'binary': 'heat-engine',
1395
        'topic': 'engine',
1396
        'report_interval': 60}
1397
1398
    values.update(kwargs)
1399
    return db_api.service_create(ctx, values)
1400
1401
1402
def create_sync_point(ctx, **kwargs):
1403
    values = {'entity_id': '0782c463-064a-468d-98fd-442efb638e3a',
1404
              'is_update': True,
1405
              'traversal_id': '899ff81e-fc1f-41f9-f41d-ad1ea7f31d19',
1406
              'atomic_key': 0,
1407
              'stack_id': 'f6359498-764b-49e7-a515-ad31cbef885b',
1408
              'input_data': {}}
1409
    values.update(kwargs)
1410
    return db_api.sync_point_create(ctx, values)
1411
1412
1413
class DBAPIRawTemplateTest(common.HeatTestCase):
1414
    def setUp(self):
1415
        super(DBAPIRawTemplateTest, self).setUp()
1416
        self.ctx = utils.dummy_context()
1417
1418
    def test_raw_template_create(self):
1419
        t = template_format.parse(wp_template)
1420
        tp = create_raw_template(self.ctx, template=t)
1421
        self.assertIsNotNone(tp.id)
1422
        self.assertEqual(t, tp.template)
1423
        self.assertEqual({'foo': 'bar'}, tp.files)
1424
1425
    def test_raw_template_get(self):
1426
        t = template_format.parse(wp_template)
1427
        tp = create_raw_template(self.ctx, template=t)
1428
        template = db_api.raw_template_get(self.ctx, tp.id)
1429
        self.assertEqual(tp.id, template.id)
1430
        self.assertEqual(tp.template, template.template)
1431
1432
    def test_raw_template_update(self):
1433
        another_wp_template = '''
1434
        {
1435
          "AWSTemplateFormatVersion" : "2010-09-09",
1436
          "Description" : "WordPress",
1437
          "Parameters" : {
1438
            "KeyName" : {
1439
              "Description" : "KeyName",
1440
              "Type" : "String",
1441
              "Default" : "test"
1442
            }
1443
          },
1444
          "Resources" : {
1445
            "WebServer": {
1446
              "Type": "AWS::EC2::Instance",
1447
              "Properties": {
1448
                "ImageId" : "fedora-20.x86_64.qcow2",
1449
                "InstanceType"   : "m1.xlarge",
1450
                "KeyName"        : "test",
1451
                "UserData"       : "wordpress"
1452
              }
1453
            }
1454
          }
1455
        }
1456
        '''
1457
        new_t = template_format.parse(another_wp_template)
1458
        new_files = {
1459
            'foo': 'bar',
1460
            'myfile': 'file:///home/somefile'
1461
        }
1462
        new_values = {
1463
            'template': new_t,
1464
            'files': new_files
1465
        }
1466
        orig_tp = create_raw_template(self.ctx)
1467
        updated_tp = db_api.raw_template_update(self.ctx,
1468
                                                orig_tp.id, new_values)
1469
1470
        self.assertEqual(orig_tp.id, updated_tp.id)
1471
        self.assertEqual(new_t, updated_tp.template)
1472
        self.assertEqual(new_files, updated_tp.files)
1473
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
1474
    def test_raw_template_delete(self):
1475
        t = template_format.parse(wp_template)
1476
        tp = create_raw_template(self.ctx, template=t)
1477
        db_api.raw_template_delete(self.ctx, tp.id)
1478
        self.assertRaises(exception.NotFound, db_api.raw_template_get,
1479
                          self.ctx, tp.id)
1480
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
1481
1482
class DBAPIUserCredsTest(common.HeatTestCase):
1483
    def setUp(self):
1484
        super(DBAPIUserCredsTest, self).setUp()
1485
        self.ctx = utils.dummy_context()
1486
1487
    def test_user_creds_create_trust(self):
1488
        user_creds = create_user_creds(self.ctx, trust_id='test_trust_id',
1489
                                       trustor_user_id='trustor_id')
1490
        self.assertIsNotNone(user_creds.id)
1491
        self.assertEqual('test_trust_id',
1492
                         db_api._decrypt(user_creds.trust_id,
1493
                                         user_creds.decrypt_method))
1494
        self.assertEqual('trustor_id', user_creds.trustor_user_id)
1495
        self.assertIsNone(user_creds.username)
1496
        self.assertIsNone(user_creds.password)
1497
        self.assertEqual(self.ctx.tenant, user_creds.tenant)
1498
        self.assertEqual(self.ctx.tenant_id, user_creds.tenant_id)
1499
1500
    def test_user_creds_create_password(self):
1501
        user_creds = create_user_creds(self.ctx)
1502
        self.assertIsNotNone(user_creds.id)
1503
        self.assertEqual(self.ctx.password,
1504
                         db_api._decrypt(user_creds.password,
1505
                                         user_creds.decrypt_method))
1506
1507
    def test_user_creds_get(self):
1508
        user_creds = create_user_creds(self.ctx)
1509
        ret_user_creds = db_api.user_creds_get(user_creds.id)
1510
        self.assertEqual(db_api._decrypt(user_creds.password,
1511
                                         user_creds.decrypt_method),
1512
                         ret_user_creds['password'])
1513
1514
    def test_user_creds_get_noexist(self):
1515
        self.assertIsNone(db_api.user_creds_get(123456))
1516
1517
    def test_user_creds_delete(self):
1518
        user_creds = create_user_creds(self.ctx)
1519
        self.assertIsNotNone(user_creds.id)
1520
        db_api.user_creds_delete(self.ctx, user_creds.id)
1521
        creds = db_api.user_creds_get(user_creds.id)
1522
        self.assertIsNone(creds)
1523
        err = self.assertRaises(
1524
            exception.NotFound, db_api.user_creds_delete,
1525
            self.ctx, user_creds.id)
1526
        exp_msg = ('Attempt to delete user creds with id '
1527
                   '%s that does not exist' % user_creds.id)
1528
        self.assertIn(exp_msg, six.text_type(err))
1529
1530
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
1531
class DBAPIStackTagTest(common.HeatTestCase):
1532
    def setUp(self):
1533
        super(DBAPIStackTagTest, self).setUp()
1534
        self.ctx = utils.dummy_context()
1535
        self.template = create_raw_template(self.ctx)
1536
        self.user_creds = create_user_creds(self.ctx)
1537
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
1538
1539
    def test_stack_tags_set(self):
1540
        tags = db_api.stack_tags_set(self.ctx, self.stack.id, ['tag1', 'tag2'])
1541
        self.assertEqual(self.stack.id, tags[0].stack_id)
1542
        self.assertEqual('tag1', tags[0].tag)
1543
1544
        tags = db_api.stack_tags_set(self.ctx, self.stack.id, [])
1545
        self.assertIsNone(tags)
1546
1547
    def test_stack_tags_get(self):
1548
        db_api.stack_tags_set(self.ctx, self.stack.id, ['tag1', 'tag2'])
1549
        tags = db_api.stack_tags_get(self.ctx, self.stack.id)
1550
        self.assertEqual(self.stack.id, tags[0].stack_id)
1551
        self.assertEqual('tag1', tags[0].tag)
1552
1553
        tags = db_api.stack_tags_get(self.ctx, UUID1)
1554
        self.assertIsNone(tags)
1555
1556
    def test_stack_tags_delete(self):
1557
        db_api.stack_tags_set(self.ctx, self.stack.id, ['tag1', 'tag2'])
1558
        db_api.stack_tags_delete(self.ctx, self.stack.id)
1559
        tags = db_api.stack_tags_get(self.ctx, self.stack.id)
1560
        self.assertIsNone(tags)
1561
1562
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
1563
class DBAPIStackTest(common.HeatTestCase):
1564
    def setUp(self):
1565
        super(DBAPIStackTest, self).setUp()
1566
        self.ctx = utils.dummy_context()
1567
        self.template = create_raw_template(self.ctx)
1568
        self.user_creds = create_user_creds(self.ctx)
1569
1570
    def test_stack_create(self):
1571
        stack = create_stack(self.ctx, self.template, self.user_creds)
1572
        self.assertIsNotNone(stack.id)
1573
        self.assertEqual('db_test_stack_name', stack.name)
1574
        self.assertEqual(self.template.id, stack.raw_template_id)
1575
        self.assertEqual(self.ctx.username, stack.username)
1576
        self.assertEqual(self.ctx.tenant_id, stack.tenant)
1577
        self.assertEqual('create', stack.action)
1578
        self.assertEqual('complete', stack.status)
1579
        self.assertEqual('create_complete', stack.status_reason)
1580
        self.assertEqual({}, stack.parameters)
1581
        self.assertEqual(self.user_creds.id, stack.user_creds_id)
1582
        self.assertIsNone(stack.owner_id)
1583
        self.assertEqual('60', stack.timeout)
1584
        self.assertFalse(stack.disable_rollback)
1585
1586
    def test_stack_delete(self):
1587
        stack = create_stack(self.ctx, self.template, self.user_creds)
1588
        stack_id = stack.id
1589
        resource = create_resource(self.ctx, stack)
1590
        db_api.stack_delete(self.ctx, stack_id)
1591
        self.assertIsNone(db_api.stack_get(self.ctx, stack_id,
1592
                                           show_deleted=False))
1593
        self.assertRaises(exception.NotFound, db_api.resource_get,
1594
                          self.ctx, resource.id)
1595
1596
        self.assertRaises(exception.NotFound, db_api.stack_delete,
1597
                          self.ctx, stack_id)
1598
1599
        # Testing soft delete
1600
        ret_stack = db_api.stack_get(self.ctx, stack_id, show_deleted=True)
1601
        self.assertIsNotNone(ret_stack)
1602
        self.assertEqual(stack_id, ret_stack.id)
1603
        self.assertEqual('db_test_stack_name', ret_stack.name)
1604
1605
        # Testing child resources deletion
1606
        self.assertRaises(exception.NotFound, db_api.resource_get,
1607
                          self.ctx, resource.id)
1608
1609
    def test_stack_update(self):
1610
        stack = create_stack(self.ctx, self.template, self.user_creds)
1611
        values = {
1612
            'name': 'db_test_stack_name2',
1613
            'action': 'update',
1614
            'status': 'failed',
1615
            'status_reason': "update_failed",
1616
            'timeout': '90',
1617
            'current_traversal': 'dummy-uuid',
1618
        }
1619
        db_api.stack_update(self.ctx, stack.id, values)
1620
        stack = db_api.stack_get(self.ctx, stack.id)
1621
        self.assertEqual('db_test_stack_name2', stack.name)
1622
        self.assertEqual('update', stack.action)
1623
        self.assertEqual('failed', stack.status)
1624
        self.assertEqual('update_failed', stack.status_reason)
1625
        self.assertEqual(90, stack.timeout)
1626
        self.assertEqual('dummy-uuid', stack.current_traversal)
1627
1628
        self.assertRaises(exception.NotFound, db_api.stack_update, self.ctx,
1629
                          UUID2, values)
1630
1631
    def test_stack_get_returns_a_stack(self):
1632
        stack = create_stack(self.ctx, self.template, self.user_creds)
1633
        ret_stack = db_api.stack_get(self.ctx, stack.id, show_deleted=False)
1634
        self.assertIsNotNone(ret_stack)
1635
        self.assertEqual(stack.id, ret_stack.id)
1636
        self.assertEqual('db_test_stack_name', ret_stack.name)
1637
1638
    def test_stack_get_returns_none_if_stack_does_not_exist(self):
1639
        stack = db_api.stack_get(self.ctx, UUID1, show_deleted=False)
1640
        self.assertIsNone(stack)
1641
1642
    def test_stack_get_returns_none_if_tenant_id_does_not_match(self):
1643
        stack = create_stack(self.ctx, self.template, self.user_creds)
1644
        self.ctx.tenant_id = 'abc'
1645
        stack = db_api.stack_get(self.ctx, UUID1, show_deleted=False)
1646
        self.assertIsNone(stack)
1647
1648
    def test_stack_get_tenant_is_stack_user_project_id(self):
1649
        stack = create_stack(self.ctx, self.template, self.user_creds,
1650
                             stack_user_project_id='astackuserproject')
1651
        self.ctx.tenant_id = 'astackuserproject'
1652
        ret_stack = db_api.stack_get(self.ctx, stack.id, show_deleted=False)
1653
        self.assertIsNotNone(ret_stack)
1654
        self.assertEqual(stack.id, ret_stack.id)
1655
        self.assertEqual('db_test_stack_name', ret_stack.name)
1656
1657
    def test_stack_get_can_return_a_stack_from_different_tenant(self):
1658
        stack = create_stack(self.ctx, self.template, self.user_creds)
1659
        self.ctx.tenant_id = 'abc'
1660
        ret_stack = db_api.stack_get(self.ctx, stack.id,
1661
                                     show_deleted=False, tenant_safe=False)
1662
        self.assertEqual(stack.id, ret_stack.id)
1663
        self.assertEqual('db_test_stack_name', ret_stack.name)
1664
1665
    def test_stack_get_by_name(self):
1666
        stack = create_stack(self.ctx, self.template, self.user_creds)
1667
        ret_stack = db_api.stack_get_by_name(self.ctx, stack.name)
1668
        self.assertIsNotNone(ret_stack)
1669
        self.assertEqual(stack.id, ret_stack.id)
1670
        self.assertEqual('db_test_stack_name', ret_stack.name)
1671
1672
        self.assertIsNone(db_api.stack_get_by_name(self.ctx, 'abc'))
1673
1674
        self.ctx.tenant_id = 'abc'
1675
        self.assertIsNone(db_api.stack_get_by_name(self.ctx, 'abc'))
1676
1677
    def test_stack_get_all(self):
1678
        values = [
1679
            {'name': 'stack1'},
1680
            {'name': 'stack2'},
1681
            {'name': 'stack3'},
1682
            {'name': 'stack4'}
1683
        ]
1684
        [create_stack(self.ctx, self.template, self.user_creds,
1685
                      **val) for val in values]
1686
1687
        ret_stacks = db_api.stack_get_all(self.ctx)
1688
        self.assertEqual(4, len(ret_stacks))
1689
        names = [ret_stack.name for ret_stack in ret_stacks]
1690
        [self.assertIn(val['name'], names) for val in values]
1691
1692
    def test_stack_get_all_by_owner_id(self):
1693
        parent_stack1 = create_stack(self.ctx, self.template, self.user_creds)
1694
        parent_stack2 = create_stack(self.ctx, self.template, self.user_creds)
1695
        values = [
1696
            {'owner_id': parent_stack1.id},
1697
            {'owner_id': parent_stack1.id},
1698
            {'owner_id': parent_stack2.id},
1699
            {'owner_id': parent_stack2.id},
1700
        ]
1701
        [create_stack(self.ctx, self.template, self.user_creds,
1702
                      **val) for val in values]
1703
1704
        stack1_children = db_api.stack_get_all_by_owner_id(self.ctx,
1705
                                                           parent_stack1.id)
1706
        self.assertEqual(2, len(stack1_children))
1707
        stack2_children = db_api.stack_get_all_by_owner_id(self.ctx,
1708
                                                           parent_stack2.id)
1709
        self.assertEqual(2, len(stack2_children))
1710
1711
    def test_stack_get_all_with_regular_tenant(self):
1712
        values = [
1713
            {'tenant': UUID1},
1714
            {'tenant': UUID1},
1715
            {'tenant': UUID2},
1716
            {'tenant': UUID2},
1717
            {'tenant': UUID2},
1718
        ]
1719
        [create_stack(self.ctx, self.template, self.user_creds,
1720
                      **val) for val in values]
1721
1722
        self.ctx.tenant_id = UUID1
1723
        stacks = db_api.stack_get_all(self.ctx)
1724
        self.assertEqual(2, len(stacks))
1725
1726
        self.ctx.tenant_id = UUID2
1727
        stacks = db_api.stack_get_all(self.ctx)
1728
        self.assertEqual(3, len(stacks))
1729
1730
        self.ctx.tenant_id = UUID3
1731
        self.assertEqual([], db_api.stack_get_all(self.ctx))
1732
1733
    def test_stack_get_all_with_tenant_safe_false(self):
1734
        values = [
1735
            {'tenant': UUID1},
1736
            {'tenant': UUID1},
1737
            {'tenant': UUID2},
1738
            {'tenant': UUID2},
1739
            {'tenant': UUID2},
1740
        ]
1741
        [create_stack(self.ctx, self.template, self.user_creds,
1742
                      **val) for val in values]
1743
1744
        stacks = db_api.stack_get_all(self.ctx, tenant_safe=False)
1745
        self.assertEqual(5, len(stacks))
1746
1747
    def test_stack_count_all_with_regular_tenant(self):
1748
        values = [
1749
            {'tenant': UUID1},
1750
            {'tenant': UUID1},
1751
            {'tenant': UUID2},
1752
            {'tenant': UUID2},
1753
            {'tenant': UUID2},
1754
        ]
1755
        [create_stack(self.ctx, self.template, self.user_creds,
1756
                      **val) for val in values]
1757
1758
        self.ctx.tenant_id = UUID1
1759
        self.assertEqual(2, db_api.stack_count_all(self.ctx))
1760
1761
        self.ctx.tenant_id = UUID2
1762
        self.assertEqual(3, db_api.stack_count_all(self.ctx))
1763
1764
    def test_stack_count_all_with_tenant_safe_false(self):
1765
        values = [
1766
            {'tenant': UUID1},
1767
            {'tenant': UUID1},
1768
            {'tenant': UUID2},
1769
            {'tenant': UUID2},
1770
            {'tenant': UUID2},
1771
        ]
1772
        [create_stack(self.ctx, self.template, self.user_creds,
1773
                      **val) for val in values]
1774
1775
        self.assertEqual(5,
1776
                         db_api.stack_count_all(self.ctx, tenant_safe=False))
1777
1778
    def test_purge_deleted(self):
1779
        now = datetime.datetime.now()
1780
        delta = datetime.timedelta(seconds=3600 * 7)
1781
        deleted = [now - delta * i for i in range(1, 6)]
1782
        templates = [create_raw_template(self.ctx) for i in range(5)]
1783
        creds = [create_user_creds(self.ctx) for i in range(5)]
1784
        stacks = [create_stack(self.ctx, templates[i], creds[i],
1785
                               deleted_at=deleted[i]) for i in range(5)]
1786
1787
        db_api.purge_deleted(age=1, granularity='days')
1788
        self._deleted_stack_existance(utils.dummy_context(), stacks,
1789
                                      (0, 1, 2), (3, 4))
1790
1791
        db_api.purge_deleted(age=22, granularity='hours')
1792
        self._deleted_stack_existance(utils.dummy_context(), stacks,
1793
                                      (0, 1, 2), (3, 4))
1794
1795
        db_api.purge_deleted(age=1100, granularity='minutes')
1796
        self._deleted_stack_existance(utils.dummy_context(), stacks,
1797
                                      (0, 1), (2, 3, 4))
1798
1799
        db_api.purge_deleted(age=3600, granularity='seconds')
1800
        self._deleted_stack_existance(utils.dummy_context(), stacks,
1801
                                      (), (0, 1, 2, 3, 4))
1802
1803
    def _deleted_stack_existance(self, ctx, stacks, existing, deleted):
1804
        for s in existing:
1805
            self.assertIsNotNone(db_api.stack_get(ctx, stacks[s].id,
1806
                                                  show_deleted=True))
1807
        for s in deleted:
1808
            self.assertIsNone(db_api.stack_get(ctx, stacks[s].id,
1809
                                               show_deleted=True))
1810
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
1811
    def test_stack_get_root_id(self):
1812
        root = create_stack(self.ctx, self.template, self.user_creds,
1813
                            name='root stack')
1814
        child_1 = create_stack(self.ctx, self.template, self.user_creds,
1815
                               name='child 1 stack', owner_id=root.id)
1816
        child_2 = create_stack(self.ctx, self.template, self.user_creds,
1817
                               name='child 2 stack', owner_id=child_1.id)
1818
        child_3 = create_stack(self.ctx, self.template, self.user_creds,
1819
                               name='child 3 stack', owner_id=child_2.id)
1820
1821
        self.assertEqual(root.id, db_api.stack_get_root_id(
1822
            self.ctx, child_3.id))
1823
        self.assertEqual(root.id, db_api.stack_get_root_id(
1824
            self.ctx, child_2.id))
1825
        self.assertEqual(root.id, db_api.stack_get_root_id(
1826
            self.ctx, root.id))
1827
        self.assertEqual(root.id, db_api.stack_get_root_id(
1828
            self.ctx, child_1.id))
1829
1830
    def test_stack_count_total_resources(self):
1831
1832
        def add_resources(stack, count):
1833
            for i in range(count):
1834
                create_resource(
1835
                    self.ctx, stack, name='%s-%s' % (stack.name, i))
1836
1837
        root = create_stack(self.ctx, self.template, self.user_creds,
1838
                            name='root stack')
1839
1840
        # stack with 3 children
1841
        s_1 = create_stack(self.ctx, self.template, self.user_creds,
1842
                           name='s_1', owner_id=root.id)
1843
        s_1_1 = create_stack(self.ctx, self.template, self.user_creds,
1844
                             name='s_1_1', owner_id=s_1.id)
1845
        s_1_2 = create_stack(self.ctx, self.template, self.user_creds,
1846
                             name='s_1_2', owner_id=s_1.id)
1847
        s_1_3 = create_stack(self.ctx, self.template, self.user_creds,
1848
                             name='s_1_3', owner_id=s_1.id)
1849
1850
        # stacks 4 ancestors deep
1851
        s_2 = create_stack(self.ctx, self.template, self.user_creds,
1852
                           name='s_2', owner_id=root.id)
1853
        s_2_1 = create_stack(self.ctx, self.template, self.user_creds,
1854
                             name='s_2_1', owner_id=s_2.id)
1855
        s_2_1_1 = create_stack(self.ctx, self.template, self.user_creds,
1856
                               name='s_2_1_1', owner_id=s_2_1.id)
1857
        s_2_1_1_1 = create_stack(self.ctx, self.template, self.user_creds,
1858
                                 name='s_2_1_1_1', owner_id=s_2_1_1.id)
1859
1860
        s_3 = create_stack(self.ctx, self.template, self.user_creds,
1861
                           name='s_3', owner_id=root.id)
1862
        s_4 = create_stack(self.ctx, self.template, self.user_creds,
1863
                           name='s_4', owner_id=root.id)
1864
1865
        add_resources(root, 3)
1866
        add_resources(s_1, 2)
1867
        add_resources(s_1_1, 4)
1868
        add_resources(s_1_2, 5)
1869
        add_resources(s_1_3, 6)
1870
1871
        add_resources(s_2, 1)
1872
        add_resources(s_2_1_1_1, 1)
1873
        add_resources(s_3, 4)
1874
1875
        self.assertEqual(26, db_api.stack_count_total_resources(
1876
            self.ctx, root.id))
1877
1878
        self.assertEqual(17, db_api.stack_count_total_resources(
1879
            self.ctx, s_1.id))
1880
        self.assertEqual(4, db_api.stack_count_total_resources(
1881
            self.ctx, s_1_1.id))
1882
        self.assertEqual(5, db_api.stack_count_total_resources(
1883
            self.ctx, s_1_2.id))
1884
        self.assertEqual(6, db_api.stack_count_total_resources(
1885
            self.ctx, s_1_3.id))
1886
1887
        self.assertEqual(2, db_api.stack_count_total_resources(
1888
            self.ctx, s_2.id))
1889
        self.assertEqual(1, db_api.stack_count_total_resources(
1890
            self.ctx, s_2_1.id))
1891
        self.assertEqual(1, db_api.stack_count_total_resources(
1892
            self.ctx, s_2_1_1.id))
1893
        self.assertEqual(1, db_api.stack_count_total_resources(
1894
            self.ctx, s_2_1_1_1.id))
1895
        self.assertEqual(4, db_api.stack_count_total_resources(
1896
            self.ctx, s_3.id))
1897
        self.assertEqual(0, db_api.stack_count_total_resources(
1898
            self.ctx, s_4.id))
1899
        self.assertEqual(0, db_api.stack_count_total_resources(
1900
            self.ctx, 'asdf'))
1901
        self.assertEqual(0, db_api.stack_count_total_resources(
1902
            self.ctx, None))
1903
1.1.24 by Chuck Short
Import upstream version 2015.1~rc1
1904
1905
class DBAPIResourceTest(common.HeatTestCase):
1906
    def setUp(self):
1907
        super(DBAPIResourceTest, self).setUp()
1908
        self.ctx = utils.dummy_context()
1909
        self.template = create_raw_template(self.ctx)
1910
        self.user_creds = create_user_creds(self.ctx)
1911
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
1912
1913
    def test_resource_create(self):
1914
        res = create_resource(self.ctx, self.stack)
1915
        ret_res = db_api.resource_get(self.ctx, res.id)
1916
        self.assertIsNotNone(ret_res)
1917
        self.assertEqual('test_resource_name', ret_res.name)
1918
        self.assertEqual(UUID1, ret_res.nova_instance)
1919
        self.assertEqual('create', ret_res.action)
1920
        self.assertEqual('complete', ret_res.status)
1921
        self.assertEqual('create_complete', ret_res.status_reason)
1922
        self.assertEqual('{"foo": "123"}', json.dumps(ret_res.rsrc_metadata))
1923
        self.assertEqual(self.stack.id, ret_res.stack_id)
1924
1925
    def test_resource_get(self):
1926
        res = create_resource(self.ctx, self.stack)
1927
        ret_res = db_api.resource_get(self.ctx, res.id)
1928
        self.assertIsNotNone(ret_res)
1929
1930
        self.assertRaises(exception.NotFound, db_api.resource_get,
1931
                          self.ctx, UUID2)
1932
1933
    def test_resource_get_by_name_and_stack(self):
1934
        create_resource(self.ctx, self.stack)
1935
1936
        ret_res = db_api.resource_get_by_name_and_stack(self.ctx,
1937
                                                        'test_resource_name',
1938
                                                        self.stack.id)
1939
1940
        self.assertIsNotNone(ret_res)
1941
        self.assertEqual('test_resource_name', ret_res.name)
1942
        self.assertEqual(self.stack.id, ret_res.stack_id)
1943
1944
        self.assertIsNone(db_api.resource_get_by_name_and_stack(self.ctx,
1945
                                                                'abc',
1946
                                                                self.stack.id))
1947
1948
    def test_resource_get_by_physical_resource_id(self):
1949
        create_resource(self.ctx, self.stack)
1950
1951
        ret_res = db_api.resource_get_by_physical_resource_id(self.ctx, UUID1)
1952
        self.assertIsNotNone(ret_res)
1953
        self.assertEqual(UUID1, ret_res.nova_instance)
1954
1955
        self.assertIsNone(db_api.resource_get_by_physical_resource_id(self.ctx,
1956
                                                                      UUID2))
1957
1958
    def test_resource_get_all(self):
1959
        values = [
1960
            {'name': 'res1'},
1961
            {'name': 'res2'},
1962
            {'name': 'res3'},
1963
        ]
1964
        [create_resource(self.ctx, self.stack, **val) for val in values]
1965
1966
        resources = db_api.resource_get_all(self.ctx)
1967
        self.assertEqual(3, len(resources))
1968
1969
        names = [resource.name for resource in resources]
1970
        [self.assertIn(val['name'], names) for val in values]
1971
1972
    def test_resource_get_all_by_stack(self):
1973
        self.stack1 = create_stack(self.ctx, self.template, self.user_creds)
1974
        self.stack2 = create_stack(self.ctx, self.template, self.user_creds)
1975
        values = [
1976
            {'name': 'res1', 'stack_id': self.stack.id},
1977
            {'name': 'res2', 'stack_id': self.stack.id},
1978
            {'name': 'res3', 'stack_id': self.stack1.id},
1979
        ]
1980
        [create_resource(self.ctx, self.stack, **val) for val in values]
1981
1982
        resources = db_api.resource_get_all_by_stack(self.ctx, self.stack.id)
1983
        self.assertEqual(2, len(resources))
1984
        self.assertEqual('res1', resources.get('res1').name)
1985
        self.assertEqual('res2', resources.get('res2').name)
1986
1987
        self.assertRaises(exception.NotFound, db_api.resource_get_all_by_stack,
1988
                          self.ctx, self.stack2.id)
1989
1990
1991
class DBAPIStackLockTest(common.HeatTestCase):
1992
    def setUp(self):
1993
        super(DBAPIStackLockTest, self).setUp()
1994
        self.ctx = utils.dummy_context()
1995
        self.template = create_raw_template(self.ctx)
1996
        self.user_creds = create_user_creds(self.ctx)
1997
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
1998
1999
    def test_stack_lock_create_success(self):
2000
        observed = db_api.stack_lock_create(self.stack.id, UUID1)
2001
        self.assertIsNone(observed)
2002
2003
    def test_stack_lock_create_fail_double_same(self):
2004
        db_api.stack_lock_create(self.stack.id, UUID1)
2005
        observed = db_api.stack_lock_create(self.stack.id, UUID1)
2006
        self.assertEqual(UUID1, observed)
2007
2008
    def test_stack_lock_create_fail_double_different(self):
2009
        db_api.stack_lock_create(self.stack.id, UUID1)
2010
        observed = db_api.stack_lock_create(self.stack.id, UUID2)
2011
        self.assertEqual(UUID1, observed)
2012
2013
    def test_stack_lock_get_id_success(self):
2014
        db_api.stack_lock_create(self.stack.id, UUID1)
2015
        observed = db_api.stack_lock_get_engine_id(self.stack.id)
2016
        self.assertEqual(UUID1, observed)
2017
2018
    def test_stack_lock_get_id_return_none(self):
2019
        observed = db_api.stack_lock_get_engine_id(self.stack.id)
2020
        self.assertIsNone(observed)
2021
2022
    def test_stack_lock_steal_success(self):
2023
        db_api.stack_lock_create(self.stack.id, UUID1)
2024
        observed = db_api.stack_lock_steal(self.stack.id, UUID1, UUID2)
2025
        self.assertIsNone(observed)
2026
2027
    def test_stack_lock_steal_fail_gone(self):
2028
        db_api.stack_lock_create(self.stack.id, UUID1)
2029
        db_api.stack_lock_release(self.stack.id, UUID1)
2030
        observed = db_api.stack_lock_steal(self.stack.id, UUID1, UUID2)
2031
        self.assertTrue(observed)
2032
2033
    def test_stack_lock_steal_fail_stolen(self):
2034
        db_api.stack_lock_create(self.stack.id, UUID1)
2035
2036
        # Simulate stolen lock
2037
        db_api.stack_lock_release(self.stack.id, UUID1)
2038
        db_api.stack_lock_create(self.stack.id, UUID2)
2039
2040
        observed = db_api.stack_lock_steal(self.stack.id, UUID3, UUID2)
2041
        self.assertEqual(UUID2, observed)
2042
2043
    def test_stack_lock_release_success(self):
2044
        db_api.stack_lock_create(self.stack.id, UUID1)
2045
        observed = db_api.stack_lock_release(self.stack.id, UUID1)
2046
        self.assertIsNone(observed)
2047
2048
    def test_stack_lock_release_fail_double(self):
2049
        db_api.stack_lock_create(self.stack.id, UUID1)
2050
        db_api.stack_lock_release(self.stack.id, UUID1)
2051
        observed = db_api.stack_lock_release(self.stack.id, UUID1)
2052
        self.assertTrue(observed)
2053
2054
    def test_stack_lock_release_fail_wrong_engine_id(self):
2055
        db_api.stack_lock_create(self.stack.id, UUID1)
2056
        observed = db_api.stack_lock_release(self.stack.id, UUID2)
2057
        self.assertTrue(observed)
2058
2059
2060
class DBAPIResourceDataTest(common.HeatTestCase):
2061
    def setUp(self):
2062
        super(DBAPIResourceDataTest, self).setUp()
2063
        self.ctx = utils.dummy_context()
2064
        self.template = create_raw_template(self.ctx)
2065
        self.user_creds = create_user_creds(self.ctx)
2066
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
2067
        self.resource = create_resource(self.ctx, self.stack)
2068
        self.resource.context = self.ctx
2069
2070
    def test_resource_data_set_get(self):
2071
        create_resource_data(self.ctx, self.resource)
2072
        val = db_api.resource_data_get(self.resource, 'test_resource_key')
2073
        self.assertEqual('test_value', val)
2074
2075
        # Updating existing resource data
2076
        create_resource_data(self.ctx, self.resource, value='foo')
2077
        val = db_api.resource_data_get(self.resource, 'test_resource_key')
2078
        self.assertEqual('foo', val)
2079
2080
        # Testing with encrypted value
2081
        create_resource_data(self.ctx, self.resource,
2082
                             key='encryped_resource_key', redact=True)
2083
        val = db_api.resource_data_get(self.resource, 'encryped_resource_key')
2084
        self.assertEqual('test_value', val)
2085
2086
        # get all by querying for data
2087
        vals = db_api.resource_data_get_all(self.resource)
2088
        self.assertEqual(2, len(vals))
2089
        self.assertEqual('foo', vals.get('test_resource_key'))
2090
        self.assertEqual('test_value', vals.get('encryped_resource_key'))
2091
2092
        # get all by using associated resource data
2093
        vals = db_api.resource_data_get_all(None, self.resource.data)
2094
        self.assertEqual(2, len(vals))
2095
        self.assertEqual('foo', vals.get('test_resource_key'))
2096
        self.assertEqual('test_value', vals.get('encryped_resource_key'))
2097
2098
    def test_resource_data_delete(self):
2099
        create_resource_data(self.ctx, self.resource)
2100
        res_data = db_api.resource_data_get_by_key(self.ctx, self.resource.id,
2101
                                                   'test_resource_key')
2102
        self.assertIsNotNone(res_data)
2103
        self.assertEqual('test_value', res_data.value)
2104
2105
        db_api.resource_data_delete(self.resource, 'test_resource_key')
2106
        self.assertRaises(exception.NotFound, db_api.resource_data_get_by_key,
2107
                          self.ctx, self.resource.id, 'test_resource_key')
2108
        self.assertIsNotNone(res_data)
2109
2110
2111
class DBAPIEventTest(common.HeatTestCase):
2112
    def setUp(self):
2113
        super(DBAPIEventTest, self).setUp()
2114
        self.ctx = utils.dummy_context()
2115
        self.template = create_raw_template(self.ctx)
2116
        self.user_creds = create_user_creds(self.ctx)
2117
2118
    def test_event_create_get(self):
2119
        event = create_event(self.ctx)
2120
        ret_event = db_api.event_get(self.ctx, event.id)
2121
        self.assertIsNotNone(ret_event)
2122
        self.assertEqual('test_stack_id', ret_event.stack_id)
2123
        self.assertEqual('create', ret_event.resource_action)
2124
        self.assertEqual('complete', ret_event.resource_status)
2125
        self.assertEqual('res', ret_event.resource_name)
2126
        self.assertEqual(UUID1, ret_event.physical_resource_id)
2127
        self.assertEqual('create_complete', ret_event.resource_status_reason)
2128
        self.assertEqual({'name': 'foo'}, ret_event.resource_properties)
2129
2130
    def test_event_get_all(self):
2131
        self.stack1 = create_stack(self.ctx, self.template, self.user_creds,
2132
                                   tenant='tenant1')
2133
        self.stack2 = create_stack(self.ctx, self.template, self.user_creds,
2134
                                   tenant='tenant2')
2135
        values = [
2136
            {'stack_id': self.stack1.id, 'resource_name': 'res1'},
2137
            {'stack_id': self.stack1.id, 'resource_name': 'res2'},
2138
            {'stack_id': self.stack2.id, 'resource_name': 'res3'},
2139
        ]
2140
        [create_event(self.ctx, **val) for val in values]
2141
2142
        events = db_api.event_get_all(self.ctx)
2143
        self.assertEqual(3, len(events))
2144
2145
        stack_ids = [event.stack_id for event in events]
2146
        res_names = [event.resource_name for event in events]
2147
        [(self.assertIn(val['stack_id'], stack_ids),
2148
          self.assertIn(val['resource_name'], res_names)) for val in values]
2149
2150
    def test_event_get_all_by_tenant(self):
2151
        self.stack1 = create_stack(self.ctx, self.template, self.user_creds,
2152
                                   tenant='tenant1')
2153
        self.stack2 = create_stack(self.ctx, self.template, self.user_creds,
2154
                                   tenant='tenant2')
2155
        values = [
2156
            {'stack_id': self.stack1.id, 'resource_name': 'res1'},
2157
            {'stack_id': self.stack1.id, 'resource_name': 'res2'},
2158
            {'stack_id': self.stack2.id, 'resource_name': 'res3'},
2159
        ]
2160
        [create_event(self.ctx, **val) for val in values]
2161
2162
        self.ctx.tenant_id = 'tenant1'
2163
        events = db_api.event_get_all_by_tenant(self.ctx)
2164
        self.assertEqual(2, len(events))
2165
        marker = events[0].uuid
2166
        expected = events[1].uuid
2167
        events = db_api.event_get_all_by_tenant(self.ctx,
2168
                                                marker=marker)
2169
        self.assertEqual(1, len(events))
2170
        self.assertEqual(expected, events[0].uuid)
2171
2172
        events = db_api.event_get_all_by_tenant(self.ctx, limit=1)
2173
        self.assertEqual(1, len(events))
2174
2175
        filters = {'resource_name': 'res2'}
2176
        events = db_api.event_get_all_by_tenant(self.ctx,
2177
                                                filters=filters)
2178
        self.assertEqual(1, len(events))
2179
        self.assertEqual('res2', events[0].resource_name)
2180
2181
        sort_keys = 'resource_type'
2182
        events = db_api.event_get_all_by_tenant(self.ctx,
2183
                                                sort_keys=sort_keys)
2184
        self.assertEqual(2, len(events))
2185
2186
        self.ctx.tenant_id = 'tenant2'
2187
        events = db_api.event_get_all_by_tenant(self.ctx)
2188
        self.assertEqual(1, len(events))
2189
2190
    def test_event_get_all_by_stack(self):
2191
        self.stack1 = create_stack(self.ctx, self.template, self.user_creds)
2192
        self.stack2 = create_stack(self.ctx, self.template, self.user_creds)
2193
        values = [
2194
            {'stack_id': self.stack1.id, 'resource_name': 'res1'},
2195
            {'stack_id': self.stack1.id, 'resource_name': 'res2'},
2196
            {'stack_id': self.stack2.id, 'resource_name': 'res3'},
2197
        ]
2198
        [create_event(self.ctx, **val) for val in values]
2199
2200
        self.ctx.tenant_id = 'tenant1'
2201
        events = db_api.event_get_all_by_stack(self.ctx, self.stack1.id)
2202
        self.assertEqual(2, len(events))
2203
2204
        self.ctx.tenant_id = 'tenant2'
2205
        events = db_api.event_get_all_by_stack(self.ctx, self.stack2.id)
2206
        self.assertEqual(1, len(events))
2207
2208
    def test_event_count_all_by_stack(self):
2209
        self.stack1 = create_stack(self.ctx, self.template, self.user_creds)
2210
        self.stack2 = create_stack(self.ctx, self.template, self.user_creds)
2211
        values = [
2212
            {'stack_id': self.stack1.id, 'resource_name': 'res1'},
2213
            {'stack_id': self.stack1.id, 'resource_name': 'res2'},
2214
            {'stack_id': self.stack2.id, 'resource_name': 'res3'},
2215
        ]
2216
        [create_event(self.ctx, **val) for val in values]
2217
2218
        self.assertEqual(2, db_api.event_count_all_by_stack(self.ctx,
2219
                                                            self.stack1.id))
2220
2221
        self.assertEqual(1, db_api.event_count_all_by_stack(self.ctx,
2222
                                                            self.stack2.id))
2223
2224
2225
class DBAPIWatchRuleTest(common.HeatTestCase):
2226
    def setUp(self):
2227
        super(DBAPIWatchRuleTest, self).setUp()
2228
        self.ctx = utils.dummy_context()
2229
        self.template = create_raw_template(self.ctx)
2230
        self.user_creds = create_user_creds(self.ctx)
2231
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
2232
2233
    def test_watch_rule_create_get(self):
2234
        watch_rule = create_watch_rule(self.ctx, self.stack)
2235
        ret_wr = db_api.watch_rule_get(self.ctx, watch_rule.id)
2236
        self.assertIsNotNone(ret_wr)
2237
        self.assertEqual('test_rule', ret_wr.name)
2238
        self.assertEqual('{"foo": "123"}', json.dumps(ret_wr.rule))
2239
        self.assertEqual('normal', ret_wr.state)
2240
        self.assertEqual(self.stack.id, ret_wr.stack_id)
2241
2242
    def test_watch_rule_get_by_name(self):
2243
        watch_rule = create_watch_rule(self.ctx, self.stack)
2244
        ret_wr = db_api.watch_rule_get_by_name(self.ctx, watch_rule.name)
2245
        self.assertIsNotNone(ret_wr)
2246
        self.assertEqual('test_rule', ret_wr.name)
2247
2248
    def test_watch_rule_get_all(self):
2249
        values = [
2250
            {'name': 'rule1'},
2251
            {'name': 'rule2'},
2252
            {'name': 'rule3'},
2253
        ]
2254
        [create_watch_rule(self.ctx, self.stack, **val) for val in values]
2255
2256
        wrs = db_api.watch_rule_get_all(self.ctx)
2257
        self.assertEqual(3, len(wrs))
2258
2259
        names = [wr.name for wr in wrs]
2260
        [self.assertIn(val['name'], names) for val in values]
2261
2262
    def test_watch_rule_get_all_by_stack(self):
2263
        self.stack1 = create_stack(self.ctx, self.template, self.user_creds)
2264
2265
        values = [
2266
            {'name': 'rule1', 'stack_id': self.stack.id},
2267
            {'name': 'rule2', 'stack_id': self.stack1.id},
2268
            {'name': 'rule3', 'stack_id': self.stack1.id},
2269
        ]
2270
        [create_watch_rule(self.ctx, self.stack, **val) for val in values]
2271
2272
        wrs = db_api.watch_rule_get_all_by_stack(self.ctx, self.stack.id)
2273
        self.assertEqual(1, len(wrs))
2274
        wrs = db_api.watch_rule_get_all_by_stack(self.ctx, self.stack1.id)
2275
        self.assertEqual(2, len(wrs))
2276
2277
    def test_watch_rule_update(self):
2278
        watch_rule = create_watch_rule(self.ctx, self.stack)
2279
        values = {
2280
            'name': 'test_rule_1',
2281
            'rule': json.loads('{"foo": "bar"}'),
2282
            'state': 'nodata',
2283
        }
2284
        db_api.watch_rule_update(self.ctx, watch_rule.id, values)
2285
        watch_rule = db_api.watch_rule_get(self.ctx, watch_rule.id)
2286
        self.assertEqual('test_rule_1', watch_rule.name)
2287
        self.assertEqual('{"foo": "bar"}', json.dumps(watch_rule.rule))
2288
        self.assertEqual('nodata', watch_rule.state)
2289
2290
        self.assertRaises(exception.NotFound, db_api.watch_rule_update,
2291
                          self.ctx, UUID2, values)
2292
2293
    def test_watch_rule_delete(self):
2294
        watch_rule = create_watch_rule(self.ctx, self.stack)
2295
        create_watch_data(self.ctx, watch_rule)
2296
        db_api.watch_rule_delete(self.ctx, watch_rule.id)
2297
        self.assertIsNone(db_api.watch_rule_get(self.ctx, watch_rule.id))
2298
        self.assertRaises(exception.NotFound, db_api.watch_rule_delete,
2299
                          self.ctx, UUID2)
2300
2301
        # Testing associated watch data deletion
2302
        self.assertEqual([], db_api.watch_data_get_all(self.ctx))
2303
2304
2305
class DBAPIWatchDataTest(common.HeatTestCase):
2306
    def setUp(self):
2307
        super(DBAPIWatchDataTest, self).setUp()
2308
        self.ctx = utils.dummy_context()
2309
        self.template = create_raw_template(self.ctx)
2310
        self.user_creds = create_user_creds(self.ctx)
2311
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
2312
        self.watch_rule = create_watch_rule(self.ctx, self.stack)
2313
2314
    def test_watch_data_create(self):
2315
        create_watch_data(self.ctx, self.watch_rule)
2316
        ret_data = db_api.watch_data_get_all(self.ctx)
2317
        self.assertEqual(1, len(ret_data))
2318
2319
        self.assertEqual('{"foo": "bar"}', json.dumps(ret_data[0].data))
2320
        self.assertEqual(self.watch_rule.id, ret_data[0].watch_rule_id)
2321
2322
    def test_watch_data_get_all(self):
2323
        values = [
2324
            {'data': json.loads('{"foo": "d1"}')},
2325
            {'data': json.loads('{"foo": "d2"}')},
2326
            {'data': json.loads('{"foo": "d3"}')}
2327
        ]
2328
        [create_watch_data(self.ctx, self.watch_rule, **val) for val in values]
2329
        watch_data = db_api.watch_data_get_all(self.ctx)
2330
        self.assertEqual(3, len(watch_data))
2331
2332
        data = [wd.data for wd in watch_data]
2333
        [self.assertIn(val['data'], data) for val in values]
2334
2335
2336
class DBAPIServiceTest(common.HeatTestCase):
2337
    def setUp(self):
2338
        super(DBAPIServiceTest, self).setUp()
2339
        self.ctx = utils.dummy_context()
2340
2341
    def test_service_create_get(self):
2342
        service = create_service(self.ctx)
2343
        ret_service = db_api.service_get(self.ctx, service.id)
2344
        self.assertIsNotNone(ret_service)
2345
        self.assertEqual(service.id, ret_service.id)
2346
        self.assertEqual(service.hostname, ret_service.hostname)
2347
        self.assertEqual(service.binary, ret_service.binary)
2348
        self.assertEqual(service.host, ret_service.host)
2349
        self.assertEqual(service.topic, ret_service.topic)
2350
        self.assertEqual(service.engine_id, ret_service.engine_id)
2351
        self.assertEqual(service.report_interval, ret_service.report_interval)
2352
        self.assertIsNotNone(service.created_at)
2353
        self.assertIsNone(service.updated_at)
2354
        self.assertIsNone(service.deleted_at)
2355
2356
    def test_service_get_all_by_args(self):
2357
        # Host-1
2358
        values = [{'id': str(uuid.uuid4()),
2359
                   'hostname': 'host-1',
2360
                   'host': 'engine-1'}]
2361
        # Host-2
2362
        for i in [0, 1, 2]:
2363
            values.append({'id': str(uuid.uuid4()),
2364
                           'hostname': 'host-2',
2365
                           'host': 'engine-%s' % i})
2366
2367
        [create_service(self.ctx, **val) for val in values]
2368
2369
        services = db_api.service_get_all(self.ctx)
2370
        self.assertEqual(4, len(services))
2371
2372
        services_by_args = db_api.service_get_all_by_args(self.ctx,
2373
                                                          hostname='host-2',
2374
                                                          binary='heat-engine',
2375
                                                          host='engine-0')
2376
        self.assertEqual(1, len(services_by_args))
2377
        self.assertEqual('host-2', services_by_args[0].hostname)
2378
        self.assertEqual('heat-engine', services_by_args[0].binary)
2379
        self.assertEqual('engine-0', services_by_args[0].host)
2380
2381
    def test_service_update(self):
2382
        service = create_service(self.ctx)
2383
        values = {'hostname': 'host-updated',
2384
                  'host': 'engine-updated',
2385
                  'retry_interval': 120}
2386
        service = db_api.service_update(self.ctx, service.id, values)
2387
        self.assertEqual('host-updated', service.hostname)
2388
        self.assertEqual(120, service.retry_interval)
2389
        self.assertEqual('engine-updated', service.host)
2390
2391
        # simple update, expected the updated_at is updated
2392
        old_updated_date = service.updated_at
2393
        service = db_api.service_update(self.ctx, service.id, dict())
2394
        self.assertGreater(service.updated_at, old_updated_date)
2395
2396
    def test_service_delete_soft_delete(self):
2397
        service = create_service(self.ctx)
2398
2399
        # Soft delete
2400
        db_api.service_delete(self.ctx, service.id)
2401
        ret_service = db_api.service_get(self.ctx, service.id)
2402
        self.assertEqual(ret_service.id, service.id)
2403
2404
        # Delete
2405
        db_api.service_delete(self.ctx, service.id, False)
2406
        self.assertRaises(exception.ServiceNotFound, db_api.service_get,
2407
                          self.ctx, service.id)
2408
2409
2410
class DBAPIResourceUpdateTest(common.HeatTestCase):
2411
    def setUp(self):
2412
        super(DBAPIResourceUpdateTest, self).setUp()
2413
        self.ctx = utils.dummy_context()
2414
        template = create_raw_template(self.ctx)
2415
        user_creds = create_user_creds(self.ctx)
2416
        stack = create_stack(self.ctx, template, user_creds)
2417
        self.resource = create_resource(self.ctx, stack,
2418
                                        atomic_key=0)
2419
2420
    def test_unlocked_resource_update(self):
2421
        values = {'engine_id': 'engine-1',
2422
                  'action': 'CREATE',
2423
                  'status': 'IN_PROGRESS'}
2424
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2425
        ret = db_api.resource_update(self.ctx, self.resource.id,
2426
                                     values, db_res.atomic_key, None)
2427
        self.assertTrue(ret)
2428
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2429
        self.assertEqual('engine-1', db_res.engine_id)
2430
        self.assertEqual('CREATE', db_res.action)
2431
        self.assertEqual('IN_PROGRESS', db_res.status)
2432
        self.assertEqual(1, db_res.atomic_key)
2433
2434
    def test_locked_resource_update_by_same_engine(self):
2435
        values = {'engine_id': 'engine-1',
2436
                  'action': 'CREATE',
2437
                  'status': 'IN_PROGRESS'}
2438
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2439
        ret = db_api.resource_update(self.ctx, self.resource.id,
2440
                                     values, db_res.atomic_key, None)
2441
        self.assertTrue(ret)
2442
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2443
        self.assertEqual('engine-1', db_res.engine_id)
2444
        self.assertEqual(1, db_res.atomic_key)
2445
        values = {'engine_id': 'engine-1',
2446
                  'action': 'CREATE',
2447
                  'status': 'FAILED'}
2448
        ret = db_api.resource_update(self.ctx, self.resource.id,
2449
                                     values, db_res.atomic_key, 'engine-1')
2450
        self.assertTrue(ret)
2451
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2452
        self.assertEqual('engine-1', db_res.engine_id)
2453
        self.assertEqual('CREATE', db_res.action)
2454
        self.assertEqual('FAILED', db_res.status)
2455
        self.assertEqual(2, db_res.atomic_key)
2456
2457
    def test_locked_resource_update_by_other_engine(self):
2458
        values = {'engine_id': 'engine-1',
2459
                  'action': 'CREATE',
2460
                  'status': 'IN_PROGRESS'}
2461
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2462
        ret = db_api.resource_update(self.ctx, self.resource.id,
2463
                                     values, db_res.atomic_key, None)
2464
        self.assertTrue(ret)
2465
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2466
        self.assertEqual('engine-1', db_res.engine_id)
2467
        self.assertEqual(1, db_res.atomic_key)
2468
        values = {'engine_id': 'engine-2',
2469
                  'action': 'CREATE',
2470
                  'status': 'FAILED'}
2471
        ret = db_api.resource_update(self.ctx, self.resource.id,
2472
                                     values, db_res.atomic_key, 'engine-2')
2473
        self.assertFalse(ret)
2474
2475
    def test_release_resource_lock(self):
2476
        values = {'engine_id': 'engine-1',
2477
                  'action': 'CREATE',
2478
                  'status': 'IN_PROGRESS'}
2479
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2480
        ret = db_api.resource_update(self.ctx, self.resource.id,
2481
                                     values, db_res.atomic_key, None)
2482
        self.assertTrue(ret)
2483
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2484
        self.assertEqual('engine-1', db_res.engine_id)
2485
        self.assertEqual(1, db_res.atomic_key)
2486
        # Set engine id as None to release the lock
2487
        values = {'engine_id': None,
2488
                  'action': 'CREATE',
2489
                  'status': 'COMPLETE'}
2490
        ret = db_api.resource_update(self.ctx, self.resource.id,
2491
                                     values, db_res.atomic_key, 'engine-1')
2492
        self.assertTrue(ret)
2493
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2494
        self.assertIsNone(db_res.engine_id)
2495
        self.assertEqual('CREATE', db_res.action)
2496
        self.assertEqual('COMPLETE', db_res.status)
2497
        self.assertEqual(2, db_res.atomic_key)
2498
2499
    def test_steal_resource_lock(self):
2500
        values = {'engine_id': 'engine-1',
2501
                  'action': 'CREATE',
2502
                  'status': 'IN_PROGRESS'}
2503
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2504
        ret = db_api.resource_update(self.ctx, self.resource.id,
2505
                                     values, db_res.atomic_key, None)
2506
        self.assertTrue(ret)
2507
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2508
        self.assertEqual('engine-1', db_res.engine_id)
2509
        self.assertEqual(1, db_res.atomic_key)
2510
        # Set engine id as engine-2 and pass expected engine id as old engine
2511
        # i.e engine-1 in db api steal the lock
2512
        values = {'engine_id': 'engine-2',
2513
                  'action': 'DELETE',
2514
                  'status': 'IN_PROGRESS'}
2515
        ret = db_api.resource_update(self.ctx, self.resource.id,
2516
                                     values, db_res.atomic_key, 'engine-1')
2517
        self.assertTrue(ret)
2518
        db_res = db_api.resource_get(self.ctx, self.resource.id)
2519
        self.assertEqual('engine-2', db_res.engine_id)
2520
        self.assertEqual('DELETE', db_res.action)
2521
        self.assertEqual(2, db_res.atomic_key)
2522
2523
2524
class DBAPISyncPointTest(common.HeatTestCase):
2525
    def setUp(self):
2526
        super(DBAPISyncPointTest, self).setUp()
2527
        self.ctx = utils.dummy_context()
2528
        self.template = create_raw_template(self.ctx)
2529
        self.user_creds = create_user_creds(self.ctx)
2530
        self.stack = create_stack(self.ctx, self.template, self.user_creds)
2531
        self.resources = [create_resource(self.ctx, self.stack, name='res1'),
2532
                          create_resource(self.ctx, self.stack, name='res2'),
2533
                          create_resource(self.ctx, self.stack, name='res3')]
2534
2535
    def test_sync_point_create_get(self):
2536
        for res in self.resources:
2537
            # create sync_point for resources and verify
2538
            sync_point_rsrc = create_sync_point(
2539
                self.ctx, entity_id=str(res.id), stack_id=self.stack.id,
2540
                traversal_id=self.stack.current_traversal
2541
            )
2542
2543
            ret_sync_point_rsrc = db_api.sync_point_get(
2544
                self.ctx, sync_point_rsrc.entity_id,
2545
                sync_point_rsrc.traversal_id, sync_point_rsrc.is_update
2546
            )
2547
2548
            self.assertIsNotNone(ret_sync_point_rsrc)
2549
            self.assertEqual(sync_point_rsrc.entity_id,
2550
                             ret_sync_point_rsrc.entity_id)
2551
            self.assertEqual(sync_point_rsrc.traversal_id,
2552
                             ret_sync_point_rsrc.traversal_id)
2553
            self.assertEqual(sync_point_rsrc.is_update,
2554
                             ret_sync_point_rsrc.is_update)
2555
            self.assertEqual(sync_point_rsrc.atomic_key,
2556
                             ret_sync_point_rsrc.atomic_key)
2557
            self.assertEqual(sync_point_rsrc.stack_id,
2558
                             ret_sync_point_rsrc.stack_id)
2559
            self.assertEqual(sync_point_rsrc.input_data,
2560
                             ret_sync_point_rsrc.input_data)
2561
2562
        # Finally create sync_point for stack and verify
2563
        sync_point_stack = create_sync_point(
2564
            self.ctx, entity_id=self.stack.id, stack_id=self.stack.id,
2565
            traversal_id=self.stack.current_traversal
2566
        )
2567
2568
        ret_sync_point_stack = db_api.sync_point_get(
2569
            self.ctx, sync_point_stack.entity_id,
2570
            sync_point_stack.traversal_id, sync_point_stack.is_update
2571
        )
2572
2573
        self.assertIsNotNone(ret_sync_point_stack)
2574
        self.assertEqual(sync_point_stack.entity_id,
2575
                         ret_sync_point_stack.entity_id)
2576
        self.assertEqual(sync_point_stack.traversal_id,
2577
                         ret_sync_point_stack.traversal_id)
2578
        self.assertEqual(sync_point_stack.is_update,
2579
                         ret_sync_point_stack.is_update)
2580
        self.assertEqual(sync_point_stack.atomic_key,
2581
                         ret_sync_point_stack.atomic_key)
2582
        self.assertEqual(sync_point_stack.stack_id,
2583
                         ret_sync_point_stack.stack_id)
2584
        self.assertEqual(sync_point_stack.input_data,
2585
                         ret_sync_point_stack.input_data)
2586
2587
    def test_sync_point_update(self):
2588
        sync_point = create_sync_point(
2589
            self.ctx, entity_id=str(self.resources[0].id),
2590
            stack_id=self.stack.id, traversal_id=self.stack.current_traversal
2591
        )
2592
        self.assertEqual({}, sync_point.input_data)
2593
        self.assertEqual(0, sync_point.atomic_key)
2594
2595
        # first update
2596
        rows_updated = db_api.sync_point_update_input_data(
2597
            self.ctx, sync_point.entity_id, sync_point.traversal_id,
2598
            sync_point.is_update, sync_point.atomic_key,
2599
            {'input_data': '{key: value}'}
2600
        )
2601
        self.assertEqual(1, rows_updated)
2602
2603
        ret_sync_point = db_api.sync_point_get(self.ctx,
2604
                                               sync_point.entity_id,
2605
                                               sync_point.traversal_id,
2606
                                               sync_point.is_update)
2607
        self.assertIsNotNone(ret_sync_point)
2608
        # check if atomic_key was incremented on write
2609
        self.assertEqual(1, ret_sync_point.atomic_key)
2610
        self.assertEqual({'input_data': '{key: value}'},
2611
                         ret_sync_point.input_data)
2612
2613
        # second update
2614
        rows_updated = db_api.sync_point_update_input_data(
2615
            self.ctx, sync_point.entity_id, sync_point.traversal_id,
2616
            sync_point.is_update, sync_point.atomic_key,
2617
            {'input_data': '{key1: value1}'}
2618
        )
2619
        self.assertEqual(1, rows_updated)
2620
2621
        ret_sync_point = db_api.sync_point_get(self.ctx,
2622
                                               sync_point.entity_id,
2623
                                               sync_point.traversal_id,
2624
                                               sync_point.is_update)
2625
        self.assertIsNotNone(ret_sync_point)
2626
        # check if atomic_key was incremented on write
2627
        self.assertEqual(2, ret_sync_point.atomic_key)
2628
        self.assertEqual({'input_data': '{key1: value1}'},
2629
                         ret_sync_point.input_data)
2630
2631
    def test_sync_point_concurrent_update(self):
2632
        sync_point = create_sync_point(
2633
            self.ctx, entity_id=str(self.resources[0].id),
2634
            stack_id=self.stack.id, traversal_id=self.stack.current_traversal
2635
        )
2636
        self.assertEqual({}, sync_point.input_data)
2637
        self.assertEqual(0, sync_point.atomic_key)
2638
2639
        # update where atomic_key is 0 and succeeds.
2640
        rows_updated = db_api.sync_point_update_input_data(
2641
            self.ctx, sync_point.entity_id, sync_point.traversal_id,
2642
            sync_point.is_update, 0, {'input_data': '{key: value}'}
2643
        )
2644
        self.assertEqual(1, rows_updated)
2645
2646
        # another update where atomic_key is 0 and does not update.
2647
        rows_updated = db_api.sync_point_update_input_data(
2648
            self.ctx, sync_point.entity_id, sync_point.traversal_id,
2649
            sync_point.is_update, 0, {'input_data': '{key: value}'}
2650
        )
2651
        self.assertEqual(0, rows_updated)
2652
2653
    def test_sync_point_delete(self):
2654
        for res in self.resources:
2655
            sync_point_rsrc = create_sync_point(
2656
                self.ctx, entity_id=str(res.id), stack_id=self.stack.id,
2657
                traversal_id=self.stack.current_traversal
2658
            )
2659
            self.assertIsNotNone(sync_point_rsrc)
2660
2661
        sync_point_stack = create_sync_point(
2662
            self.ctx, entity_id=self.stack.id,
2663
            stack_id=self.stack.id,
2664
            traversal_id=self.stack.current_traversal
2665
        )
2666
        self.assertIsNotNone(sync_point_stack)
2667
2668
        rows_deleted = db_api.sync_point_delete_all_by_stack_and_traversal(
2669
            self.ctx, self.stack.id,
2670
            self.stack.current_traversal
2671
        )
2672
        self.assertGreater(rows_deleted, 0)
2673
        self.assertEqual(4, rows_deleted)
2674
2675
        # Additionally check if sync_point_get returns None.
2676
        for res in self.resources:
2677
            ret_sync_point_rsrc = db_api.sync_point_get(
2678
                self.ctx, str(res.id), self.stack.current_traversal, True
2679
            )
2680
            self.assertEqual(None, ret_sync_point_rsrc)
2681
2682
        ret_sync_point_stack = db_api.sync_point_get(
2683
            self.ctx, self.stack.id, self.stack.current_traversal, True
2684
        )
2685
        self.assertEqual(None, ret_sync_point_stack)
1.1.26 by Corey Bryant
Import upstream version 5.0.0~b1
2686
2687
2688
class DBAPICryptParamsPropsTest(common.HeatTestCase):
2689
    def setUp(self):
2690
        super(DBAPICryptParamsPropsTest, self).setUp()
2691
        self.ctx = utils.dummy_context()
2692
        t = template_format.parse('''
2693
        heat_template_version: 2013-05-23
2694
        parameters:
2695
            param1:
2696
                type: string
2697
                description: value1.
2698
            param2:
2699
                type: string
2700
                description: value2.
2701
                hidden: true
2702
        resources:
2703
            a_resource:
2704
                type: GenericResourceType
2705
        ''')
2706
        template = {
2707
            'template': t,
2708
            'files': {'foo': 'bar'},
2709
            'environment': {'parameters': {'param1': 'foo',
2710
                                           'param2': 'bar'}}}
2711
        self.template = db_api.raw_template_create(self.ctx, template)
2712
2713
    def test_db_encrypt_decrypt(self):
2714
        session = db_api.get_session()
2715
2716
        env = session.query(models.RawTemplate).all()[0].environment
2717
        self.assertEqual('bar', env['parameters']['param2'])
2718
2719
        db_api.db_encrypt_parameters_and_properties(
2720
            self.ctx, cfg.CONF.auth_encryption_key)
2721
2722
        env = session.query(models.RawTemplate).all()[0].environment
2723
        self.assertEqual('oslo_decrypt_v1',
2724
                         env['parameters']['param2'][0])
2725
2726
        db_api.db_decrypt_parameters_and_properties(
2727
            self.ctx, cfg.CONF.auth_encryption_key)
2728
2729
        env = session.query(models.RawTemplate).all()[0].environment
2730
        self.assertEqual('bar', env['parameters']['param2'])
2731
2732
        # Use a different encryption key to decrypt
2733
        db_api.db_encrypt_parameters_and_properties(
2734
            self.ctx, cfg.CONF.auth_encryption_key)
2735
        db_api.db_decrypt_parameters_and_properties(
2736
            self.ctx, '774c15be099ea74123a9b9592ff12680')
2737
2738
        env = session.query(models.RawTemplate).all()[0].environment
2739
        self.assertNotEqual('bar', env['parameters']['param2'])