Prevent to delete the pods 13/52613/8
authorthuva4 <tharma.thuva@gmail.com>
Mon, 26 Feb 2018 04:18:45 +0000 (09:48 +0530)
committerthuva4 <tharma.thuva@gmail.com>
Thu, 1 Mar 2018 06:59:16 +0000 (12:29 +0530)
Do not allow to delete pods which are associated
with test-results

JIRA: RELENG-350

Change-Id: I8cb306d719acebff257048f08bcb981d81c64513
Signed-off-by: thuva4 <tharma.thuva@gmail.com>
testapi/opnfv_testapi/common/check.py
testapi/opnfv_testapi/handlers/base_handlers.py
testapi/opnfv_testapi/tests/unit/handlers/test_pod.py
testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py

index 7f866dd..77b48f5 100644 (file)
@@ -35,7 +35,7 @@ def is_authorized(method):
                 if type(query) is not dict:
                     query_data = query()
                 else:
-                    if self.json_args is None:
+                    if self.json_args is None or 'name' not in self.json_args:
                         query_data = query
                     else:
                         query_data = self.json_args
@@ -47,13 +47,22 @@ def is_authorized(method):
     return wrapper
 
 
-def is_allowed(method):
+def is_reource_tied(method):
     @functools.wraps(method)
     def wrapper(self, *args, **kwargs):
-        if self.table == 'projects':
-            query_data = {}
-            query_data['project_name'] = kwargs.get('query')['name']
-            data = yield dbapi.db_find_one('testcases', query_data)
+        query_data = {}
+        tied_map_tables = {
+            'projects': ('testcases', 'project_name'),
+            'pods': ('results', 'pod_name'),
+            'testcases': ('results', 'case_name')
+        }
+        if self.table in tied_map_tables:
+            if method.__name__ == '_update':
+                if 'name' not in self.json_args:
+                    ret = yield gen.coroutine(method)(self, *args, **kwargs)
+                    raise gen.Return(ret)
+            query_data[tied_map_tables[self.table][1]] = kwargs.get('query')['name']
+            data = yield dbapi.db_find_one(tied_map_tables[self.table][0], query_data)
             if data:
                 raises.Unauthorized(message.tied_with_resource())
         ret = yield gen.coroutine(method)(self, *args, **kwargs)
index ed4aeb2..350c38d 100644 (file)
@@ -179,7 +179,7 @@ class GenericApiHandler(web.RequestHandler):
     @gen.coroutine
     @check.not_exist
     @check.is_authorized
-    @check.is_allowed
+    @check.is_reource_tied
     def _delete(self, data, query=None):
         yield dbapi.db_delete(self.table, query)
         self.finish_request()
@@ -190,7 +190,7 @@ class GenericApiHandler(web.RequestHandler):
     @check.not_exist
     @check.updated_one_not_exist
     @check.is_authorized
-    @check.is_allowed
+    @check.is_reource_tied
     def _update(self, data, query=None, **kwargs):
         data = self.table_cls.from_dict(data)
         update_req = self._update_requests(data)
index d1eedc0..28d29b5 100644 (file)
@@ -10,6 +10,7 @@ import httplib
 
 from opnfv_testapi.common import message
 from opnfv_testapi.models import pod_models as pm
+from opnfv_testapi.models import result_models as rm
 from opnfv_testapi.tests.unit import executor
 from opnfv_testapi.tests.unit import fake_pymongo
 from opnfv_testapi.tests.unit.handlers import test_base as base
@@ -23,6 +24,8 @@ class TestPodBase(base.TestBase):
         self.basePath = '/api/v1/pods'
         self.req_d = pm.PodCreateRequest.from_dict(self.pod_d.format())
         self.req_e = pm.PodCreateRequest.from_dict(self.pod_e.format())
+        self.results_d = rm.ResultCreateRequest.from_dict(
+            self.load_json('test_result'))
 
     def assert_get_body(self, pod, req=None):
         if not req:
@@ -101,3 +104,37 @@ class TestPodGet(TestPodBase):
                 self.assert_get_body(pod)
             else:
                 self.assert_get_body(pod, self.req_e)
+
+
+class TestPodDelete(TestPodBase):
+    @executor.mock_valid_lfid()
+    def setUp(self):
+        super(TestPodDelete, self).setUp()
+        fake_pymongo.pods.insert(self.pod_d.format())
+        fake_pymongo.projects.insert({'name': self.results_d.project_name})
+        fake_pymongo.testcases.insert({'name': self.results_d.case_name,
+                                       'project_name': self.results_d.project_name})
+
+    @executor.delete(httplib.BAD_REQUEST, message.not_login())
+    def test_notlogin(self):
+        return self.pod_d.name
+
+    @executor.delete(httplib.NOT_FOUND, message.not_found_base)
+    def test_notFound(self):
+        return 'notFound'
+
+    @executor.mock_valid_lfid()
+    @executor.delete(httplib.UNAUTHORIZED, message.tied_with_resource())
+    def test_deleteNotAllowed(self):
+        self.create_help('/api/v1/results', self.results_d)
+        return self.pod_d.name
+
+    @executor.mock_valid_lfid()
+    @executor.delete(httplib.OK, '_assert_delete')
+    def test_success(self):
+        return self.pod_d.name
+
+    def _assert_delete(self, body):
+        self.assertEqual(body, '')
+        code, body = self.get(self.pod_d.name)
+        self.assertEqual(code, httplib.NOT_FOUND)
index 9a2bf58..78f3ab1 100644 (file)
@@ -10,6 +10,7 @@ import httplib
 
 from opnfv_testapi.common import message
 from opnfv_testapi.models import testcase_models as tcm
+from opnfv_testapi.models import result_models as rm
 from opnfv_testapi.tests.unit import executor
 from opnfv_testapi.tests.unit import fake_pymongo
 from opnfv_testapi.tests.unit.handlers import test_base as base
@@ -32,6 +33,8 @@ class TestCaseBase(base.TestBase):
         self.basePath = '/api/v1/projects/%s/cases'
         fake_pymongo.projects.insert(self.project_e.format())
         print self.req_d.format()
+        self.results_d = rm.ResultCreateRequest.from_dict(
+            self.load_json('test_result'))
 
     def assert_body(self, case, req=None):
         if not req:
@@ -176,11 +179,20 @@ class TestCaseDelete(TestCaseBase):
     def setUp(self):
         super(TestCaseDelete, self).setUp()
         self.create_d()
+        fake_pymongo.pods.insert(self.pod_d.format())
+        fake_pymongo.projects.insert({'name': self.results_d.project_name})
+        fake_pymongo.testcases.insert({'name': self.results_d.case_name,
+                                       'project_name': self.results_d.project_name})
 
     @executor.delete(httplib.NOT_FOUND, message.not_found_base)
     def test_notFound(self):
         return 'notFound'
 
+    @executor.delete(httplib.UNAUTHORIZED, message.tied_with_resource())
+    def test_deleteNotAllowed(self):
+        print self.create_help('/api/v1/results', self.results_d)
+        return self.results_d.case_name
+
     @executor.delete(httplib.OK, '_delete_success')
     def test_success(self):
         return self.req_d.name