summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--result_collection_api/opnfv_testapi/tests/unit/test_result.py9
-rw-r--r--result_collection_api/opnfv_testapi/tests/unit/test_version.py6
-rw-r--r--result_collection_api/opnfv_testapi/tornado_swagger/README.md273
3 files changed, 276 insertions, 12 deletions
diff --git a/result_collection_api/opnfv_testapi/tests/unit/test_result.py b/result_collection_api/opnfv_testapi/tests/unit/test_result.py
index 7863fe7..fc1e9ba 100644
--- a/result_collection_api/opnfv_testapi/tests/unit/test_result.py
+++ b/result_collection_api/opnfv_testapi/tests/unit/test_result.py
@@ -162,15 +162,6 @@ class TestResultCreate(TestResultBase):
self.assertEqual(code, HTTP_OK)
self.assert_href(body)
- def test_createSameResults(self):
- req_again = copy.deepcopy(self.req_d)
- req_again.start_date = "2016-05-23 08:16:09.477097"
- req_again.stop_date = "2016-05-23 08:16:19.477097"
-
- (code, body) = self.create(req_again)
- self.assertEqual(code, HTTP_OK)
- self.assert_href(body)
-
class TestResultGet(TestResultBase):
def test_getOne(self):
diff --git a/result_collection_api/opnfv_testapi/tests/unit/test_version.py b/result_collection_api/opnfv_testapi/tests/unit/test_version.py
index 907812b..b6fbf45 100644
--- a/result_collection_api/opnfv_testapi/tests/unit/test_version.py
+++ b/result_collection_api/opnfv_testapi/tests/unit/test_version.py
@@ -12,14 +12,14 @@ from test_base import TestBase
from opnfv_testapi.resources.models import Versions
-class TestVersionbBase(TestBase):
+class TestVersionBase(TestBase):
def setUp(self):
- super(TestVersionbBase, self).setUp()
+ super(TestVersionBase, self).setUp()
self.list_res = Versions
self.basePath = '/versions'
-class TestVersion(TestVersionbBase):
+class TestVersion(TestVersionBase):
def test_success(self):
code, body = self.get()
self.assertEqual(200, code)
diff --git a/result_collection_api/opnfv_testapi/tornado_swagger/README.md b/result_collection_api/opnfv_testapi/tornado_swagger/README.md
new file mode 100644
index 0000000..d815f21
--- /dev/null
+++ b/result_collection_api/opnfv_testapi/tornado_swagger/README.md
@@ -0,0 +1,273 @@
+# tornado-swagger
+
+## What is tornado-swagger?
+tornado is a wrapper for tornado which enables swagger-ui support.
+
+In essense, you just need to wrap the Api instance and add a few python decorators to
+get full swagger support.http://swagger.io/
+
+
+## How to use:
+
+
+```python
+from tornado.web import RequestHandler, HTTPError
+from tornado_swagger import swagger
+
+swagger.docs()
+
+# You may decorate your operation with @swagger.operation and use docs to inform information
+class ItemNoParamHandler(GenericApiHandler):
+ @swagger.operation(nickname='create')
+ def post(self):
+ """
+ @param body: create test results for a item.
+ @type body: L{Item}
+ @return 200: item is created.
+ @raise 400: invalid input
+ """
+
+# Operations not decorated with @swagger.operation do not get added to the swagger docs
+
+class ItemNoParamHandler(GenericApiHandler):
+ def options(self):
+ """
+ I'm not visible in the swagger docs
+ """
+ pass
+
+
+# Then you use swagger.Application instead of tornado.web.Application
+# and do other operations as usual
+
+def make_app():
+ return swagger.Application([
+ (r"/items", ItemNoParamHandler),
+ (r"/items/([^/]+)", ItemHandler),
+ (r"/items/([^/]+)/cases/([^/]+)", ItemOptionParamHandler),
+ ])
+
+# You define models like this:
+@swagger.model
+class Item:
+ """
+ @descriptin:
+ This is an example of a model class that has parameters in its constructor
+ and the fields in the swagger spec are derived from the parameters to __init__.
+ @notes:
+ In this case we would have property1, property2 as required parameters
+ and property3 as optional parameter.
+ @property property3: Item decription
+ @ptype property3: L{PropertySubclass}
+ """
+ def __init__(self, property1, property2=None):
+ self.property1 = property1
+ self.property2 = property2
+
+# Swagger json:
+ "models": {
+ "Item": {
+ "description": "A description...",
+ "id": "Item",
+ "required": [
+ "property1",
+ ],
+ "properties": [
+ "property1": {
+ "type": "string"
+ },
+ "property2": {
+ "type": "string"
+ "default": null
+ }
+ ]
+ }
+ }
+
+# If you declare an __init__ method with meaningful arguments
+# then those args could be used to deduce the swagger model fields.
+# just as shown above
+
+# if you declare an @property in docs, this property property2 will also be used
+# to deduce the swagger model fields
+class Item:
+ """
+ @property property3: Item description
+ """
+ def __init__(self, property1, property2):
+ self.property1 = property1
+ self.property2 = property2
+
+# Swagger json:
+ "models": {
+ "Item": {
+ "description": "A description...",
+ "id": "Item",
+ "required": [
+ "property1",
+ ],
+ "properties": [
+ "property1": {
+ "type": "string"
+ },
+ "property2": {
+ "type": "string"
+ }
+ "property3": {
+ "type": "string"
+ }
+ ]
+ }
+ }
+
+# if you declare an argument with @ptype, the type of this argument will be specified
+# rather than the default 'string'
+class Item:
+ """
+ @ptype property3: L{PropertySubclass}
+ """
+ def __init__(self, property1, property2, property3=None):
+ self.property1 = property1
+ self.property2 = property2
+ self.property3 = property3
+
+# Swagger json:
+ "models": {
+ "Item": {
+ "description": "A description...",
+ "id": "Item",
+ "required": [
+ "property1",
+ ],
+ "properties": [
+ "property1": {
+ "type": "string"
+ },
+ "property2": {
+ "type": "string"
+ },
+ "property3": {
+ "type": "PropertySubclass"
+ "default": null
+ }
+ ]
+ }
+ }
+
+# if you want to declare an list property, you can do it like this:
+class Item:
+ """
+ @ptype property3: L{PropertySubclass}
+ @ptype property4: C{list} of L{PropertySubclass}
+ """
+ def __init__(self, property1, property2, property3, property4=None):
+ self.property1 = property1
+ self.property2 = property2
+ self.property3 = property3
+ self.property4 = property4
+
+# Swagger json:
+ "models": {
+ "Item": {
+ "description": "A description...",
+ "id": "Item",
+ "required": [
+ "property1",
+ ],
+ "properties": [
+ "property1": {
+ "type": "string"
+ },
+ "property2": {
+ "type": "string"
+ },
+ "property3": {
+ "type": "PropertySubclass"
+ "default": null
+ },
+ "property4": {
+ "default": null,
+ "items": {
+ "type": "PropertySubclass"},
+ "type": "array"
+ }
+ }
+ ]
+ }
+ }
+
+# if it is a query:
+class ItemQueryHandler(GenericApiHandler):
+ @swagger.operation(nickname='query')
+ def get(self):
+ """
+ @param property1:
+ @type property1: L{string}
+ @in property1: query
+ @required property1: False
+
+ @param property2:
+ @type property2: L{string}
+ @in property2: query
+ @required property2: True
+ @rtype: L{Item}
+
+ @notes: GET /item?property1=1&property2=1
+ """
+
+# Swagger json:
+ "apis": [
+ {
+ "operations": [
+ {
+ "parameters": [
+ {
+ "name": "property1",
+ "dataType": "string",
+ "paramType": "query",
+ "description": ""
+ },
+ {
+ "name": "property2",
+ "dataType": "string",
+ "paramType": "query",
+ "required": true,
+ "description": ""
+ }
+ ],
+ "responseClass": "Item",
+ "notes": null,
+ "responseMessages": [],
+ "summary": null,
+ "httpMethod": "GET",
+ "nickname": "query"
+ }
+ ],
+ "path": "/item",
+ "description": null
+ },
+ ....
+ ]
+```
+
+# Running and testing
+
+Now run your tornado app
+
+```
+python main.py
+```
+
+And visit:
+
+```
+curl http://ip:port/swagger/spec
+```
+
+access to web
+```
+http://ip:port/swagger/spec.html
+```
+
+# Passing more metadata to swagger
+customized arguments used in creating the 'swagger.docs' object will be supported later