summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testapi/etc/config.ini2
-rw-r--r--testapi/opnfv_testapi/common/check.py14
-rw-r--r--testapi/opnfv_testapi/common/constants.py1
-rw-r--r--testapi/opnfv_testapi/common/message.py8
-rw-r--r--testapi/opnfv_testapi/handlers/base_handlers.py2
-rw-r--r--testapi/opnfv_testapi/handlers/result_handlers.py48
-rw-r--r--testapi/opnfv_testapi/models/result_models.py4
-rw-r--r--testapi/opnfv_testapi/router/url_mappings.py1
-rw-r--r--testapi/opnfv_testapi/tests/unit/common/test_config.py2
-rw-r--r--testapi/opnfv_testapi/tests/unit/executor.py14
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_project.py17
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_result.py39
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/podsController.js11
-rw-r--r--testapi/opnfv_testapi/ui/components/projects/projectsController.js12
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html2
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js26
16 files changed, 84 insertions, 119 deletions
diff --git a/testapi/etc/config.ini b/testapi/etc/config.ini
index 86cb0ca..5f568a7 100644
--- a/testapi/etc/config.ini
+++ b/testapi/etc/config.ini
@@ -15,7 +15,7 @@ port = 8000
results_per_page = 20
# With debug_on set to true, error traces will be shown in HTTP responses
-debug = True
+debug = False
token_check = False
authenticate = True
diff --git a/testapi/opnfv_testapi/common/check.py b/testapi/opnfv_testapi/common/check.py
index 1a66dd7..7f866dd 100644
--- a/testapi/opnfv_testapi/common/check.py
+++ b/testapi/opnfv_testapi/common/check.py
@@ -47,6 +47,20 @@ def is_authorized(method):
return wrapper
+def is_allowed(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)
+ if data:
+ raises.Unauthorized(message.tied_with_resource())
+ ret = yield gen.coroutine(method)(self, *args, **kwargs)
+ raise gen.Return(ret)
+ return wrapper
+
+
def valid_token(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
diff --git a/testapi/opnfv_testapi/common/constants.py b/testapi/opnfv_testapi/common/constants.py
index 70c9223..c7f82d9 100644
--- a/testapi/opnfv_testapi/common/constants.py
+++ b/testapi/opnfv_testapi/common/constants.py
@@ -1,4 +1,3 @@
TESTAPI_ID = 'testapi_id'
CSRF_TOKEN = 'csrf_token'
-ROLE = 'role'
TESTAPI_USERS = ['opnfv-testapi-users']
diff --git a/testapi/opnfv_testapi/common/message.py b/testapi/opnfv_testapi/common/message.py
index b92b7f0..52cc2ad 100644
--- a/testapi/opnfv_testapi/common/message.py
+++ b/testapi/opnfv_testapi/common/message.py
@@ -10,10 +10,6 @@ not_found_base = 'Could Not Found'
exist_base = 'Already Exists'
-def key_error(key):
- return "KeyError: '{}'".format(key)
-
-
def no_body():
return 'No Body'
@@ -64,3 +60,7 @@ def must_int(name):
def no_permission():
return 'You do not have permission to perform this action'
+
+
+def tied_with_resource():
+ return 'Selected resource is associated with other resources'
diff --git a/testapi/opnfv_testapi/handlers/base_handlers.py b/testapi/opnfv_testapi/handlers/base_handlers.py
index 537077d..ed4aeb2 100644
--- a/testapi/opnfv_testapi/handlers/base_handlers.py
+++ b/testapi/opnfv_testapi/handlers/base_handlers.py
@@ -179,6 +179,7 @@ class GenericApiHandler(web.RequestHandler):
@gen.coroutine
@check.not_exist
@check.is_authorized
+ @check.is_allowed
def _delete(self, data, query=None):
yield dbapi.db_delete(self.table, query)
self.finish_request()
@@ -189,6 +190,7 @@ class GenericApiHandler(web.RequestHandler):
@check.not_exist
@check.updated_one_not_exist
@check.is_authorized
+ @check.is_allowed
def _update(self, data, query=None, **kwargs):
data = self.table_cls.from_dict(data)
update_req = self._update_requests(data)
diff --git a/testapi/opnfv_testapi/handlers/result_handlers.py b/testapi/opnfv_testapi/handlers/result_handlers.py
index b0691cd..74acb2e 100644
--- a/testapi/opnfv_testapi/handlers/result_handlers.py
+++ b/testapi/opnfv_testapi/handlers/result_handlers.py
@@ -8,12 +8,9 @@
##############################################################################
from datetime import datetime
from datetime import timedelta
-import json
-import logging
from bson import objectid
-from opnfv_testapi.common import constants
from opnfv_testapi.common import message
from opnfv_testapi.common import raises
from opnfv_testapi.common.config import CONF
@@ -41,7 +38,6 @@ class GenericResultHandler(base_handlers.GenericApiHandler):
query = dict()
date_range = dict()
- query['public'] = {'$not': {'$eq': 'false'}}
for k in self.request.query_arguments.keys():
v = self.get_query_argument(k)
if k == 'project' or k == 'pod' or k == 'case':
@@ -60,13 +56,6 @@ class GenericResultHandler(base_handlers.GenericApiHandler):
date_range.update({'$lt': str(v)})
elif 'build_id' in k:
query[k] = self.get_int(k, v)
- elif k == 'signed':
- username = self.get_secure_cookie(constants.TESTAPI_ID)
- role = self.get_secure_cookie(constants.ROLE)
- if role:
- del query['public']
- if role != "reviewer":
- query['user'] = username
elif k not in ['last', 'page', 'descend']:
query[k] = v
if date_range:
@@ -121,10 +110,9 @@ class ResultsCLHandler(GenericResultHandler):
- criteria : the global criteria status passed or failed
- trust_indicator : evaluate the stability of the test case
to avoid running systematically long and stable test case
- - signed : get logined user result
GET /results/project=functest&case=vPing&version=Arno-R1 \
- &pod=pod_name&period=15&signed
+ &pod=pod_name&period=15
@return 200: all test results consist with query,
empty list if no result is found
@rtype: L{TestResults}
@@ -184,10 +172,6 @@ class ResultsCLHandler(GenericResultHandler):
@type trust_indicator: L{float}
@in trust_indicator: query
@required trust_indicator: False
- @param signed: user results or all results
- @type signed: L{string}
- @in signed: query
- @required signed: False
@param descend: true, newest2oldest; false, oldest2newest
@type descend: L{string}
@in descend: query
@@ -231,36 +215,8 @@ class ResultsCLHandler(GenericResultHandler):
values_check=values_check)
-class ResultsUploadHandler(ResultsCLHandler):
- @swagger.operation(nickname="uploadTestResult")
- def post(self):
- """
- @description: upload and create a test result
- @param body: result to be created
- @type body: L{ResultCreateRequest}
- @in body: body
- @rtype: L{CreateResponse}
- @return 200: result is created.
- @raise 404: pod/project/testcase not exist
- @raise 400: body/pod_name/project_name/case_name not provided
- """
- logging.info('file upload')
- fileinfo = self.request.files['file'][0]
- is_public = self.get_body_argument('public')
- logging.warning('public:%s', is_public)
- logging.info('results is :%s', fileinfo['filename'])
- logging.info('results is :%s', fileinfo['body'])
- self.json_args = json.loads(fileinfo['body']).copy()
- self.json_args['public'] = is_public
-
- openid = self.get_secure_cookie(constants.TESTAPI_ID)
- if openid:
- self.json_args['user'] = openid
-
- super(ResultsUploadHandler, self).post()
-
-
class ResultsGURHandler(GenericResultHandler):
+
@swagger.operation(nickname='getTestResultById')
def get(self, result_id):
"""
diff --git a/testapi/opnfv_testapi/models/result_models.py b/testapi/opnfv_testapi/models/result_models.py
index 1dbe729..f8379d8 100644
--- a/testapi/opnfv_testapi/models/result_models.py
+++ b/testapi/opnfv_testapi/models/result_models.py
@@ -62,8 +62,6 @@ class ResultCreateRequest(base_models.ModelBase):
build_tag=None,
scenario=None,
criteria=None,
- user=None,
- public="true",
trust_indicator=None):
self.pod_name = pod_name
self.project_name = project_name
@@ -76,8 +74,6 @@ class ResultCreateRequest(base_models.ModelBase):
self.build_tag = build_tag
self.scenario = scenario
self.criteria = criteria
- self.user = user
- self.public = public
self.trust_indicator = trust_indicator if trust_indicator else TI(0)
def __eq__(self, other):
diff --git a/testapi/opnfv_testapi/router/url_mappings.py b/testapi/opnfv_testapi/router/url_mappings.py
index b9dd231..8f01a66 100644
--- a/testapi/opnfv_testapi/router/url_mappings.py
+++ b/testapi/opnfv_testapi/router/url_mappings.py
@@ -49,7 +49,6 @@ mappings = [
# Push results with mandatory request payload parameters
# (project, case, and pod)
(r"/api/v1/results", result_handlers.ResultsCLHandler),
- (r'/api/v1/results/upload', result_handlers.ResultsUploadHandler),
(r"/api/v1/results/([^/]+)", result_handlers.ResultsGURHandler),
(r"/api/v1/deployresults", deploy_handlers.DeployResultsHandler),
(r"/api/v1/deployresults/([^/]+)", deploy_handlers.DeployResultHandler),
diff --git a/testapi/opnfv_testapi/tests/unit/common/test_config.py b/testapi/opnfv_testapi/tests/unit/common/test_config.py
index 6d160ce..8e4966f 100644
--- a/testapi/opnfv_testapi/tests/unit/common/test_config.py
+++ b/testapi/opnfv_testapi/tests/unit/common/test_config.py
@@ -11,7 +11,7 @@ def test_config_normal(mocker, config_normal):
assert CONF.mongo_url == 'mongodb://127.0.0.1:27017/'
assert CONF.mongo_dbname == 'test_results_collection'
assert CONF.api_port == 8000
- assert CONF.api_debug is True
+ assert CONF.api_debug is False
assert CONF.api_token_check is False
assert CONF.api_authenticate is True
assert CONF.ui_url == 'http://localhost:8000'
diff --git a/testapi/opnfv_testapi/tests/unit/executor.py b/testapi/opnfv_testapi/tests/unit/executor.py
index 743c076..d08782c 100644
--- a/testapi/opnfv_testapi/tests/unit/executor.py
+++ b/testapi/opnfv_testapi/tests/unit/executor.py
@@ -43,20 +43,6 @@ def mock_valid_lfid():
return _mock_valid_lfid
-def upload(excepted_status, excepted_response):
- def _upload(create_request):
- @functools.wraps(create_request)
- def wrap(self):
- request = create_request(self)
- status, body = self.upload(request)
- if excepted_status == httplib.OK:
- getattr(self, excepted_response)(body)
- else:
- self.assertIn(excepted_response, body)
- return wrap
- return _upload
-
-
def create(excepted_status, excepted_response):
def _create(create_request):
@functools.wraps(create_request)
diff --git a/testapi/opnfv_testapi/tests/unit/handlers/test_project.py b/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
index cbd1a4e..884dd68 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
@@ -12,6 +12,7 @@ import urllib
from opnfv_testapi.common import message
from opnfv_testapi.models import project_models
+from opnfv_testapi.models import testcase_models as tcm
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit.handlers import test_base as base
@@ -23,6 +24,9 @@ class TestProjectBase(base.TestBase):
'qtip-ssh test')
self.req_e = project_models.ProjectCreateRequest('functest',
'functest test')
+ self.testcase_d = tcm.TestcaseCreateRequest.from_dict(
+ self.load_json('testcase_d'))
+ self.project = 'qtip'
self.get_res = project_models.Project
self.list_res = project_models.Projects
self.update_res = project_models.Project
@@ -150,6 +154,13 @@ class TestProjectUpdate(TestProjectBase):
return self.req_d, self.req_d.name
@executor.mock_valid_lfid()
+ @executor.update(httplib.UNAUTHORIZED, message.tied_with_resource())
+ def test_updateNotAllowed(self):
+ self.create_help('/api/v1/projects/%s/cases', self.testcase_d, self.req_d.name)
+ req = project_models.ProjectUpdateRequest('apex', 'apex test')
+ return req, self.req_d.name
+
+ @executor.mock_valid_lfid()
@executor.update(httplib.OK, '_assert_update')
def test_success(self):
req = project_models.ProjectUpdateRequest('apex', 'apex test')
@@ -178,6 +189,12 @@ class TestProjectDelete(TestProjectBase):
return 'notFound'
@executor.mock_valid_lfid()
+ @executor.delete(httplib.UNAUTHORIZED, message.tied_with_resource())
+ def test_deleteNotAllowed(self):
+ self.create_help('/api/v1/projects/%s/cases', self.testcase_d, self.req_d.name)
+ return self.req_d.name
+
+ @executor.mock_valid_lfid()
@executor.delete(httplib.OK, '_assert_delete')
def test_success(self):
return self.req_d.name
diff --git a/testapi/opnfv_testapi/tests/unit/handlers/test_result.py b/testapi/opnfv_testapi/tests/unit/handlers/test_result.py
index f1f055e..c07d792 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_result.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_result.py
@@ -10,7 +10,6 @@ import copy
from datetime import datetime
from datetime import timedelta
import httplib
-import json
import urllib
from opnfv_testapi.common import message
@@ -46,22 +45,6 @@ class TestResultBase(base.TestBase):
_, res = self.create_d()
return res.href.split('/')[-1]
- def upload(self, req):
- if req and not isinstance(req, str) and hasattr(req, 'format'):
- req = req.format()
- res = self.fetch(self.basePath + '/upload',
- method='POST',
- body=json.dumps(req),
- headers=self.headers)
-
- return self._get_return(res, self.create_res)
-
-
-class TestResultUpload(TestResultBase):
- @executor.upload(httplib.BAD_REQUEST, message.key_error('file'))
- def test_filenotfind(self):
- return None
-
class TestResultCreate(TestResultBase):
@executor.create(httplib.BAD_REQUEST, message.no_body())
@@ -197,16 +180,6 @@ class TestResultGet(TestResultBase):
def test_queryLast(self):
return self._set_query(last=1)
- @executor.query(httplib.OK, '_query_success', 4)
- def test_queryPublic(self):
- self._create_public_data()
- return self._set_query()
-
- @executor.query(httplib.OK, '_query_success', 1)
- def test_queryPrivate(self):
- self._create_private_data()
- return self._set_query(public='false')
-
@executor.query(httplib.OK, '_query_period_one', 1)
def test_combination(self):
return self._set_query('pod',
@@ -266,18 +239,6 @@ class TestResultGet(TestResultBase):
self.create(req)
return req
- def _create_public_data(self, **kwargs):
- req = copy.deepcopy(self.req_d)
- req.public = 'true'
- self.create(req)
- return req
-
- def _create_private_data(self, **kwargs):
- req = copy.deepcopy(self.req_d)
- req.public = 'false'
- self.create(req)
- return req
-
def _set_query(self, *args, **kwargs):
def get_value(arg):
if arg in ['pod', 'project', 'case']:
diff --git a/testapi/opnfv_testapi/ui/components/pods/podsController.js b/testapi/opnfv_testapi/ui/components/pods/podsController.js
index 95e3571..38e084d 100644
--- a/testapi/opnfv_testapi/ui/components/pods/podsController.js
+++ b/testapi/opnfv_testapi/ui/components/pods/podsController.js
@@ -137,7 +137,6 @@
function batchDelete(){
var index;
var checkedBox = [];
- console.log(ctrl.checkBox)
for(index in ctrl.checkBox){
if(!ctrl.showError){
if(ctrl.checkBox[index]){
@@ -153,7 +152,13 @@
* message
*/
function openBatchDeleteModal() {
- confirmModal("Delete",ctrl.batchDelete);
+ var deleteObjects = []
+ for(var index in ctrl.checkBox){
+ if(ctrl.checkBox[index]){
+ deleteObjects.push(ctrl.data.pods[index].name)
+ }
+ }
+ confirmModal("Delete", 'pods', ctrl.batchDelete, deleteObjects);
}
/**
@@ -162,7 +167,7 @@
*/
function openDeleteModal(name) {
console.log(name)
- confirmModal("Delete", ctrl.podDelete, name);
+ confirmModal("Delete", 'pod', ctrl.podDelete, name);
}
/**
diff --git a/testapi/opnfv_testapi/ui/components/projects/projectsController.js b/testapi/opnfv_testapi/ui/components/projects/projectsController.js
index 940c1e2..0d0ec99 100644
--- a/testapi/opnfv_testapi/ui/components/projects/projectsController.js
+++ b/testapi/opnfv_testapi/ui/components/projects/projectsController.js
@@ -204,7 +204,15 @@
* message
*/
function openBatchDeleteModal() {
- confirmModal("Delete",ctrl.batchDelete);
+ var deleteObjects = []
+ ctrl.checkBox.forEach(function(project, index){
+ if(!ctrl.showError){
+ if(project){
+ deleteObjects.push(ctrl.data.projects[index].name)
+ }
+ }
+ });
+ confirmModal("Delete", 'projects', ctrl.batchDelete, deleteObjects);
}
/**
@@ -212,7 +220,7 @@
* message
*/
function openDeleteModal(name) {
- confirmModal("Delete", ctrl.projectDelete, name);
+ confirmModal("Delete",'projects', ctrl.projectDelete, name);
}
ctrl.listProjects();
diff --git a/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html b/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html
index e5397e0..417af37 100644
--- a/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html
+++ b/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html
@@ -10,7 +10,7 @@
</div>
<div class="Delete" ng-class="{ 'hidden': confirmModal.data.text!='Delete' }">
<div class="form-group">
- <label for="confirmText"> You are about to delete.</label>
+ <label for="confirmText"> You are about to delete following {{confirmModal.data.resource}} : {{confirmModal.deleteObjects}} </label>
<br>
Do you want to proceed?
</div>
diff --git a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
index 42cf873..c115a3c 100644
--- a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
+++ b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
@@ -11,7 +11,7 @@
* Opens confirm modal dialog with input textbox
*/
function confirmModal($uibModal) {
- return function(text, successHandler, name) {
+ return function(text, resource, successHandler, name) {
$uibModal.open({
templateUrl: 'testapi-ui/shared/alerts/confirmModal.html',
controller: 'CustomConfirmModalController as confirmModal',
@@ -20,8 +20,10 @@
data: function () {
return {
text: text,
+ resource: resource,
successHandler: successHandler,
name: name
+
};
}
}
@@ -44,8 +46,26 @@
ctrl.confirm = confirm;
ctrl.cancel = cancel;
-
+ ctrl.buildDeleteObjects = buildDeleteObjects;
ctrl.data = angular.copy(data);
+
+ function buildDeleteObjects(){
+ ctrl.deleteObjects = '';
+ if (typeof ctrl.data.name === 'string') {
+ ctrl.deleteObjects = ctrl.data.name
+ }
+ else{
+ for(var index in ctrl.data.name){
+ if(index==0){
+ ctrl.deleteObjects += ctrl.data.name[index]
+ }
+ else{
+ ctrl.deleteObjects += ", "+ ctrl.data.name[index]
+ }
+
+ }
+ }
+ }
/**
* Initiate confirmation and call the success handler with the
* input text.
@@ -63,5 +83,7 @@
function cancel() {
$uibModalInstance.dismiss('cancel');
}
+
+ ctrl.buildDeleteObjects();
}
})();