From aaaf3f1c8402c8c18dad0f945b9ed77efb1cd8ee Mon Sep 17 00:00:00 2001 From: Alexander Chadin Date: Thu, 21 Apr 2016 18:57:42 +0300 Subject: [PATCH] Remove using of UUID field in POST methods of Watcher API This patch set removes the possibility of using UUID field in POST methods of Watcher API. Closes-Bug: #1572625 Change-Id: I88a8aa5346e937e3e9409b55da3316cbe1ed832a --- watcher/api/controllers/v1/action.py | 2 +- watcher/api/controllers/v1/action_plan.py | 2 +- watcher/api/controllers/v1/audit.py | 3 --- watcher/api/controllers/v1/audit_template.py | 3 ++- watcher/tests/api/v1/test_audit_templates.py | 19 ++++++++++++++++-- watcher/tests/api/v1/test_audits.py | 21 ++++++++++++++++---- watcher/tests/db/test_audit.py | 17 +++++----------- watcher/tests/db/test_audit_template.py | 12 ----------- 8 files changed, 43 insertions(+), 36 deletions(-) diff --git a/watcher/api/controllers/v1/action.py b/watcher/api/controllers/v1/action.py index b67f51c8e..152bba25f 100644 --- a/watcher/api/controllers/v1/action.py +++ b/watcher/api/controllers/v1/action.py @@ -119,7 +119,7 @@ class Action(base.APIBase): self.action_next_uuid = None # raise e - uuid = types.uuid + uuid = wtypes.wsattr(types.uuid, readonly=True) """Unique UUID for this action""" action_plan_uuid = wsme.wsproperty(types.uuid, _get_action_plan_uuid, diff --git a/watcher/api/controllers/v1/action_plan.py b/watcher/api/controllers/v1/action_plan.py index d7e5924c7..079d44caa 100644 --- a/watcher/api/controllers/v1/action_plan.py +++ b/watcher/api/controllers/v1/action_plan.py @@ -143,7 +143,7 @@ class ActionPlan(base.APIBase): except exception.ActionNotFound: self._first_action_uuid = None - uuid = types.uuid + uuid = wtypes.wsattr(types.uuid, readonly=True) """Unique UUID for this action plan""" first_action_uuid = wsme.wsproperty( diff --git a/watcher/api/controllers/v1/audit.py b/watcher/api/controllers/v1/audit.py index a57e67f37..19cf30209 100644 --- a/watcher/api/controllers/v1/audit.py +++ b/watcher/api/controllers/v1/audit.py @@ -51,8 +51,6 @@ from watcher import objects class AuditPostType(wtypes.Base): - uuid = wtypes.wsattr(types.uuid, mandatory=False) - audit_template_uuid = wtypes.wsattr(types.uuid, mandatory=True) type = wtypes.wsattr(wtypes.text, mandatory=True) @@ -68,7 +66,6 @@ class AuditPostType(wtypes.Base): raise exception.AuditTypeNotFound(audit_type=self.type) return Audit( - uuid=self.uuid or utils.generate_uuid(), audit_template_id=self.audit_template_uuid, type=self.type, deadline=self.deadline) diff --git a/watcher/api/controllers/v1/audit_template.py b/watcher/api/controllers/v1/audit_template.py index 6e1ee2c73..00dc9d492 100644 --- a/watcher/api/controllers/v1/audit_template.py +++ b/watcher/api/controllers/v1/audit_template.py @@ -95,7 +95,8 @@ class AuditTemplate(base.APIBase): between the internal object model and the API representation of an audit template. """ - uuid = types.uuid + + uuid = wtypes.wsattr(types.uuid, readonly=True) """Unique UUID for this audit template""" name = wtypes.text diff --git a/watcher/tests/api/v1/test_audit_templates.py b/watcher/tests/api/v1/test_audit_templates.py index eb4023948..643bdc6e8 100644 --- a/watcher/tests/api/v1/test_audit_templates.py +++ b/watcher/tests/api/v1/test_audit_templates.py @@ -392,6 +392,7 @@ class TestPost(api_base.FunctionalTest): audit_template_dict = api_utils.audit_template_post_data() test_time = datetime.datetime(2000, 1, 1, 0, 0) mock_utcnow.return_value = test_time + del audit_template_dict['uuid'] response = self.post_json('/audit_templates', audit_template_dict) self.assertEqual('application/json', response.content_type) @@ -399,10 +400,9 @@ class TestPost(api_base.FunctionalTest): # Check location header self.assertIsNotNone(response.location) expected_location = \ - '/v1/audit_templates/%s' % audit_template_dict['uuid'] + '/v1/audit_templates/%s' % response.json['uuid'] self.assertEqual(urlparse.urlparse(response.location).path, expected_location) - self.assertEqual(audit_template_dict['uuid'], response.json['uuid']) self.assertNotIn('updated_at', response.json.keys) self.assertNotIn('deleted_at', response.json.keys) return_created_at = timeutils.parse_isotime( @@ -417,6 +417,7 @@ class TestPost(api_base.FunctionalTest): ) as cn_mock: audit_template_dict = api_utils.audit_template_post_data( goal='DUMMY') + del audit_template_dict['uuid'] response = self.post_json('/audit_templates', audit_template_dict) self.assertEqual(audit_template_dict['goal'], response.json['goal']) @@ -447,6 +448,20 @@ class TestPost(api_base.FunctionalTest): self.assertEqual(400, response.status_int) assert not cn_mock.called + def test_create_audit_template_with_uuid(self): + with mock.patch.object( + self.dbapi, + 'create_audit_template', + wraps=self.dbapi.create_audit_template + ) as cn_mock: + audit_template_dict = api_utils.audit_template_post_data() + + response = self.post_json('/audit_templates', audit_template_dict, + expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(400, response.status_int) + assert not cn_mock.called + class TestDelete(api_base.FunctionalTest): diff --git a/watcher/tests/api/v1/test_audits.py b/watcher/tests/api/v1/test_audits.py index 0ef027084..0e7a0ecfa 100644 --- a/watcher/tests/api/v1/test_audits.py +++ b/watcher/tests/api/v1/test_audits.py @@ -433,6 +433,7 @@ class TestPost(api_base.FunctionalTest): mock_utcnow.return_value = test_time audit_dict = post_get_test_audit(state=objects.audit.State.PENDING) + del audit_dict['uuid'] del audit_dict['state'] response = self.post_json('/audits', audit_dict) @@ -440,10 +441,9 @@ class TestPost(api_base.FunctionalTest): self.assertEqual(201, response.status_int) # Check location header self.assertIsNotNone(response.location) - expected_location = '/v1/audits/%s' % audit_dict['uuid'] + expected_location = '/v1/audits/%s' % response.json['uuid'] self.assertEqual(urlparse.urlparse(response.location).path, expected_location) - self.assertEqual(audit_dict['uuid'], response.json['uuid']) self.assertEqual(objects.audit.State.PENDING, response.json['state']) self.assertNotIn('updated_at', response.json.keys) @@ -473,6 +473,7 @@ class TestPost(api_base.FunctionalTest): mock_utcnow.return_value = test_time audit_dict = post_get_test_audit() + del audit_dict['uuid'] del audit_dict['state'] # Make the audit template UUID some garbage value audit_dict['audit_template_uuid'] = ( @@ -492,6 +493,7 @@ class TestPost(api_base.FunctionalTest): audit_dict = post_get_test_audit(state=objects.audit.State.PENDING) state = audit_dict['state'] + del audit_dict['uuid'] del audit_dict['state'] with mock.patch.object(self.dbapi, 'create_audit', wraps=self.dbapi.create_audit) as cn_mock: @@ -520,9 +522,20 @@ class TestPost(api_base.FunctionalTest): with mock.patch.object(deapi.DecisionEngineAPI, 'trigger_audit') as de_mock: audit_dict = post_get_test_audit(state=objects.audit.State.PENDING) + del audit_dict['uuid'] del audit_dict['state'] - self.post_json('/audits', audit_dict) - de_mock.assert_called_once_with(mock.ANY, audit_dict['uuid']) + response = self.post_json('/audits', audit_dict) + de_mock.assert_called_once_with(mock.ANY, response.json['uuid']) + + @mock.patch.object(deapi.DecisionEngineAPI, 'trigger_audit') + def test_create_audit_with_uuid(self, mock_trigger_audit): + mock_trigger_audit.return_value = mock.ANY + + audit_dict = post_get_test_audit(state=objects.audit.State.PENDING) + response = self.post_json('/audits', audit_dict, expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(400, response.status_int) + assert not mock_trigger_audit.called # class TestDelete(api_base.FunctionalTest): diff --git a/watcher/tests/db/test_audit.py b/watcher/tests/db/test_audit.py index 48a41df85..3866381a7 100644 --- a/watcher/tests/db/test_audit.py +++ b/watcher/tests/db/test_audit.py @@ -371,13 +371,13 @@ class DbAuditTestCase(base.DbTestCase): self.context, audit['id']) def test_destroy_audit_by_uuid(self): - uuid = w_utils.generate_uuid() - self._create_test_audit(uuid=uuid) + audit = self._create_test_audit() self.assertIsNotNone(self.dbapi.get_audit_by_uuid(self.context, - uuid)) - self.dbapi.destroy_audit(uuid) + audit['uuid'])) + self.dbapi.destroy_audit(audit['uuid']) self.assertRaises(exception.AuditNotFound, - self.dbapi.get_audit_by_uuid, self.context, uuid) + self.dbapi.get_audit_by_uuid, self.context, + audit['uuid']) def test_destroy_audit_that_does_not_exist(self): self.assertRaises(exception.AuditNotFound, @@ -389,10 +389,3 @@ class DbAuditTestCase(base.DbTestCase): self.assertEqual(audit['id'], action_plan.audit_id) self.assertRaises(exception.AuditReferenced, self.dbapi.destroy_audit, audit['id']) - - def test_create_audit_already_exists(self): - uuid = w_utils.generate_uuid() - self._create_test_audit(id=1, uuid=uuid) - self.assertRaises(exception.AuditAlreadyExists, - self._create_test_audit, - id=2, uuid=uuid) diff --git a/watcher/tests/db/test_audit_template.py b/watcher/tests/db/test_audit_template.py index f38ae7abf..013f4bb6c 100644 --- a/watcher/tests/db/test_audit_template.py +++ b/watcher/tests/db/test_audit_template.py @@ -358,15 +358,3 @@ class DbAuditTemplateTestCase(base.DbTestCase): utils.create_test_audit_template, uuid=w_utils.generate_uuid(), name='audit_template_name') - - def test_audit_template_create_same_uuid(self): - uuid = w_utils.generate_uuid() - audit_template1 = utils.create_test_audit_template( - uuid=uuid, - name='audit_template_name_1') - self.assertEqual(audit_template1['uuid'], audit_template1.uuid) - self.assertRaises( - exception.AuditTemplateAlreadyExists, - utils.create_test_audit_template, - uuid=uuid, - name='audit_template_name_2')