diff options
author | SerenaFeng <feng.xiaowei@zte.com.cn> | 2016-05-23 18:34:19 +0800 |
---|---|---|
committer | SerenaFeng <feng.xiaowei@zte.com.cn> | 2016-05-25 15:14:28 +0800 |
commit | f4f8328db358131963b3fa9e81677bf570b8d0aa (patch) | |
tree | 611efe5271abc45869ac164e79323f70c6783641 /utils/test/result_collection_api/resources | |
parent | 2e273acb2bb50394182575b1322b47ce17f8e53d (diff) |
add test result/dashboard related unittests in testAPI and refactor its response
modification:
add unittests for test result/dashboard
rename test_results table name in db to results
refactor response body
JIRA: FUNCTEST-255
Change-Id: I0657e6e95156a8c79072e7333fd8aaeb12d986e5
Signed-off-by: SerenaFeng <feng.xiaowei@zte.com.cn>
Diffstat (limited to 'utils/test/result_collection_api/resources')
3 files changed, 268 insertions, 259 deletions
diff --git a/utils/test/result_collection_api/resources/handlers.py b/utils/test/result_collection_api/resources/handlers.py index 161f89e7e..268d19aba 100644 --- a/utils/test/result_collection_api/resources/handlers.py +++ b/utils/test/result_collection_api/resources/handlers.py @@ -9,26 +9,27 @@ # feng.xiaowei@zte.com.cn refactor test_project to project 5-19-2016 # feng.xiaowei@zte.com.cn refactor response body 5-19-2016 # feng.xiaowei@zte.com.cn refactor pod/project response info 5-19-2016 -# feng.xiaowei@zte.com.cn refactor case related handler 5-20-2016 +# feng.xiaowei@zte.com.cn refactor testcase related handler 5-20-2016 +# feng.xiaowei@zte.com.cn refactor result related handler 5-23-2016 +# feng.xiaowei@zte.com.cn refactor dashboard related handler 5-24-2016 ############################################################################## import json +from datetime import datetime, timedelta from tornado.web import RequestHandler, asynchronous, HTTPError from tornado import gen -from datetime import datetime, timedelta -from models import TestResult, CreateResponse +from models import CreateResponse +from resources.result_models import TestResult from resources.testcase_models import Testcase from resources.project_models import Project from resources.pod_models import Pod from common.constants import DEFAULT_REPRESENTATION, HTTP_BAD_REQUEST, \ HTTP_NOT_FOUND, HTTP_FORBIDDEN from common.config import prepare_put_request - -from dashboard.dashboard_utils import get_dashboard_cases, \ - check_dashboard_ready_project, check_dashboard_ready_case, \ - get_dashboard_result +from dashboard.dashboard_utils import check_dashboard_ready_project, \ + check_dashboard_ready_case, get_dashboard_result def format_data(data, cls): @@ -48,7 +49,7 @@ class GenericApiHandler(RequestHandler): self.db = self.settings["db"] def prepare(self): - if not (self.request.method == "GET" or self.request.method == "DELETE"): + if self.request.method != "GET" and self.request.method != "DELETE": if self.request.headers.get("Content-Type") is not None: if self.request.headers["Content-Type"].startswith( DEFAULT_REPRESENTATION): @@ -67,6 +68,10 @@ class GenericApiHandler(RequestHandler): self.set_header("Content-Type", DEFAULT_REPRESENTATION) self.finish() + def _create_response(self, resource): + href = self.request.full_url() + '/' + resource + return CreateResponse(href=href).format() + class VersionHandler(RequestHandler): """ Display a message for the API version """ @@ -133,9 +138,7 @@ class PodHandler(GenericApiHandler): pod.creation_date = datetime.now() yield self.db.pods.insert(pod.format()) - - res = CreateResponse(self.request.full_url() + '/{}'.format(pod.name)) - self.finish_request(res.format()) + self.finish_request(self._create_response(pod.name)) @asynchronous @gen.coroutine @@ -223,10 +226,7 @@ class ProjectHandler(GenericApiHandler): project.creation_date = datetime.now() yield self.db.projects.insert(project.format()) - - res = CreateResponse(self.request.full_url() + '/{}'.format(project.name)) - self.finish_request(res.format()) - + self.finish_request(self._create_response(project.name)) @asynchronous @gen.coroutine @@ -372,8 +372,7 @@ class TestcaseHandler(GenericApiHandler): testcase.creation_date = datetime.now() yield self.db.testcases.insert(testcase.format()) - res = CreateResponse(self.request.full_url() + '/{}'.format(testcase.name)) - self.finish_request(res.format()) + self.finish_request(self._create_response(testcase.name)) @asynchronous @gen.coroutine @@ -502,46 +501,55 @@ class TestResultsHandler(GenericApiHandler): => get results with optional filters """ - project_arg = self.get_query_argument("project", None) - case_arg = self.get_query_argument("case", None) - pod_arg = self.get_query_argument("pod", None) - version_arg = self.get_query_argument("version", None) - installer_arg = self.get_query_argument("installer", None) - build_tag_arg = self.get_query_argument("build_tag", None) - scenario_arg = self.get_query_argument("scenario", None) - criteria_arg = self.get_query_argument("criteria", None) - period_arg = self.get_query_argument("period", None) - trust_indicator_arg = self.get_query_argument("trust_indicator", None) - # prepare request - get_request = dict() - if result_id is None: + query = dict() + if result_id is not None: + query["_id"] = result_id + answer = yield self.db.results.find_one(query) + if answer is None: + raise HTTPError(HTTP_NOT_FOUND, + "test result {} Not Exist".format(result_id)) + else: + answer = format_data(answer, TestResult) + else: + pod_arg = self.get_query_argument("pod", None) + project_arg = self.get_query_argument("project", None) + case_arg = self.get_query_argument("case", None) + version_arg = self.get_query_argument("version", None) + installer_arg = self.get_query_argument("installer", None) + build_tag_arg = self.get_query_argument("build_tag", None) + scenario_arg = self.get_query_argument("scenario", None) + criteria_arg = self.get_query_argument("criteria", None) + period_arg = self.get_query_argument("period", None) + trust_indicator_arg = self.get_query_argument("trust_indicator", + None) + if project_arg is not None: - get_request["project_name"] = project_arg + query["project_name"] = project_arg if case_arg is not None: - get_request["case_name"] = case_arg + query["case_name"] = case_arg if pod_arg is not None: - get_request["pod_name"] = pod_arg + query["pod_name"] = pod_arg if version_arg is not None: - get_request["version"] = version_arg + query["version"] = version_arg if installer_arg is not None: - get_request["installer"] = installer_arg + query["installer"] = installer_arg if build_tag_arg is not None: - get_request["build_tag"] = build_tag_arg + query["build_tag"] = build_tag_arg if scenario_arg is not None: - get_request["scenario"] = scenario_arg + query["scenario"] = scenario_arg if criteria_arg is not None: - get_request["criteria_tag"] = criteria_arg + query["criteria_tag"] = criteria_arg if trust_indicator_arg is not None: - get_request["trust_indicator_arg"] = trust_indicator_arg + query["trust_indicator_arg"] = trust_indicator_arg if period_arg is not None: try: @@ -552,27 +560,14 @@ class TestResultsHandler(GenericApiHandler): if period_arg > 0: period = datetime.now() - timedelta(days=period_arg) obj = {"$gte": str(period)} - get_request["creation_date"] = obj - else: - get_request["_id"] = result_id + query["creation_date"] = obj - print get_request - res = [] - # fetching results - cursor = self.db.test_results.find(get_request) - while (yield cursor.fetch_next): - test_result = TestResult.test_result_from_dict( - cursor.next_object()) - res.append(test_result.format_http()) - - # building meta object - meta = dict() - meta["total"] = len(res) + res = [] + cursor = self.db.results.find(query) + while (yield cursor.fetch_next): + res.append(format_data(cursor.next_object(), TestResult)) + answer = {'results': res} - # final response object - answer = dict() - answer["test_results"] = res - answer["meta"] = meta self.finish_request(answer) @asynchronous @@ -586,53 +581,51 @@ class TestResultsHandler(GenericApiHandler): # check for request payload if self.json_args is None: - raise HTTPError(HTTP_BAD_REQUEST) + raise HTTPError(HTTP_BAD_REQUEST, 'no payload') + + result = TestResult.from_dict(self.json_args) - # check for missing parameters in the request payload - if self.json_args.get("project_name") is None: - raise HTTPError(HTTP_BAD_REQUEST) - if self.json_args.get("case_name") is None: - raise HTTPError(HTTP_BAD_REQUEST) # check for pod_name instead of id, # keeping id for current implementations - if self.json_args.get("pod_name") is None: - raise HTTPError(HTTP_BAD_REQUEST) + if result.pod_name is None: + raise HTTPError(HTTP_BAD_REQUEST, 'pod is not provided') - # TODO : replace checks with jsonschema - # check for project - mongo_dict = yield self.db.projects.find_one( - {"name": self.json_args.get("project_name")}) - if mongo_dict is None: - raise HTTPError(HTTP_NOT_FOUND, - "Could not find project [{}] " - .format(self.json_args.get("project_name"))) + # check for missing parameters in the request payload + if result.project_name is None: + raise HTTPError(HTTP_BAD_REQUEST, 'project is not provided') - # check for case - mongo_dict = yield self.db.testcases.find_one( - {"name": self.json_args.get("case_name")}) - if mongo_dict is None: - raise HTTPError(HTTP_NOT_FOUND, - "Could not find case [{}] " - .format(self.json_args.get("case_name"))) + if result.case_name is None: + raise HTTPError(HTTP_BAD_REQUEST, 'testcase is not provided') + # TODO : replace checks with jsonschema # check for pod - mongo_dict = yield self.db.pods.find_one( - {"name": self.json_args.get("pod_name")}) - if mongo_dict is None: + the_pod = yield self.db.pods.find_one({"name": result.pod_name}) + if the_pod is None: raise HTTPError(HTTP_NOT_FOUND, "Could not find POD [{}] " .format(self.json_args.get("pod_name"))) + # check for project + the_project = yield self.db.projects.find_one( + {"name": result.project_name}) + if the_project is None: + raise HTTPError(HTTP_NOT_FOUND, "Could not find project [{}] " + .format(result.project_name)) + + # check for testcase + the_testcase = yield self.db.testcases.find_one( + {"name": result.case_name}) + if the_testcase is None: + raise HTTPError(HTTP_NOT_FOUND, + "Could not find testcase [{}] " + .format(result.case_name)) + # convert payload to object - test_result = TestResult.test_result_from_dict(self.json_args) - test_result.creation_date = datetime.now() + result.creation_date = datetime.now() - future = self.db.test_results.insert(test_result.format(), - check_keys=False) - result = yield future - test_result._id = result + _id = yield self.db.results.insert(result.format(), check_keys=False) - self.finish_request(test_result.format_http()) + self.finish_request(self._create_response(_id)) class DashboardHandler(GenericApiHandler): @@ -650,7 +643,7 @@ class DashboardHandler(GenericApiHandler): @asynchronous @gen.coroutine - def get(self, result_id=None): + def get(self): """ Retrieve dashboard ready result(s) for a test project Available filters for this request are : @@ -678,99 +671,61 @@ class DashboardHandler(GenericApiHandler): period_arg = self.get_query_argument("period", None) # prepare request - get_request = dict() + query = dict() - # /dashboard?project=<>&pod=<>... - if (result_id is None): - if project_arg is not None: - get_request["project_name"] = project_arg + if project_arg is not None: + query["project_name"] = project_arg - if case_arg is not None: - get_request["case_name"] = case_arg + if case_arg is not None: + query["case_name"] = case_arg - if pod_arg is not None: - get_request["pod_name"] = pod_arg + if pod_arg is not None: + query["pod_name"] = pod_arg - if version_arg is not None: - get_request["version"] = version_arg + if version_arg is not None: + query["version"] = version_arg - if installer_arg is not None: - get_request["installer"] = installer_arg + if installer_arg is not None: + query["installer"] = installer_arg - if period_arg is not None: - try: - period_arg = int(period_arg) - except: - raise HTTPError(HTTP_BAD_REQUEST) - if period_arg > 0: - period = datetime.now() - timedelta(days=period_arg) - obj = {"$gte": str(period)} - get_request["creation_date"] = obj - else: - get_request["_id"] = result_id - - dashboard = [] + if period_arg is not None: + try: + period_arg = int(period_arg) + except: + raise HTTPError(HTTP_BAD_REQUEST) + if period_arg > 0: + period = datetime.now() - timedelta(days=period_arg) + obj = {"$gte": str(period)} + query["creation_date"] = obj # on /dashboard retrieve the list of projects and testcases # ready for dashboard if project_arg is None: - raise HTTPError(HTTP_NOT_FOUND, - "error:Project name missing") - elif check_dashboard_ready_project(project_arg, "./dashboard"): - res = [] - - if case_arg is None: - raise HTTPError( - HTTP_NOT_FOUND, - "error:Test case missing for project " + project_arg) - - # special case of status for project - if case_arg == "status": - del get_request["case_name"] - # retention time to be agreed - # last five days by default? - # TODO move to DB - period = datetime.now() - timedelta(days=5) - get_request["creation_date"] = {"$gte": period} - - # fetching results - cursor = self.db.test_results.find(get_request) - while (yield cursor.fetch_next): - test_result = TestResult.test_result_from_dict( - cursor.next_object()) - res.append(test_result.format_http()) + raise HTTPError(HTTP_NOT_FOUND, "Project name missing") - if check_dashboard_ready_case(project_arg, case_arg): - dashboard = get_dashboard_result(project_arg, case_arg, res) - else: - raise HTTPError( - HTTP_NOT_FOUND, - "error:" + case_arg + - " test case not case dashboard ready on project " + - project_arg) + if not check_dashboard_ready_project(project_arg): + raise HTTPError(HTTP_NOT_FOUND, + 'Project [{}] not dashboard ready' + .format(project_arg)) - else: - dashboard.append( - {"error": "Project not recognized or not dashboard ready"}) - dashboard.append( - {"Dashboard-ready-projects": - get_dashboard_cases("./dashboard")}) + if case_arg is None: raise HTTPError( HTTP_NOT_FOUND, - "error: no dashboard ready data for this project") + 'Test case missing for project [{}]'.format(project_arg)) - # fetching results - # cursor = self.db.test_results.find(get_request) - # while (yield cursor.fetch_next): - # test_result = TestResult.test_result_from_dict( - # cursor.next_object()) - # res.append(test_result.format_http()) + if not check_dashboard_ready_case(project_arg, case_arg): + raise HTTPError( + HTTP_NOT_FOUND, + 'Test case [{}] not dashboard ready for project [{}]' + .format(case_arg, project_arg)) - # building meta object - meta = dict() + # special case of status for project + res = [] + if case_arg != "status": + cursor = self.db.results.find(query) + while (yield cursor.fetch_next): + result = TestResult.from_dict(cursor.next_object()) + res.append(result.format_http()) # final response object - answer = dict() - answer["dashboard"] = dashboard - answer["meta"] = meta - self.finish_request(answer) + self.finish_request(get_dashboard_result(project_arg, case_arg, res)) diff --git a/utils/test/result_collection_api/resources/models.py b/utils/test/result_collection_api/resources/models.py index b919d9e54..b4094dd2c 100644 --- a/utils/test/result_collection_api/resources/models.py +++ b/utils/test/result_collection_api/resources/models.py @@ -10,7 +10,8 @@ # feng.xiaowei@zte.com.cn mv TestProject to project_models.py 5-19-2016
# feng.xiaowei@zte.com.cn delete meta class 5-19-2016
# feng.xiaowei@zte.com.cn add CreateResponse 5-19-2016
-# feng.xiaowei@zte.com.cn mv TestCase to testcase_models.py 5-20-2016
+# feng.xiaowei@zte.com.cn mv TestCase to testcase_models.py 5-20-2016
+# feng.xiaowei@zte.com.cn mv TestResut to result_models.py 5-23-2016
##############################################################################
@@ -29,91 +30,3 @@ class CreateResponse(object): def format(self):
return {'href': self.href}
-
-
-class TestResult:
- """ Describes a test result"""
-
- def __init__(self):
- self._id = None
- self.case_name = None
- self.project_name = None
- self.pod_name = None
- self.installer = None
- self.version = None
- self.description = None
- self.creation_date = None
- self.details = None
- self.build_tag = None
- self.scenario = None
- self.criteria = None
- self.trust_indicator = None
-
- @staticmethod
- def test_result_from_dict(test_result_dict):
-
- if test_result_dict is None:
- return None
-
- t = TestResult()
- t._id = test_result_dict.get('_id')
- t.case_name = test_result_dict.get('case_name')
- t.pod_name = test_result_dict.get('pod_name')
- t.project_name = test_result_dict.get('project_name')
- t.description = test_result_dict.get('description')
- t.creation_date = str(test_result_dict.get('creation_date'))
- t.details = test_result_dict.get('details')
- t.version = test_result_dict.get('version')
- t.installer = test_result_dict.get('installer')
- t.build_tag = test_result_dict.get('build_tag')
- t.scenario = test_result_dict.get('scenario')
- t.criteria = test_result_dict.get('criteria')
- # 0 < trust indicator < 1
- # if bad value => set this indicator to 0
- if test_result_dict.get('trust_indicator') is not None:
- if isinstance(test_result_dict.get('trust_indicator'),
- (int, long, float)):
- if test_result_dict.get('trust_indicator') < 0:
- t.trust_indicator = 0
- elif test_result_dict.get('trust_indicator') > 1:
- t.trust_indicator = 1
- else:
- t.trust_indicator = test_result_dict.get('trust_indicator')
- else:
- t.trust_indicator = 0
- else:
- t.trust_indicator = 0
- return t
-
- def format(self):
- return {
- "case_name": self.case_name,
- "project_name": self.project_name,
- "pod_name": self.pod_name,
- "description": self.description,
- "creation_date": str(self.creation_date),
- "version": self.version,
- "installer": self.installer,
- "details": self.details,
- "build_tag": self.build_tag,
- "scenario": self.scenario,
- "criteria": self.criteria,
- "trust_indicator": self.trust_indicator
- }
-
- def format_http(self):
- return {
- "_id": str(self._id),
- "case_name": self.case_name,
- "project_name": self.project_name,
- "pod_name": self.pod_name,
- "description": self.description,
- "creation_date": str(self.creation_date),
- "version": self.version,
- "installer": self.installer,
- "details": self.details,
- "build_tag": self.build_tag,
- "scenario": self.scenario,
- "criteria": self.criteria,
- "trust_indicator": self.trust_indicator
- }
diff --git a/utils/test/result_collection_api/resources/result_models.py b/utils/test/result_collection_api/resources/result_models.py new file mode 100644 index 000000000..795621ab1 --- /dev/null +++ b/utils/test/result_collection_api/resources/result_models.py @@ -0,0 +1,141 @@ + +class ResultCreateRequest(object): + def __init__(self, + pod_name=None, + project_name=None, + case_name=None, + installer=None, + version=None, + description=None, + details=None, + build_tag=None, + scenario=None, + criteria=None, + trust_indicator=None): + self.pod_name = pod_name + self.project_name = project_name + self.case_name = case_name + self.installer = installer + self.version = version + self.description = description + self.details = details + self.build_tag = build_tag + self.scenario = scenario + self.criteria = criteria + self.trust_indicator = trust_indicator + + def format(self): + return { + "pod_name": self.pod_name, + "project_name": self.project_name, + "case_name": self.case_name, + "installer": self.installer, + "version": self.version, + "description": self.description, + "details": self.details, + "build_tag": self.build_tag, + "scenario": self.scenario, + "criteria": self.criteria, + "trust_indicator": self.trust_indicator + } + + +class TestResult: + """ Describes a test result""" + + def __init__(self): + self._id = None + self.case_name = None + self.project_name = None + self.pod_name = None + self.installer = None + self.version = None + self.description = None + self.creation_date = None + self.details = None + self.build_tag = None + self.scenario = None + self.criteria = None + self.trust_indicator = None + + @staticmethod + def from_dict(a_dict): + + if a_dict is None: + return None + + t = TestResult() + t._id = a_dict.get('_id') + t.case_name = a_dict.get('case_name') + t.pod_name = a_dict.get('pod_name') + t.project_name = a_dict.get('project_name') + t.description = a_dict.get('description') + t.creation_date = str(a_dict.get('creation_date')) + t.details = a_dict.get('details') + t.version = a_dict.get('version') + t.installer = a_dict.get('installer') + t.build_tag = a_dict.get('build_tag') + t.scenario = a_dict.get('scenario') + t.criteria = a_dict.get('criteria') + # 0 < trust indicator < 1 + # if bad value => set this indicator to 0 + t.trust_indicator = a_dict.get('trust_indicator') + if t.trust_indicator is not None: + if isinstance(t.trust_indicator, (int, long, float)): + if t.trust_indicator < 0: + t.trust_indicator = 0 + elif t.trust_indicator > 1: + t.trust_indicator = 1 + else: + t.trust_indicator = 0 + else: + t.trust_indicator = 0 + return t + + def format(self): + return { + "case_name": self.case_name, + "project_name": self.project_name, + "pod_name": self.pod_name, + "description": self.description, + "creation_date": str(self.creation_date), + "version": self.version, + "installer": self.installer, + "details": self.details, + "build_tag": self.build_tag, + "scenario": self.scenario, + "criteria": self.criteria, + "trust_indicator": self.trust_indicator + } + + def format_http(self): + return { + "_id": str(self._id), + "case_name": self.case_name, + "project_name": self.project_name, + "pod_name": self.pod_name, + "description": self.description, + "creation_date": str(self.creation_date), + "version": self.version, + "installer": self.installer, + "details": self.details, + "build_tag": self.build_tag, + "scenario": self.scenario, + "criteria": self.criteria, + "trust_indicator": self.trust_indicator + } + + +class TestResults(object): + def __init__(self, results=list()): + self.results = results + + @staticmethod + def from_dict(a_dict): + if a_dict is None: + return None + + res = TestResults() + for result in a_dict.get('results'): + res.results.append(TestResult.from_dict(result)) + return res |