summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-10-29 17:26:38 +0000
committerGerrit Code Review <review@openstack.org>2018-10-29 17:26:38 +0000
commit464d2c0ea5ebb50bee615a0e0f2624c3aa40d9bd (patch)
tree3a1b7eb9eeed5d9d307cea59aec32926f86f4cdd
parent27aeeb8fea0d9b8749e023e0d2254c03e3abfdc2 (diff)
parent035841416bb349d84fd227716624f39c120a1787 (diff)
Merge "Validate bucket diffing works with revision rollback"
-rw-r--r--deckhand/engine/revision_diff.py11
-rw-r--r--deckhand/tests/unit/base.py116
-rw-r--r--deckhand/tests/unit/db/base.py136
-rw-r--r--deckhand/tests/unit/db/test_documents.py4
-rw-r--r--deckhand/tests/unit/db/test_documents_negative.py4
-rw-r--r--deckhand/tests/unit/db/test_layering_policies.py4
-rw-r--r--deckhand/tests/unit/db/test_revision_documents.py4
-rw-r--r--deckhand/tests/unit/db/test_revision_rollback.py6
-rw-r--r--deckhand/tests/unit/db/test_revision_tags.py4
-rw-r--r--deckhand/tests/unit/db/test_revision_tags_negative.py4
-rw-r--r--deckhand/tests/unit/db/test_revisions.py4
-rw-r--r--deckhand/tests/unit/engine/test_revision_deepdiffing.py4
-rw-r--r--deckhand/tests/unit/engine/test_revision_diffing.py31
-rw-r--r--deckhand/tests/unit/engine/test_secrets_manager.py8
-rw-r--r--deckhand/tests/unit/views/test_document_views.py4
-rw-r--r--deckhand/tests/unit/views/test_revision_tag_views.py4
-rw-r--r--deckhand/tests/unit/views/test_revision_views.py4
17 files changed, 179 insertions, 173 deletions
diff --git a/deckhand/engine/revision_diff.py b/deckhand/engine/revision_diff.py
index 51f5c2c..977fdaa 100644
--- a/deckhand/engine/revision_diff.py
+++ b/deckhand/engine/revision_diff.py
@@ -102,8 +102,8 @@ def revision_diff(revision_id, comparison_revision_id, deepdiff=False):
102 bucket_a: created 102 bucket_a: created
103 """ 103 """
104 if deepdiff: 104 if deepdiff:
105 docs = (_rendered_doc(revision_id) if revision_id != 0 else []) 105 docs = (_render_documents(revision_id) if revision_id != 0 else [])
106 comparison_docs = (_rendered_doc(comparison_revision_id) 106 comparison_docs = (_render_documents(comparison_revision_id)
107 if comparison_revision_id != 0 else []) 107 if comparison_revision_id != 0 else [])
108 else: 108 else:
109 # Retrieve document history for each revision. Since `revision_id` of 0 109 # Retrieve document history for each revision. Since `revision_id` of 0
@@ -143,7 +143,7 @@ def revision_diff(revision_id, comparison_revision_id, deepdiff=False):
143 shared_buckets = set(buckets.keys()).intersection( 143 shared_buckets = set(buckets.keys()).intersection(
144 comparison_buckets.keys()) 144 comparison_buckets.keys())
145 # `unshared_buckets` references buckets not shared by both `revision_id` 145 # `unshared_buckets` references buckets not shared by both `revision_id`
146 # and `comparison_revision_id` -- i.e. their non-intersection. 146 # and `comparison_revision_id` -- i.e. their union.
147 unshared_buckets = set(buckets.keys()).union( 147 unshared_buckets = set(buckets.keys()).union(
148 comparison_buckets.keys()) - shared_buckets 148 comparison_buckets.keys()) - shared_buckets
149 149
@@ -163,9 +163,8 @@ def revision_diff(revision_id, comparison_revision_id, deepdiff=False):
163 result[bucket_name] = 'unmodified' 163 result[bucket_name] = 'unmodified'
164 else: 164 else:
165 result[bucket_name] = 'modified' 165 result[bucket_name] = 'modified'
166 # If deepdiff enabled 166 # If deepdiff is enabled, find out diff between buckets
167 if deepdiff: 167 if deepdiff:
168 # find out diff between buckets
169 bucket_diff = _diff_buckets(buckets[bucket_name], 168 bucket_diff = _diff_buckets(buckets[bucket_name],
170 comparison_buckets[bucket_name]) 169 comparison_buckets[bucket_name])
171 result[bucket_name + ' diff'] = bucket_diff 170 result[bucket_name + ' diff'] = bucket_diff
@@ -289,7 +288,7 @@ def _format_diff_result(dr):
289 return dr 288 return dr
290 289
291 290
292def _rendered_doc(revision_id): 291def _render_documents(revision_id):
293 """Provides rendered document by given revision id.""" 292 """Provides rendered document by given revision id."""
294 filters = {'deleted': False} 293 filters = {'deleted': False}
295 rendered_documents, _ = common.get_rendered_docs(revision_id, **filters) 294 rendered_documents, _ = common.get_rendered_docs(revision_id, **filters)
diff --git a/deckhand/tests/unit/base.py b/deckhand/tests/unit/base.py
index 0f949e1..085bb6c 100644
--- a/deckhand/tests/unit/base.py
+++ b/deckhand/tests/unit/base.py
@@ -25,12 +25,19 @@ import testtools
25from deckhand.conf import config # noqa: Calls register_opts(CONF) 25from deckhand.conf import config # noqa: Calls register_opts(CONF)
26from deckhand.db.sqlalchemy import api as db_api 26from deckhand.db.sqlalchemy import api as db_api
27from deckhand.engine import cache 27from deckhand.engine import cache
28from deckhand.tests import test_utils
28from deckhand.tests.unit import fixtures as dh_fixtures 29from deckhand.tests.unit import fixtures as dh_fixtures
29 30
30CONF = cfg.CONF 31CONF = cfg.CONF
31logging.register_options(CONF) 32logging.register_options(CONF)
32logging.setup(CONF, 'deckhand') 33logging.setup(CONF, 'deckhand')
33 34
35BASE_EXPECTED_FIELDS = ("created_at", "updated_at", "deleted_at", "deleted")
36DOCUMENT_EXPECTED_FIELDS = BASE_EXPECTED_FIELDS + (
37 "id", "schema", "name", "layer", "metadata", "data", "data_hash",
38 "metadata_hash", "revision_id", "bucket_id")
39REVISION_EXPECTED_FIELDS = ("id", "documents", "tags")
40
34 41
35class DeckhandTestCase(testtools.TestCase): 42class DeckhandTestCase(testtools.TestCase):
36 43
@@ -122,3 +129,112 @@ class DeckhandWithDBTestCase(DeckhandTestCase):
122 group='database') 129 group='database')
123 db_api.setup_db(CONF.database.connection, create_tables=True) 130 db_api.setup_db(CONF.database.connection, create_tables=True)
124 self.addCleanup(db_api.drop_db) 131 self.addCleanup(db_api.drop_db)
132
133 def create_documents(self, bucket_name, documents,
134 validation_policies=None):
135 if not validation_policies:
136 validation_policies = []
137
138 if not isinstance(documents, list):
139 documents = [documents]
140 if not isinstance(validation_policies, list):
141 validation_policies = [validation_policies]
142
143 docs = db_api.documents_create(
144 bucket_name, documents, validation_policies)
145
146 return docs
147
148 def show_document(self, **fields):
149 doc = db_api.document_get(**fields)
150
151 self.validate_document(actual=doc)
152
153 return doc
154
155 def create_revision(self):
156 # Implicitly creates a revision and returns it.
157 documents = [DocumentFixture.get_minimal_fixture()]
158 bucket_name = test_utils.rand_name('bucket')
159 revision_id = self.create_documents(bucket_name, documents)[0][
160 'revision_id']
161 return revision_id
162
163 def show_revision(self, revision_id):
164 revision = db_api.revision_get(revision_id)
165 self.validate_revision(revision)
166 return revision
167
168 def delete_revisions(self):
169 return db_api.revision_delete_all()
170
171 def list_revision_documents(self, revision_id, **filters):
172 documents = db_api.revision_documents_get(revision_id, **filters)
173 for document in documents:
174 self.validate_document(document)
175 return documents
176
177 def list_revisions(self):
178 return db_api.revision_get_all()
179
180 def rollback_revision(self, revision_id):
181 latest_revision = db_api.revision_get_latest()
182 return db_api.revision_rollback(revision_id, latest_revision)
183
184 def create_validation(self, revision_id, val_name, val_data):
185 return db_api.validation_create(revision_id, val_name, val_data)
186
187 def _validate_object(self, obj):
188 for attr in BASE_EXPECTED_FIELDS:
189 if attr.endswith('_at'):
190 self.assertThat(obj[attr], testtools.matchers.MatchesAny(
191 testtools.matchers.Is(None),
192 testtools.matchers.IsInstance(str)))
193 else:
194 self.assertIsInstance(obj[attr], bool)
195
196 def validate_document(self, actual, expected=None, is_deleted=False):
197 self._validate_object(actual)
198
199 # Validate that the document has all expected fields and is a dict.
200 expected_fields = list(DOCUMENT_EXPECTED_FIELDS)
201 if not is_deleted:
202 expected_fields.remove('deleted_at')
203
204 self.assertIsInstance(actual, dict)
205 for field in expected_fields:
206 self.assertIn(field, actual)
207
208 def validate_revision(self, revision):
209 self._validate_object(revision)
210
211 for attr in REVISION_EXPECTED_FIELDS:
212 self.assertIn(attr, revision)
213
214
215# TODO(felipemonteiro): Move this into a separate module called `fixtures`.
216class DocumentFixture(object):
217
218 @staticmethod
219 def get_minimal_fixture(**kwargs):
220 fixture = {
221 'data': {
222 test_utils.rand_name('key'): test_utils.rand_name('value')
223 },
224 'metadata': {
225 'name': test_utils.rand_name('metadata_data'),
226 'label': test_utils.rand_name('metadata_label'),
227 'layeringDefinition': {
228 'abstract': test_utils.rand_bool(),
229 'layer': test_utils.rand_name('layer')
230 },
231 'storagePolicy': test_utils.rand_name('storage_policy')
232 },
233 'schema': test_utils.rand_name('schema')}
234 fixture.update(kwargs)
235 return fixture
236
237 @staticmethod
238 def get_minimal_multi_fixture(count=2, **kwargs):
239 return [DocumentFixture.get_minimal_fixture(**kwargs)
240 for _ in range(count)]
diff --git a/deckhand/tests/unit/db/base.py b/deckhand/tests/unit/db/base.py
deleted file mode 100644
index 17bc3ab..0000000
--- a/deckhand/tests/unit/db/base.py
+++ /dev/null
@@ -1,136 +0,0 @@
1# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from testtools import matchers
16
17from deckhand.db.sqlalchemy import api as db_api
18from deckhand.tests import test_utils
19from deckhand.tests.unit import base
20
21BASE_EXPECTED_FIELDS = ("created_at", "updated_at", "deleted_at", "deleted")
22DOCUMENT_EXPECTED_FIELDS = BASE_EXPECTED_FIELDS + (
23 "id", "schema", "name", "layer", "metadata", "data", "data_hash",
24 "metadata_hash", "revision_id", "bucket_id")
25REVISION_EXPECTED_FIELDS = ("id", "documents", "tags")
26
27
28# TODO(felipemonteiro): Move this into a separate module called `fixtures`.
29class DocumentFixture(object):
30
31 @staticmethod
32 def get_minimal_fixture(**kwargs):
33 fixture = {
34 'data': {
35 test_utils.rand_name('key'): test_utils.rand_name('value')
36 },
37 'metadata': {
38 'name': test_utils.rand_name('metadata_data'),
39 'label': test_utils.rand_name('metadata_label'),
40 'layeringDefinition': {
41 'abstract': test_utils.rand_bool(),
42 'layer': test_utils.rand_name('layer')
43 },
44 'storagePolicy': test_utils.rand_name('storage_policy')
45 },
46 'schema': test_utils.rand_name('schema')}
47 fixture.update(kwargs)
48 return fixture
49
50 @staticmethod
51 def get_minimal_multi_fixture(count=2, **kwargs):
52 return [DocumentFixture.get_minimal_fixture(**kwargs)
53 for _ in range(count)]
54
55
56class TestDbBase(base.DeckhandWithDBTestCase):
57
58 def create_documents(self, bucket_name, documents,
59 validation_policies=None):
60 if not validation_policies:
61 validation_policies = []
62
63 if not isinstance(documents, list):
64 documents = [documents]
65 if not isinstance(validation_policies, list):
66 validation_policies = [validation_policies]
67
68 docs = db_api.documents_create(
69 bucket_name, documents, validation_policies)
70
71 return docs
72
73 def show_document(self, **fields):
74 doc = db_api.document_get(**fields)
75
76 self.validate_document(actual=doc)
77
78 return doc
79
80 def create_revision(self):
81 # Implicitly creates a revision and returns it.
82 documents = [DocumentFixture.get_minimal_fixture()]
83 bucket_name = test_utils.rand_name('bucket')
84 revision_id = self.create_documents(bucket_name, documents)[0][
85 'revision_id']
86 return revision_id
87
88 def show_revision(self, revision_id):
89 revision = db_api.revision_get(revision_id)
90 self.validate_revision(revision)
91 return revision
92
93 def delete_revisions(self):
94 return db_api.revision_delete_all()
95
96 def list_revision_documents(self, revision_id, **filters):
97 documents = db_api.revision_documents_get(revision_id, **filters)
98 for document in documents:
99 self.validate_document(document)
100 return documents
101
102 def list_revisions(self):
103 return db_api.revision_get_all()
104
105 def rollback_revision(self, revision_id):
106 latest_revision = db_api.revision_get_latest()
107 return db_api.revision_rollback(revision_id, latest_revision)
108
109 def create_validation(self, revision_id, val_name, val_data):
110 return db_api.validation_create(revision_id, val_name, val_data)
111
112 def _validate_object(self, obj):
113 for attr in BASE_EXPECTED_FIELDS:
114 if attr.endswith('_at'):
115 self.assertThat(obj[attr], matchers.MatchesAny(
116 matchers.Is(None), matchers.IsInstance(str)))
117 else:
118 self.assertIsInstance(obj[attr], bool)
119
120 def validate_document(self, actual, expected=None, is_deleted=False):
121 self._validate_object(actual)
122
123 # Validate that the document has all expected fields and is a dict.
124 expected_fields = list(DOCUMENT_EXPECTED_FIELDS)
125 if not is_deleted:
126 expected_fields.remove('deleted_at')
127
128 self.assertIsInstance(actual, dict)
129 for field in expected_fields:
130 self.assertIn(field, actual)
131
132 def validate_revision(self, revision):
133 self._validate_object(revision)
134
135 for attr in REVISION_EXPECTED_FIELDS:
136 self.assertIn(attr, revision)
diff --git a/deckhand/tests/unit/db/test_documents.py b/deckhand/tests/unit/db/test_documents.py
index 18ab94c..246c495 100644
--- a/deckhand/tests/unit/db/test_documents.py
+++ b/deckhand/tests/unit/db/test_documents.py
@@ -19,10 +19,10 @@ from deckhand.db.sqlalchemy import api as db_api
19from deckhand import errors 19from deckhand import errors
20from deckhand import factories 20from deckhand import factories
21from deckhand.tests import test_utils 21from deckhand.tests import test_utils
22from deckhand.tests.unit.db import base 22from deckhand.tests.unit import base
23 23
24 24
25class TestDocuments(base.TestDbBase): 25class TestDocuments(base.DeckhandWithDBTestCase):
26 26
27 def setUp(self): 27 def setUp(self):
28 super(TestDocuments, self).setUp() 28 super(TestDocuments, self).setUp()
diff --git a/deckhand/tests/unit/db/test_documents_negative.py b/deckhand/tests/unit/db/test_documents_negative.py
index 76fb8e1..1633a13 100644
--- a/deckhand/tests/unit/db/test_documents_negative.py
+++ b/deckhand/tests/unit/db/test_documents_negative.py
@@ -14,10 +14,10 @@
14 14
15from deckhand import errors 15from deckhand import errors
16from deckhand.tests import test_utils 16from deckhand.tests import test_utils
17from deckhand.tests.unit.db import base 17from deckhand.tests.unit import base
18 18
19 19
20class TestDocumentsNegative(base.TestDbBase): 20class TestDocumentsNegative(base.DeckhandWithDBTestCase):
21 21
22 def test_get_documents_by_revision_id_and_wrong_filters(self): 22 def test_get_documents_by_revision_id_and_wrong_filters(self):
23 payload = base.DocumentFixture.get_minimal_fixture() 23 payload = base.DocumentFixture.get_minimal_fixture()
diff --git a/deckhand/tests/unit/db/test_layering_policies.py b/deckhand/tests/unit/db/test_layering_policies.py
index fba0854..52b02ab 100644
--- a/deckhand/tests/unit/db/test_layering_policies.py
+++ b/deckhand/tests/unit/db/test_layering_policies.py
@@ -15,10 +15,10 @@
15from deckhand import errors 15from deckhand import errors
16from deckhand import factories 16from deckhand import factories
17from deckhand.tests import test_utils 17from deckhand.tests import test_utils
18from deckhand.tests.unit.db import base 18from deckhand.tests.unit import base
19 19
20 20
21class LayeringPoliciesBaseTest(base.TestDbBase): 21class LayeringPoliciesBaseTest(base.DeckhandWithDBTestCase):
22 22
23 def setUp(self): 23 def setUp(self):
24 super(LayeringPoliciesBaseTest, self).setUp() 24 super(LayeringPoliciesBaseTest, self).setUp()
diff --git a/deckhand/tests/unit/db/test_revision_documents.py b/deckhand/tests/unit/db/test_revision_documents.py
index 5572380..c1dd6a8 100644
--- a/deckhand/tests/unit/db/test_revision_documents.py
+++ b/deckhand/tests/unit/db/test_revision_documents.py
@@ -13,10 +13,10 @@
13# limitations under the License. 13# limitations under the License.
14 14
15from deckhand.tests import test_utils 15from deckhand.tests import test_utils
16from deckhand.tests.unit.db import base 16from deckhand.tests.unit import base
17 17
18 18
19class TestRevisionDocumentsFiltering(base.TestDbBase): 19class TestRevisionDocumentsFiltering(base.DeckhandWithDBTestCase):
20 20
21 def test_document_filtering_by_bucket_name(self): 21 def test_document_filtering_by_bucket_name(self):
22 document = base.DocumentFixture.get_minimal_fixture() 22 document = base.DocumentFixture.get_minimal_fixture()
diff --git a/deckhand/tests/unit/db/test_revision_rollback.py b/deckhand/tests/unit/db/test_revision_rollback.py
index e7ee7c5..602ec1c 100644
--- a/deckhand/tests/unit/db/test_revision_rollback.py
+++ b/deckhand/tests/unit/db/test_revision_rollback.py
@@ -14,10 +14,10 @@
14 14
15from deckhand import errors 15from deckhand import errors
16from deckhand.tests import test_utils 16from deckhand.tests import test_utils
17from deckhand.tests.unit.db import base 17from deckhand.tests.unit import base
18 18
19 19
20class TestRevisionRollback(base.TestDbBase): 20class TestRevisionRollback(base.DeckhandWithDBTestCase):
21 21
22 def test_create_update_rollback(self): 22 def test_create_update_rollback(self):
23 # Revision 1: Create 4 documents. 23 # Revision 1: Create 4 documents.
@@ -124,7 +124,7 @@ class TestRevisionRollback(base.TestDbBase):
124 self.assertEmpty(rollback_documents) 124 self.assertEmpty(rollback_documents)
125 125
126 126
127class TestRevisionRollbackNegative(base.TestDbBase): 127class TestRevisionRollbackNegative(base.DeckhandWithDBTestCase):
128 128
129 def test_rollback_to_missing_revision_raises_exc(self): 129 def test_rollback_to_missing_revision_raises_exc(self):
130 # revision_id=1 doesn't exist yet since we start from an empty DB. 130 # revision_id=1 doesn't exist yet since we start from an empty DB.
diff --git a/deckhand/tests/unit/db/test_revision_tags.py b/deckhand/tests/unit/db/test_revision_tags.py
index b9b0047..9bd5468 100644
--- a/deckhand/tests/unit/db/test_revision_tags.py
+++ b/deckhand/tests/unit/db/test_revision_tags.py
@@ -15,10 +15,10 @@
15from deckhand.db.sqlalchemy import api as db_api 15from deckhand.db.sqlalchemy import api as db_api
16from deckhand import errors 16from deckhand import errors
17from deckhand.tests import test_utils 17from deckhand.tests import test_utils
18from deckhand.tests.unit.db import base 18from deckhand.tests.unit import base
19 19
20 20
21class TestRevisionTags(base.TestDbBase): 21class TestRevisionTags(base.DeckhandWithDBTestCase):
22 22
23 def setUp(self): 23 def setUp(self):
24 super(TestRevisionTags, self).setUp() 24 super(TestRevisionTags, self).setUp()
diff --git a/deckhand/tests/unit/db/test_revision_tags_negative.py b/deckhand/tests/unit/db/test_revision_tags_negative.py
index 9062c9c..716c9f7 100644
--- a/deckhand/tests/unit/db/test_revision_tags_negative.py
+++ b/deckhand/tests/unit/db/test_revision_tags_negative.py
@@ -14,10 +14,10 @@
14 14
15from deckhand.db.sqlalchemy import api as db_api 15from deckhand.db.sqlalchemy import api as db_api
16from deckhand import errors 16from deckhand import errors
17from deckhand.tests.unit.db import base 17from deckhand.tests.unit import base
18 18
19 19
20class TestRevisionTagsNegative(base.TestDbBase): 20class TestRevisionTagsNegative(base.DeckhandWithDBTestCase):
21 21
22 def test_create_tag_revision_not_found(self): 22 def test_create_tag_revision_not_found(self):
23 self.assertRaises( 23 self.assertRaises(
diff --git a/deckhand/tests/unit/db/test_revisions.py b/deckhand/tests/unit/db/test_revisions.py
index 540692f..34419ba 100644
--- a/deckhand/tests/unit/db/test_revisions.py
+++ b/deckhand/tests/unit/db/test_revisions.py
@@ -14,10 +14,10 @@
14 14
15from deckhand import errors 15from deckhand import errors
16from deckhand.tests import test_utils 16from deckhand.tests import test_utils
17from deckhand.tests.unit.db import base 17from deckhand.tests.unit import base
18 18
19 19
20class TestRevisions(base.TestDbBase): 20class TestRevisions(base.DeckhandWithDBTestCase):
21 21
22 def test_list(self): 22 def test_list(self):
23 documents = [base.DocumentFixture.get_minimal_fixture() 23 documents = [base.DocumentFixture.get_minimal_fixture()
diff --git a/deckhand/tests/unit/engine/test_revision_deepdiffing.py b/deckhand/tests/unit/engine/test_revision_deepdiffing.py
index 6d39454..120d633 100644
--- a/deckhand/tests/unit/engine/test_revision_deepdiffing.py
+++ b/deckhand/tests/unit/engine/test_revision_deepdiffing.py
@@ -16,10 +16,10 @@ import copy
16 16
17from deckhand.engine import revision_diff 17from deckhand.engine import revision_diff
18from deckhand import factories 18from deckhand import factories
19from deckhand.tests.unit.db import base 19from deckhand.tests.unit import base
20 20
21 21
22class TestRevisionDeepDiffing(base.TestDbBase): 22class TestRevisionDeepDiffing(base.DeckhandWithDBTestCase):
23 23
24 def _test_data(self): 24 def _test_data(self):
25 return { 25 return {
diff --git a/deckhand/tests/unit/engine/test_revision_diffing.py b/deckhand/tests/unit/engine/test_revision_diffing.py
index 52e8cf9..5bebf64 100644
--- a/deckhand/tests/unit/engine/test_revision_diffing.py
+++ b/deckhand/tests/unit/engine/test_revision_diffing.py
@@ -16,10 +16,10 @@ import copy
16 16
17from deckhand.engine.revision_diff import revision_diff 17from deckhand.engine.revision_diff import revision_diff
18from deckhand.tests import test_utils 18from deckhand.tests import test_utils
19from deckhand.tests.unit.db import base 19from deckhand.tests.unit import base
20 20
21 21
22class TestRevisionDiffing(base.TestDbBase): 22class TestRevisionDiffing(base.DeckhandWithDBTestCase):
23 23
24 def _verify_buckets_status(self, revision_id, comparison_revision_id, 24 def _verify_buckets_status(self, revision_id, comparison_revision_id,
25 expected): 25 expected):
@@ -307,3 +307,30 @@ class TestRevisionDiffing(base.TestDbBase):
307 self._verify_buckets_status( 307 self._verify_buckets_status(
308 revision_id_1, revision_id_4, 308 revision_id_1, revision_id_4,
309 {bucket_name: 'unmodified', alt_bucket_name_2: 'created'}) 309 {bucket_name: 'unmodified', alt_bucket_name_2: 'created'})
310
311 def test_revision_diff_delete_then_rollback(self):
312 """Validate that rolling back a revision works with bucket diff."""
313 payload = base.DocumentFixture.get_minimal_fixture()
314 bucket_name = test_utils.rand_name('bucket')
315 created_documents = self.create_documents(bucket_name, payload)
316 revision_id = created_documents[0]['revision_id']
317
318 # Delete all previously created documents.
319 deleted_documents = self.create_documents(bucket_name, [])
320 comparison_revision_id = deleted_documents[0]['revision_id']
321
322 # Validate that the empty bucket is deleted.
323 self._verify_buckets_status(
324 revision_id, comparison_revision_id, {bucket_name: 'deleted'})
325
326 # Rollback to first non-empty revision.
327 rollback_revision_id = self.rollback_revision(revision_id)['id']
328 # Validate that diffing rolled-back revision against 1 is unmodified.
329 self._verify_buckets_status(
330 revision_id, rollback_revision_id, {bucket_name: 'unmodified'})
331
332 # Validate that diffing rolled-back revision against 2 is created
333 # (because the rolled-back revision is newer than revision 2).
334 self._verify_buckets_status(
335 comparison_revision_id, rollback_revision_id,
336 {bucket_name: 'created'})
diff --git a/deckhand/tests/unit/engine/test_secrets_manager.py b/deckhand/tests/unit/engine/test_secrets_manager.py
index 7af4060..11306a8 100644
--- a/deckhand/tests/unit/engine/test_secrets_manager.py
+++ b/deckhand/tests/unit/engine/test_secrets_manager.py
@@ -27,10 +27,10 @@ from deckhand.engine import secrets_manager
27from deckhand import errors 27from deckhand import errors
28from deckhand import factories 28from deckhand import factories
29from deckhand.tests import test_utils 29from deckhand.tests import test_utils
30from deckhand.tests.unit.db import base as test_base 30from deckhand.tests.unit import base as test_base
31 31
32 32
33class TestSecretsManager(test_base.TestDbBase): 33class TestSecretsManager(test_base.DeckhandWithDBTestCase):
34 34
35 def setUp(self): 35 def setUp(self):
36 super(TestSecretsManager, self).setUp() 36 super(TestSecretsManager, self).setUp()
@@ -168,7 +168,7 @@ class TestSecretsManager(test_base.TestDbBase):
168 self.assertEqual(payload, retrieved_payload) 168 self.assertEqual(payload, retrieved_payload)
169 169
170 170
171class TestSecretsSubstitution(test_base.TestDbBase): 171class TestSecretsSubstitution(test_base.DeckhandWithDBTestCase):
172 172
173 def setUp(self): 173 def setUp(self):
174 super(TestSecretsSubstitution, self).setUp() 174 super(TestSecretsSubstitution, self).setUp()
@@ -876,7 +876,7 @@ data:
876 self.assertEqual(expected, substituted_docs[0]) 876 self.assertEqual(expected, substituted_docs[0])
877 877
878 878
879class TestSecretsSubstitutionNegative(test_base.TestDbBase): 879class TestSecretsSubstitutionNegative(test_base.DeckhandWithDBTestCase):
880 880
881 def setUp(self): 881 def setUp(self):
882 super(TestSecretsSubstitutionNegative, self).setUp() 882 super(TestSecretsSubstitutionNegative, self).setUp()
diff --git a/deckhand/tests/unit/views/test_document_views.py b/deckhand/tests/unit/views/test_document_views.py
index 038514f..3932b04 100644
--- a/deckhand/tests/unit/views/test_document_views.py
+++ b/deckhand/tests/unit/views/test_document_views.py
@@ -14,10 +14,10 @@
14 14
15from deckhand.control.views import document 15from deckhand.control.views import document
16from deckhand.tests import test_utils 16from deckhand.tests import test_utils
17from deckhand.tests.unit.db import base 17from deckhand.tests.unit import base
18 18
19 19
20class TestDocumentViews(base.TestDbBase): 20class TestDocumentViews(base.DeckhandWithDBTestCase):
21 21
22 def setUp(self): 22 def setUp(self):
23 super(TestDocumentViews, self).setUp() 23 super(TestDocumentViews, self).setUp()
diff --git a/deckhand/tests/unit/views/test_revision_tag_views.py b/deckhand/tests/unit/views/test_revision_tag_views.py
index 47592a5..5ad18f0 100644
--- a/deckhand/tests/unit/views/test_revision_tag_views.py
+++ b/deckhand/tests/unit/views/test_revision_tag_views.py
@@ -15,10 +15,10 @@
15from deckhand.control.views import revision_tag 15from deckhand.control.views import revision_tag
16from deckhand.db.sqlalchemy import api as db_api 16from deckhand.db.sqlalchemy import api as db_api
17from deckhand.tests import test_utils 17from deckhand.tests import test_utils
18from deckhand.tests.unit.db import base 18from deckhand.tests.unit import base
19 19
20 20
21class TestRevisionViews(base.TestDbBase): 21class TestRevisionViews(base.DeckhandWithDBTestCase):
22 22
23 def setUp(self): 23 def setUp(self):
24 super(TestRevisionViews, self).setUp() 24 super(TestRevisionViews, self).setUp()
diff --git a/deckhand/tests/unit/views/test_revision_views.py b/deckhand/tests/unit/views/test_revision_views.py
index 6bed962..05e4511 100644
--- a/deckhand/tests/unit/views/test_revision_views.py
+++ b/deckhand/tests/unit/views/test_revision_views.py
@@ -14,10 +14,10 @@
14 14
15from deckhand.control.views import revision 15from deckhand.control.views import revision
16from deckhand.tests import test_utils 16from deckhand.tests import test_utils
17from deckhand.tests.unit.db import base 17from deckhand.tests.unit import base
18 18
19 19
20class TestRevisionViews(base.TestDbBase): 20class TestRevisionViews(base.DeckhandWithDBTestCase):
21 21
22 def setUp(self): 22 def setUp(self):
23 super(TestRevisionViews, self).setUp() 23 super(TestRevisionViews, self).setUp()