summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--result_collection_api/resources/handlers.py107
-rw-r--r--result_collection_api/resources/pod_handler.py89
-rw-r--r--result_collection_api/resources/pod_models.py10
-rw-r--r--result_collection_api/result_collection_api.py20
-rw-r--r--result_collection_api/tests/unit/test_base.py7
-rw-r--r--result_collection_api/tests/unit/test_pod.py12
6 files changed, 152 insertions, 93 deletions
diff --git a/result_collection_api/resources/handlers.py b/result_collection_api/resources/handlers.py
index 4353343..afee1cd 100644
--- a/result_collection_api/resources/handlers.py
+++ b/result_collection_api/resources/handlers.py
@@ -12,6 +12,8 @@
# 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
+# feng.xiaowei@zte.com.cn add methods to GenericApiHandler 5-26-2016
+# feng.xiaowei@zte.com.cn remove PodHandler 5-26-2016
##############################################################################
import json
@@ -24,7 +26,6 @@ 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
@@ -72,95 +73,43 @@ class GenericApiHandler(RequestHandler):
href = self.request.full_url() + '/' + resource
return CreateResponse(href=href).format()
-
-class VersionHandler(GenericApiHandler):
- """ Display a message for the API version """
- def get(self):
- self.finish_request([{'v1': 'basics'}])
-
-
-class PodHandler(GenericApiHandler):
- """ Handle the requests about the POD Platforms
- HTTP Methdods :
- - GET : Get PODS
- - POST : Create a pod
- - DELETE : DELETE POD
- """
-
- def initialize(self):
- """ Prepares the database for the entire class """
- super(PodHandler, self).initialize()
-
@asynchronous
@gen.coroutine
- def get(self, pod_name=None):
- """
- Get all pods or a single pod
- :param pod_id:
- """
- query = dict()
-
- if pod_name is not None:
- query["name"] = pod_name
- answer = yield self.db.pods.find_one(query)
- if answer is None:
- raise HTTPError(HTTP_NOT_FOUND,
- "{} Not Exist".format(pod_name))
- else:
- answer = format_data(answer, Pod)
- else:
- res = []
- cursor = self.db.pods.find(query)
- while (yield cursor.fetch_next):
- res.append(format_data(cursor.next_object(), Pod))
- answer = {'pods': res}
-
- self.finish_request(answer)
+ def _create(self, table, data, mark):
+ data.creation_date = datetime.now()
+ _id = yield self._eval_db(table, 'insert', data.format())
+ if mark is None:
+ mark = _id
+ self.finish_request(self._create_response(mark))
@asynchronous
@gen.coroutine
- def post(self):
- """ Create a POD"""
-
- if self.json_args is None:
- raise HTTPError(HTTP_BAD_REQUEST)
-
- query = {"name": self.json_args.get("name")}
-
- # check for existing name in db
- the_pod = yield self.db.pods.find_one(query)
- if the_pod is not None:
- raise HTTPError(HTTP_FORBIDDEN,
- "{} already exists as a pod".format(
- self.json_args.get("name")))
-
- pod = Pod.from_dict(self.json_args)
- pod.creation_date = datetime.now()
-
- yield self.db.pods.insert(pod.format())
- self.finish_request(self._create_response(pod.name))
+ def _list(self, table, format_cls, query=None):
+ if query is None:
+ query = {}
+ res = []
+ cursor = self._eval_db(table, 'find', query)
+ while (yield cursor.fetch_next):
+ res.append(format_data(cursor.next_object(), format_cls))
+ self.finish_request({table: res})
@asynchronous
@gen.coroutine
- def delete(self, pod_name):
- """ Remove a POD
-
- # check for an existing pod to be deleted
- mongo_dict = yield self.db.pods.find_one(
- {'name': pod_name})
- pod = TestProject.pod(mongo_dict)
- if pod is None:
+ def _get_one(self, table, format_cls, query):
+ data = yield self._eval_db(table, 'find_one', query)
+ if data is None:
raise HTTPError(HTTP_NOT_FOUND,
- "{} could not be found as a pod to be deleted"
- .format(pod_name))
+ "{} Not Exist".format(query))
+ self.finish_request(format_data(data, format_cls))
- # just delete it, or maybe save it elsewhere in a future
- res = yield self.db.projects.remove(
- {'name': pod_name})
+ def _eval_db(self, table, method, param):
+ return eval('self.db.%s.%s(param)' % (table, method))
- self.finish_request(answer)
- """
- pass
+
+class VersionHandler(GenericApiHandler):
+ """ Display a message for the API version """
+ def get(self):
+ self.finish_request([{'v1': 'basics'}])
class ProjectHandler(GenericApiHandler):
diff --git a/result_collection_api/resources/pod_handler.py b/result_collection_api/resources/pod_handler.py
new file mode 100644
index 0000000..7189967
--- /dev/null
+++ b/result_collection_api/resources/pod_handler.py
@@ -0,0 +1,89 @@
+from tornado import gen
+from tornado.web import HTTPError, asynchronous
+
+from tornado_swagger_ui.tornado_swagger import swagger
+from handlers import GenericApiHandler
+from common.constants import HTTP_BAD_REQUEST, HTTP_FORBIDDEN
+from pod_models import Pod
+
+
+class PodCLHandler(GenericApiHandler):
+ def initialize(self):
+ super(PodCLHandler, self).initialize()
+
+ @swagger.operation(nickname='list-all')
+ def get(self):
+ """
+ @description: list all PODs
+ @return 200: list all pods, empty list is no pod exist
+ @rtype: L{Pods}
+ """
+ self._list('pods', Pod)
+
+ # @asynchronous
+ @gen.coroutine
+ @swagger.operation(nickname='create')
+ def post(self):
+ """
+ @description: Create a POD
+ @param body: pod information to be created
+ @type body: L{PodCreateRequest}
+ @in body: body
+ @return 200: pod is created.
+ @rtype: L{Pod}
+ @raise 403: already exists as a pod
+ @raise 400: bad request
+ """
+ if self.json_args is None:
+ raise HTTPError(HTTP_BAD_REQUEST, 'no payload')
+
+ pod = Pod.from_dict(self.json_args)
+ name = pod.name
+ if name is None or name == '':
+ raise HTTPError(HTTP_BAD_REQUEST, 'pod name missing')
+
+ the_pod = yield self.db.pods.find_one({'name': name})
+ if the_pod is not None:
+ raise HTTPError(HTTP_FORBIDDEN,
+ "{} already exists as a pod".format(
+ self.json_args.get("name")))
+ self._create('pods', pod, name)
+
+
+class PodGURHandler(GenericApiHandler):
+ def initialize(self):
+ super(PodGURHandler, self).initialize()
+
+ @swagger.operation(nickname='get-one')
+ def get(self, pod_name=None):
+ """
+ @description: Get a single pod by pod_name
+ @return 200: pod exist
+ @raise 404: pod not exist
+ @rtype: L{Pod}
+ """
+ query = dict()
+ query["name"] = pod_name
+ self._get_one('pods', Pod, query)
+
+ @asynchronous
+ @gen.coroutine
+ def delete(self, pod_name):
+ """ Remove a POD
+
+ # check for an existing pod to be deleted
+ mongo_dict = yield self.db.pods.find_one(
+ {'name': pod_name})
+ pod = TestProject.pod(mongo_dict)
+ if pod is None:
+ raise HTTPError(HTTP_NOT_FOUND,
+ "{} could not be found as a pod to be deleted"
+ .format(pod_name))
+
+ # just delete it, or maybe save it elsewhere in a future
+ res = yield self.db.projects.remove(
+ {'name': pod_name})
+
+ self.finish_request(answer)
+ """
+ pass
diff --git a/result_collection_api/resources/pod_models.py b/result_collection_api/resources/pod_models.py
index b02e3c2..fcb4ddb 100644
--- a/result_collection_api/resources/pod_models.py
+++ b/result_collection_api/resources/pod_models.py
@@ -1,3 +1,5 @@
+from tornado_swagger_ui.tornado_swagger import swagger
+
__author__ = '__serena__'
# name: name of the POD e.g. zte-1
@@ -6,8 +8,9 @@ __author__ = '__serena__'
# role: ci-pod or community-pod or single-node
+@swagger.model()
class PodCreateRequest(object):
- def __init__(self, name='', mode='', details='', role=""):
+ def __init__(self, name, mode='', details='', role=""):
self.name = name
self.mode = mode
self.details = details
@@ -22,6 +25,7 @@ class PodCreateRequest(object):
}
+@swagger.model()
class Pod(PodCreateRequest):
""" describes a POD platform """
def __init__(self, name='', mode='', details='', role="",
@@ -55,7 +59,11 @@ class Pod(PodCreateRequest):
return f
+@swagger.model()
class Pods(object):
+ """
+ @ptype pods: C{list} of L{Pod}
+ """
def __init__(self, pods=list()):
self.pods = pods
diff --git a/result_collection_api/result_collection_api.py b/result_collection_api/result_collection_api.py
index 97aa58c..afd66f3 100644
--- a/result_collection_api/result_collection_api.py
+++ b/result_collection_api/result_collection_api.py
@@ -29,14 +29,16 @@ TODOs :
"""
+import argparse
+
import tornado.ioloop
import motor
-import argparse
-from resources.handlers import VersionHandler, PodHandler, \
+from resources.handlers import VersionHandler, \
ProjectHandler, TestcaseHandler, TestResultsHandler, DashboardHandler
+from resources.pod_handler import PodCLHandler, PodGURHandler
from common.config import APIConfig
-
+from tornado_swagger_ui.tornado_swagger import swagger
# optionally get config file from command line
parser = argparse.ArgumentParser()
@@ -51,16 +53,16 @@ db = client[CONF.mongo_dbname]
def make_app():
- return tornado.web.Application(
+ return swagger.Application(
[
# GET /version => GET API version
(r"/versions", VersionHandler),
# few examples:
- # GET /pods => Get all pods
- # GET /pods/1 => Get details on POD 1
- (r"/api/v1/pods", PodHandler),
- (r"/api/v1/pods/([^/]+)", PodHandler),
+ # GET /api/v1/pods => Get all pods
+ # GET /api/v1/pods/1 => Get details on POD 1
+ (r"/api/v1/pods", PodCLHandler),
+ (r"/api/v1/pods/([^/]+)", PodGURHandler),
# few examples:
# GET /projects
@@ -70,10 +72,8 @@ def make_app():
# few examples
# GET /projects/qtip/cases => Get cases for qtip
- #
(r"/api/v1/projects/([^/]+)/cases", TestcaseHandler),
(r"/api/v1/projects/([^/]+)/cases/([^/]+)", TestcaseHandler),
- # (r"/test_cases/([^/]+)", TestCasesHandler),
# new path to avoid a long depth
# GET /results?project=functest&case=keystone.catalog&pod=1
diff --git a/result_collection_api/tests/unit/test_base.py b/result_collection_api/tests/unit/test_base.py
index 99b1de2..16ed07c 100644
--- a/result_collection_api/tests/unit/test_base.py
+++ b/result_collection_api/tests/unit/test_base.py
@@ -2,7 +2,8 @@ import json
from tornado.web import Application
from tornado.testing import AsyncHTTPTestCase
-from resources.handlers import VersionHandler, PodHandler, \
+from resources.pod_handler import PodCLHandler, PodGURHandler
+from resources.handlers import VersionHandler, \
ProjectHandler, TestcaseHandler, TestResultsHandler, DashboardHandler
from resources.models import CreateResponse
import fake_pymongo
@@ -26,8 +27,8 @@ class TestBase(AsyncHTTPTestCase):
return Application(
[
(r"/versions", VersionHandler),
- (r"/api/v1/pods", PodHandler),
- (r"/api/v1/pods/([^/]+)", PodHandler),
+ (r"/api/v1/pods", PodCLHandler),
+ (r"/api/v1/pods/([^/]+)", PodGURHandler),
(r"/api/v1/projects", ProjectHandler),
(r"/api/v1/projects/([^/]+)", ProjectHandler),
(r"/api/v1/projects/([^/]+)/cases", TestcaseHandler),
diff --git a/result_collection_api/tests/unit/test_pod.py b/result_collection_api/tests/unit/test_pod.py
index d7f4c3a..8a93027 100644
--- a/result_collection_api/tests/unit/test_pod.py
+++ b/result_collection_api/tests/unit/test_pod.py
@@ -32,6 +32,18 @@ class TestPodCreate(TestPodBase):
(code, body) = self.create()
self.assertEqual(code, HTTP_BAD_REQUEST)
+ def test_emptyName(self):
+ req_empty = PodCreateRequest('')
+ (code, body) = self.create(req_empty)
+ self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertIn('pod name missing', body)
+
+ def test_noneName(self):
+ req_none = PodCreateRequest(None)
+ (code, body) = self.create(req_none)
+ self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertIn('pod name missing', body)
+
def test_success(self):
code, body = self.create_d()
self.assertEqual(code, HTTP_OK)