summaryrefslogtreecommitdiffstats
path: root/utils/test/testapi/opnfv_testapi
diff options
context:
space:
mode:
Diffstat (limited to 'utils/test/testapi/opnfv_testapi')
-rw-r--r--utils/test/testapi/opnfv_testapi/cmd/server.py34
-rw-r--r--utils/test/testapi/opnfv_testapi/common/config.py37
-rw-r--r--utils/test/testapi/opnfv_testapi/common/constants.py1
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/handlers.py94
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/models.py214
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/pod_handlers.py12
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/project_handlers.py12
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/result_handlers.py30
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py22
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/scenario_models.py63
-rw-r--r--utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py14
-rw-r--r--utils/test/testapi/opnfv_testapi/router/url_mappings.py39
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/__init__.py0
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/noparam.ini16
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/normal.ini17
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/nosection.ini11
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/notboolean.ini17
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/notint.ini17
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py36
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/fake_pymongo.py1
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_base.py36
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_fake_pymongo.py18
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_pod.py35
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_project.py58
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_result.py122
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_scenario.py47
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_testcase.py85
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_token.py118
-rw-r--r--utils/test/testapi/opnfv_testapi/tests/unit/test_version.py8
29 files changed, 795 insertions, 419 deletions
diff --git a/utils/test/testapi/opnfv_testapi/cmd/server.py b/utils/test/testapi/opnfv_testapi/cmd/server.py
index c3d734607..fa2b72250 100644
--- a/utils/test/testapi/opnfv_testapi/cmd/server.py
+++ b/utils/test/testapi/opnfv_testapi/cmd/server.py
@@ -30,37 +30,43 @@ TODOs :
"""
import argparse
+import sys
-import tornado.ioloop
import motor
+import tornado.ioloop
-from opnfv_testapi.common.config import APIConfig
-from opnfv_testapi.tornado_swagger import swagger
+from opnfv_testapi.common import config
from opnfv_testapi.router import url_mappings
+from opnfv_testapi.tornado_swagger import swagger
+
+CONF = None
+
-# optionally get config file from command line
-parser = argparse.ArgumentParser()
-parser.add_argument("-c", "--config-file", dest='config_file',
- help="Config file location")
-args = parser.parse_args()
-CONF = APIConfig().parse(args.config_file)
+def parse_config(argv=[]):
+ global CONF
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-c", "--config-file", dest='config_file',
+ help="Config file location")
+ args = parser.parse_args(argv)
+ CONF = config.APIConfig().parse(args.config_file)
-# connecting to MongoDB server, and choosing database
-client = motor.MotorClient(CONF.mongo_url)
-db = client[CONF.mongo_dbname]
-swagger.docs(base_url=CONF.swagger_base_url)
+def get_db():
+ return motor.MotorClient(CONF.mongo_url)[CONF.mongo_dbname]
def make_app():
+ swagger.docs(base_url=CONF.swagger_base_url)
return swagger.Application(
url_mappings.mappings,
- db=db,
+ db=get_db(),
debug=CONF.api_debug_on,
+ auth=CONF.api_authenticate_on
)
def main():
+ parse_config(sys.argv[1:])
application = make_app()
application.listen(CONF.api_port)
tornado.ioloop.IOLoop.current().start()
diff --git a/utils/test/testapi/opnfv_testapi/common/config.py b/utils/test/testapi/opnfv_testapi/common/config.py
index ecab88ae3..105d4fabf 100644
--- a/utils/test/testapi/opnfv_testapi/common/config.py
+++ b/utils/test/testapi/opnfv_testapi/common/config.py
@@ -7,9 +7,8 @@
# http://www.apache.org/licenses/LICENSE-2.0
# feng.xiaowei@zte.com.cn remove prepare_put_request 5-30-2016
##############################################################################
-
-
-from ConfigParser import SafeConfigParser, NoOptionError
+import ConfigParser
+import os
class ParseError(Exception):
@@ -24,7 +23,7 @@ class ParseError(Exception):
return 'error parsing config file : %s' % self.msg
-class APIConfig:
+class APIConfig(object):
"""
The purpose of this class is to load values correctly from the config file.
Each key is declared as an attribute in __init__() and linked in parse()
@@ -36,20 +35,21 @@ class APIConfig:
self.mongo_dbname = None
self.api_port = None
self.api_debug_on = None
+ self.api_authenticate_on = None
self._parser = None
self.swagger_base_url = None
def _get_parameter(self, section, param):
try:
return self._parser.get(section, param)
- except NoOptionError:
- raise ParseError("[%s.%s] parameter not found" % (section, param))
+ except ConfigParser.NoOptionError:
+ raise ParseError("No parameter: [%s.%s]" % (section, param))
def _get_int_parameter(self, section, param):
try:
return int(self._get_parameter(section, param))
except ValueError:
- raise ParseError("[%s.%s] not an int" % (section, param))
+ raise ParseError("Not int: [%s.%s]" % (section, param))
def _get_bool_parameter(self, section, param):
result = self._get_parameter(section, param)
@@ -59,7 +59,7 @@ class APIConfig:
return False
raise ParseError(
- "[%s.%s : %s] not a boolean" % (section, param, result))
+ "Not boolean: [%s.%s : %s]" % (section, param, result))
@staticmethod
def parse(config_location=None):
@@ -68,28 +68,21 @@ class APIConfig:
if config_location is None:
config_location = obj._default_config_location
- obj._parser = SafeConfigParser()
- obj._parser.read(config_location)
- if not obj._parser:
+ if not os.path.exists(config_location):
raise ParseError("%s not found" % config_location)
+ obj._parser = ConfigParser.SafeConfigParser()
+ obj._parser.read(config_location)
+
# Linking attributes to keys from file with their sections
obj.mongo_url = obj._get_parameter("mongo", "url")
obj.mongo_dbname = obj._get_parameter("mongo", "dbname")
obj.api_port = obj._get_int_parameter("api", "port")
obj.api_debug_on = obj._get_bool_parameter("api", "debug")
+ obj.api_authenticate_on = obj._get_bool_parameter("api",
+ "authenticate")
+
obj.swagger_base_url = obj._get_parameter("swagger", "base_url")
return obj
-
- def __str__(self):
- return "mongo_url = %s \n" \
- "mongo_dbname = %s \n" \
- "api_port = %s \n" \
- "api_debug_on = %s \n" \
- "swagger_base_url = %s \n" % (self.mongo_url,
- self.mongo_dbname,
- self.api_port,
- self.api_debug_on,
- self.swagger_base_url)
diff --git a/utils/test/testapi/opnfv_testapi/common/constants.py b/utils/test/testapi/opnfv_testapi/common/constants.py
index 4d39a142d..71bd95216 100644
--- a/utils/test/testapi/opnfv_testapi/common/constants.py
+++ b/utils/test/testapi/opnfv_testapi/common/constants.py
@@ -10,6 +10,7 @@
DEFAULT_REPRESENTATION = "application/json"
HTTP_BAD_REQUEST = 400
+HTTP_UNAUTHORIZED = 401
HTTP_FORBIDDEN = 403
HTTP_NOT_FOUND = 404
HTTP_OK = 200
diff --git a/utils/test/testapi/opnfv_testapi/resources/handlers.py b/utils/test/testapi/opnfv_testapi/resources/handlers.py
index a2628e249..8255b526a 100644
--- a/utils/test/testapi/opnfv_testapi/resources/handlers.py
+++ b/utils/test/testapi/opnfv_testapi/resources/handlers.py
@@ -20,19 +20,19 @@
# feng.xiaowei@zte.com.cn remove DashboardHandler 5-30-2016
##############################################################################
-import json
from datetime import datetime
+import functools
+import json
from tornado import gen
-from tornado.web import RequestHandler, asynchronous, HTTPError
+from tornado import web
-from models import CreateResponse
-from opnfv_testapi.common.constants import DEFAULT_REPRESENTATION, \
- HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_FORBIDDEN
+import models
+from opnfv_testapi.common import constants
from opnfv_testapi.tornado_swagger import swagger
-class GenericApiHandler(RequestHandler):
+class GenericApiHandler(web.RequestHandler):
def __init__(self, application, request, **kwargs):
super(GenericApiHandler, self).__init__(application, request, **kwargs)
self.db = self.settings["db"]
@@ -44,49 +44,71 @@ class GenericApiHandler(RequestHandler):
self.db_testcases = 'testcases'
self.db_results = 'results'
self.db_scenarios = 'scenarios'
+ self.auth = self.settings["auth"]
def prepare(self):
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):
+ constants.DEFAULT_REPRESENTATION):
try:
self.json_args = json.loads(self.request.body)
except (ValueError, KeyError, TypeError) as error:
- raise HTTPError(HTTP_BAD_REQUEST,
- "Bad Json format [{}]".
- format(error))
+ raise web.HTTPError(constants.HTTP_BAD_REQUEST,
+ "Bad Json format [{}]".
+ format(error))
def finish_request(self, json_object=None):
if json_object:
self.write(json.dumps(json_object))
- self.set_header("Content-Type", DEFAULT_REPRESENTATION)
+ self.set_header("Content-Type", constants.DEFAULT_REPRESENTATION)
self.finish()
def _create_response(self, resource):
href = self.request.full_url() + '/' + str(resource)
- return CreateResponse(href=href).format()
+ return models.CreateResponse(href=href).format()
def format_data(self, data):
cls_data = self.table_cls.from_dict(data)
return cls_data.format_http()
- @asynchronous
+ def authenticate(method):
+ @web.asynchronous
+ @gen.coroutine
+ @functools.wraps(method)
+ def wrapper(self, *args, **kwargs):
+ if self.auth:
+ try:
+ token = self.request.headers['X-Auth-Token']
+ except KeyError:
+ raise web.HTTPError(constants.HTTP_UNAUTHORIZED,
+ "No Authentication Header.")
+ query = {'access_token': token}
+ check = yield self._eval_db_find_one(query, 'tokens')
+ if not check:
+ raise web.HTTPError(constants.HTTP_FORBIDDEN,
+ "Invalid Token.")
+ ret = yield gen.coroutine(method)(self, *args, **kwargs)
+ raise gen.Return(ret)
+ return wrapper
+
+ @web.asynchronous
@gen.coroutine
+ @authenticate
def _create(self, miss_checks, db_checks, **kwargs):
"""
:param miss_checks: [miss1, miss2]
:param db_checks: [(table, exist, query, error)]
"""
if self.json_args is None:
- raise HTTPError(HTTP_BAD_REQUEST, "no body")
+ raise web.HTTPError(constants.HTTP_BAD_REQUEST, "no body")
data = self.table_cls.from_dict(self.json_args)
for miss in miss_checks:
miss_data = data.__getattribute__(miss)
if miss_data is None or miss_data == '':
- raise HTTPError(HTTP_BAD_REQUEST,
- '{} missing'.format(miss))
+ raise web.HTTPError(constants.HTTP_BAD_REQUEST,
+ '{} missing'.format(miss))
for k, v in kwargs.iteritems():
data.__setattr__(k, v)
@@ -95,7 +117,7 @@ class GenericApiHandler(RequestHandler):
check = yield self._eval_db_find_one(query(data), table)
if (exist and not check) or (not exist and check):
code, message = error(data)
- raise HTTPError(code, message)
+ raise web.HTTPError(code, message)
if self.table != 'results':
data.creation_date = datetime.now()
@@ -107,7 +129,7 @@ class GenericApiHandler(RequestHandler):
resource = _id
self.finish_request(self._create_response(resource))
- @asynchronous
+ @web.asynchronous
@gen.coroutine
def _list(self, query=None, res_op=None, *args, **kwargs):
if query is None:
@@ -126,40 +148,42 @@ class GenericApiHandler(RequestHandler):
res = res_op(data, *args)
self.finish_request(res)
- @asynchronous
+ @web.asynchronous
@gen.coroutine
def _get_one(self, query):
data = yield self._eval_db_find_one(query)
if data is None:
- raise HTTPError(HTTP_NOT_FOUND,
- "[{}] not exist in table [{}]"
- .format(query, self.table))
+ raise web.HTTPError(constants.HTTP_NOT_FOUND,
+ "[{}] not exist in table [{}]"
+ .format(query, self.table))
self.finish_request(self.format_data(data))
- @asynchronous
+ @web.asynchronous
@gen.coroutine
+ @authenticate
def _delete(self, query):
data = yield self._eval_db_find_one(query)
if data is None:
- raise HTTPError(HTTP_NOT_FOUND,
- "[{}] not exit in table [{}]"
- .format(query, self.table))
+ raise web.HTTPError(constants.HTTP_NOT_FOUND,
+ "[{}] not exit in table [{}]"
+ .format(query, self.table))
yield self._eval_db(self.table, 'remove', query)
self.finish_request()
- @asynchronous
+ @web.asynchronous
@gen.coroutine
+ @authenticate
def _update(self, query, db_keys):
if self.json_args is None:
- raise HTTPError(HTTP_BAD_REQUEST, "No payload")
+ raise web.HTTPError(constants.HTTP_BAD_REQUEST, "No payload")
# check old data exist
from_data = yield self._eval_db_find_one(query)
if from_data is None:
- raise HTTPError(HTTP_NOT_FOUND,
- "{} could not be found in table [{}]"
- .format(query, self.table))
+ raise web.HTTPError(constants.HTTP_NOT_FOUND,
+ "{} could not be found in table [{}]"
+ .format(query, self.table))
data = self.table_cls.from_dict(from_data)
# check new data exist
@@ -167,9 +191,9 @@ class GenericApiHandler(RequestHandler):
if not equal:
to_data = yield self._eval_db_find_one(new_query)
if to_data is not None:
- raise HTTPError(HTTP_FORBIDDEN,
- "{} already exists in table [{}]"
- .format(new_query, self.table))
+ raise web.HTTPError(constants.HTTP_FORBIDDEN,
+ "{} already exists in table [{}]"
+ .format(new_query, self.table))
# we merge the whole document """
edit_request = self._update_requests(data)
@@ -186,7 +210,7 @@ class GenericApiHandler(RequestHandler):
request = self._update_request(request, k, v,
data.__getattribute__(k))
if not request:
- raise HTTPError(HTTP_FORBIDDEN, "Nothing to update")
+ raise web.HTTPError(constants.HTTP_FORBIDDEN, "Nothing to update")
edit_request = data.format()
edit_request.update(request)
diff --git a/utils/test/testapi/opnfv_testapi/resources/models.py b/utils/test/testapi/opnfv_testapi/resources/models.py
index f518c97a0..0ea482fd2 100644
--- a/utils/test/testapi/opnfv_testapi/resources/models.py
+++ b/utils/test/testapi/opnfv_testapi/resources/models.py
@@ -1,98 +1,116 @@
-##############################################################################
-# Copyright (c) 2015 Orange
-# guyrodrigue.koffi@orange.com / koffirodrigue@gmail.com
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-# feng.xiaowei@zte.com.cn mv Pod to pod_models.py 5-18-2016
-# feng.xiaowei@zte.com.cn add MetaCreateResponse/MetaGetResponse 5-18-2016
-# 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 TestResut to result_models.py 5-23-2016
-# feng.xiaowei@zte.com.cn add ModelBase 12-20-2016
-##############################################################################
-import copy
-
-from opnfv_testapi.tornado_swagger import swagger
-
-
-class ModelBase(object):
-
- def _format(self, excludes):
- new_obj = copy.deepcopy(self)
- dicts = new_obj.__dict__
- for k in dicts.keys():
- if k in excludes:
- del dicts[k]
- elif dicts[k]:
- if hasattr(dicts[k], 'format'):
- dicts[k] = dicts[k].format()
- elif isinstance(dicts[k], list):
- hs = list()
- [hs.append(h.format() if hasattr(h, 'format') else str(h))
- for h in dicts[k]]
- dicts[k] = hs
- elif not isinstance(dicts[k], (str, int, float, dict)):
- dicts[k] = str(dicts[k])
- return dicts
-
- def format(self):
- return self._format(['_id'])
-
- def format_http(self):
- return self._format([])
-
- @staticmethod
- def attr_parser():
- return {}
-
- @classmethod
- def from_dict(cls, a_dict):
- if a_dict is None:
- return None
-
- attr_parser = cls.attr_parser()
- t = cls()
- for k, v in a_dict.iteritems():
- value = v
- if isinstance(v, dict) and k in attr_parser:
- value = attr_parser[k].from_dict(v)
- elif isinstance(v, list) and k in attr_parser:
- value = []
- for item in v:
- value.append(attr_parser[k].from_dict(item))
-
- t.__setattr__(k, value)
-
- return t
-
-
-@swagger.model()
-class CreateResponse(ModelBase):
- def __init__(self, href=''):
- self.href = href
-
-
-@swagger.model()
-class Versions(ModelBase):
- """
- @property versions:
- @ptype versions: C{list} of L{Version}
- """
-
- def __init__(self):
- self.versions = list()
-
- @staticmethod
- def attr_parser():
- return {'versions': Version}
-
-
-@swagger.model()
-class Version(ModelBase):
- def __init__(self, version=None, description=None):
- self.version = version
- self.description = description
+##############################################################################
+# Copyright (c) 2015 Orange
+# guyrodrigue.koffi@orange.com / koffirodrigue@gmail.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+# feng.xiaowei@zte.com.cn mv Pod to pod_models.py 5-18-2016
+# feng.xiaowei@zte.com.cn add MetaCreateResponse/MetaGetResponse 5-18-2016
+# 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 TestResut to result_models.py 5-23-2016
+# feng.xiaowei@zte.com.cn add ModelBase 12-20-2016
+##############################################################################
+import copy
+import ast
+
+
+from opnfv_testapi.tornado_swagger import swagger
+
+
+class ModelBase(object):
+
+ def format(self):
+ return self._format(['_id'])
+
+ def format_http(self):
+ return self._format([])
+
+ @classmethod
+ def from_dict(cls, a_dict):
+ if a_dict is None:
+ return None
+
+ attr_parser = cls.attr_parser()
+ t = cls()
+ for k, v in a_dict.iteritems():
+ value = v
+ if isinstance(v, dict) and k in attr_parser:
+ value = attr_parser[k].from_dict(v)
+ elif isinstance(v, list) and k in attr_parser:
+ value = []
+ for item in v:
+ value.append(attr_parser[k].from_dict(item))
+
+ t.__setattr__(k, value)
+
+ return t
+
+ @staticmethod
+ def attr_parser():
+ return {}
+
+ def _format(self, excludes):
+ new_obj = copy.deepcopy(self)
+ dicts = new_obj.__dict__
+ for k in dicts.keys():
+ if k in excludes:
+ del dicts[k]
+ elif dicts[k]:
+ dicts[k] = self._obj_format(dicts[k])
+ return dicts
+
+ def _obj_format(self, obj):
+ if self._has_format(obj):
+ obj = obj.format()
+ elif isinstance(obj, unicode):
+ try:
+ obj = self._obj_format(ast.literal_eval(obj))
+ except:
+ try:
+ obj = str(obj)
+ except:
+ obj = obj
+ elif isinstance(obj, list):
+ hs = list()
+ for h in obj:
+ hs.append(self._obj_format(h))
+ obj = hs
+ elif not isinstance(obj, (str, int, float, dict)):
+ obj = str(obj)
+ return obj
+
+ @staticmethod
+ def _has_format(obj):
+ return not isinstance(obj, (str, unicode)) and hasattr(obj, 'format')
+
+
+@swagger.model()
+class CreateResponse(ModelBase):
+ def __init__(self, href=''):
+ self.href = href
+
+
+@swagger.model()
+class Versions(ModelBase):
+ """
+ @property versions:
+ @ptype versions: C{list} of L{Version}
+ """
+
+ def __init__(self):
+ self.versions = list()
+
+ @staticmethod
+ def attr_parser():
+ return {'versions': Version}
+
+
+@swagger.model()
+class Version(ModelBase):
+ def __init__(self, version=None, description=None):
+ self.version = version
+ self.description = description
diff --git a/utils/test/testapi/opnfv_testapi/resources/pod_handlers.py b/utils/test/testapi/opnfv_testapi/resources/pod_handlers.py
index e1bd9d359..65c27f60a 100644
--- a/utils/test/testapi/opnfv_testapi/resources/pod_handlers.py
+++ b/utils/test/testapi/opnfv_testapi/resources/pod_handlers.py
@@ -6,17 +6,17 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+import handlers
+from opnfv_testapi.common import constants
from opnfv_testapi.tornado_swagger import swagger
-from handlers import GenericApiHandler
-from pod_models import Pod
-from opnfv_testapi.common.constants import HTTP_FORBIDDEN
+import pod_models
-class GenericPodHandler(GenericApiHandler):
+class GenericPodHandler(handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericPodHandler, self).__init__(application, request, **kwargs)
self.table = 'pods'
- self.table_cls = Pod
+ self.table_cls = pod_models.Pod
class PodCLHandler(GenericPodHandler):
@@ -46,7 +46,7 @@ class PodCLHandler(GenericPodHandler):
def error(data):
message = '{} already exists as a pod'.format(data.name)
- return HTTP_FORBIDDEN, message
+ return constants.HTTP_FORBIDDEN, message
miss_checks = ['name']
db_checks = [(self.table, False, query, error)]
diff --git a/utils/test/testapi/opnfv_testapi/resources/project_handlers.py b/utils/test/testapi/opnfv_testapi/resources/project_handlers.py
index 94c65b722..f3521961d 100644
--- a/utils/test/testapi/opnfv_testapi/resources/project_handlers.py
+++ b/utils/test/testapi/opnfv_testapi/resources/project_handlers.py
@@ -6,19 +6,19 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+import handlers
+from opnfv_testapi.common import constants
from opnfv_testapi.tornado_swagger import swagger
-from handlers import GenericApiHandler
-from opnfv_testapi.common.constants import HTTP_FORBIDDEN
-from project_models import Project
+import project_models
-class GenericProjectHandler(GenericApiHandler):
+class GenericProjectHandler(handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericProjectHandler, self).__init__(application,
request,
**kwargs)
self.table = 'projects'
- self.table_cls = Project
+ self.table_cls = project_models.Project
class ProjectCLHandler(GenericProjectHandler):
@@ -48,7 +48,7 @@ class ProjectCLHandler(GenericProjectHandler):
def error(data):
message = '{} already exists as a project'.format(data.name)
- return HTTP_FORBIDDEN, message
+ return constants.HTTP_FORBIDDEN, message
miss_checks = ['name']
db_checks = [(self.table, False, query, error)]
diff --git a/utils/test/testapi/opnfv_testapi/resources/result_handlers.py b/utils/test/testapi/opnfv_testapi/resources/result_handlers.py
index 2a1ed56ee..d41ba4820 100644
--- a/utils/test/testapi/opnfv_testapi/resources/result_handlers.py
+++ b/utils/test/testapi/opnfv_testapi/resources/result_handlers.py
@@ -6,30 +6,32 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from datetime import datetime, timedelta
+from datetime import datetime
+from datetime import timedelta
-from bson.objectid import ObjectId
-from tornado.web import HTTPError
+from bson import objectid
+from tornado import web
-from opnfv_testapi.common.constants import HTTP_BAD_REQUEST, HTTP_NOT_FOUND
-from opnfv_testapi.resources.handlers import GenericApiHandler
-from opnfv_testapi.resources.result_models import TestResult
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import handlers
+from opnfv_testapi.resources import result_models
from opnfv_testapi.tornado_swagger import swagger
-class GenericResultHandler(GenericApiHandler):
+class GenericResultHandler(handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericResultHandler, self).__init__(application,
request,
**kwargs)
self.table = self.db_results
- self.table_cls = TestResult
+ self.table_cls = result_models.TestResult
def get_int(self, key, value):
try:
value = int(value)
except:
- raise HTTPError(HTTP_BAD_REQUEST, '{} must be int'.format(key))
+ raise web.HTTPError(constants.HTTP_BAD_REQUEST,
+ '{} must be int'.format(key))
return value
def set_query(self):
@@ -144,14 +146,14 @@ class ResultsCLHandler(GenericResultHandler):
def pod_error(data):
message = 'Could not find pod [{}]'.format(data.pod_name)
- return HTTP_NOT_FOUND, message
+ return constants.HTTP_NOT_FOUND, message
def project_query(data):
return {'name': data.project_name}
def project_error(data):
message = 'Could not find project [{}]'.format(data.project_name)
- return HTTP_NOT_FOUND, message
+ return constants.HTTP_NOT_FOUND, message
def testcase_query(data):
return {'project_name': data.project_name, 'name': data.case_name}
@@ -159,7 +161,7 @@ class ResultsCLHandler(GenericResultHandler):
def testcase_error(data):
message = 'Could not find testcase [{}] in project [{}]'\
.format(data.case_name, data.project_name)
- return HTTP_NOT_FOUND, message
+ return constants.HTTP_NOT_FOUND, message
miss_checks = ['pod_name', 'project_name', 'case_name']
db_checks = [('pods', True, pod_query, pod_error),
@@ -178,7 +180,7 @@ class ResultsGURHandler(GenericResultHandler):
@raise 404: test result not exist
"""
query = dict()
- query["_id"] = ObjectId(result_id)
+ query["_id"] = objectid.ObjectId(result_id)
self._get_one(query)
@swagger.operation(nickname="updateTestResultById")
@@ -193,6 +195,6 @@ class ResultsGURHandler(GenericResultHandler):
@raise 404: result not exist
@raise 403: nothing to update
"""
- query = {'_id': ObjectId(result_id)}
+ query = {'_id': objectid.ObjectId(result_id)}
db_keys = []
self._update(query, db_keys)
diff --git a/utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py b/utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py
index a8c1a94fe..083bf59fc 100644
--- a/utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py
+++ b/utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py
@@ -1,17 +1,16 @@
-from opnfv_testapi.common.constants import HTTP_FORBIDDEN
-from opnfv_testapi.resources.handlers import GenericApiHandler
-from opnfv_testapi.resources.scenario_models import Scenario
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import handlers
import opnfv_testapi.resources.scenario_models as models
from opnfv_testapi.tornado_swagger import swagger
-class GenericScenarioHandler(GenericApiHandler):
+class GenericScenarioHandler(handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericScenarioHandler, self).__init__(application,
request,
**kwargs)
self.table = self.db_scenarios
- self.table_cls = Scenario
+ self.table_cls = models.Scenario
class ScenariosCLHandler(GenericScenarioHandler):
@@ -81,7 +80,7 @@ class ScenariosCLHandler(GenericScenarioHandler):
def error(data):
message = '{} already exists as a scenario'.format(data.name)
- return HTTP_FORBIDDEN, message
+ return constants.HTTP_FORBIDDEN, message
miss_checks = ['name']
db_checks = [(self.table, False, query, error)]
@@ -116,6 +115,17 @@ class ScenarioGURHandler(GenericScenarioHandler):
db_keys = ['name']
self._update(query, db_keys)
+ @swagger.operation(nickname="deleteScenarioByName")
+ def delete(self, name):
+ """
+ @description: delete a scenario by name
+ @return 200: delete success
+ @raise 404: scenario not exist:
+ """
+
+ query = {'name': name}
+ self._delete(query)
+
def _update_query(self, keys, data):
query = dict()
equal = True
diff --git a/utils/test/testapi/opnfv_testapi/resources/scenario_models.py b/utils/test/testapi/opnfv_testapi/resources/scenario_models.py
index 73bcbe99e..b84accf4d 100644
--- a/utils/test/testapi/opnfv_testapi/resources/scenario_models.py
+++ b/utils/test/testapi/opnfv_testapi/resources/scenario_models.py
@@ -49,6 +49,24 @@ class ScenarioProject(models.ModelBase):
return {'scores': ScenarioScore,
'trust_indicators': ScenarioTI}
+ def __eq__(self, other):
+ return [self.project == other.project and
+ self._customs_eq(other) and
+ self._scores_eq(other) and
+ self._ti_eq(other)]
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def _customs_eq(self, other):
+ return set(self.customs) == set(other.customs)
+
+ def _scores_eq(self, other):
+ return set(self.scores) == set(other.scores)
+
+ def _ti_eq(self, other):
+ return set(self.trust_indicators) == set(other.trust_indicators)
+
@swagger.model()
class ScenarioVersion(models.ModelBase):
@@ -64,6 +82,21 @@ class ScenarioVersion(models.ModelBase):
def attr_parser():
return {'projects': ScenarioProject}
+ def __eq__(self, other):
+ return [self.version == other.version and self._projects_eq(other)]
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def _projects_eq(self, other):
+ for s_project in self.projects:
+ for o_project in other.projects:
+ if s_project.project == o_project.project:
+ if s_project != o_project:
+ return False
+
+ return True
+
@swagger.model()
class ScenarioInstaller(models.ModelBase):
@@ -79,6 +112,21 @@ class ScenarioInstaller(models.ModelBase):
def attr_parser():
return {'versions': ScenarioVersion}
+ def __eq__(self, other):
+ return [self.installer == other.installer and self._versions_eq(other)]
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def _versions_eq(self, other):
+ for s_version in self.versions:
+ for o_version in other.versions:
+ if s_version.version == o_version.version:
+ if s_version != o_version:
+ return False
+
+ return True
+
@swagger.model()
class ScenarioCreateRequest(models.ModelBase):
@@ -126,6 +174,21 @@ class Scenario(models.ModelBase):
def attr_parser():
return {'installers': ScenarioInstaller}
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __eq__(self, other):
+ return [self.name == other.name and self._installers_eq(other)]
+
+ def _installers_eq(self, other):
+ for s_install in self.installers:
+ for o_install in other.installers:
+ if s_install.installer == o_install.installer:
+ if s_install != o_install:
+ return False
+
+ return True
+
@swagger.model()
class Scenarios(models.ModelBase):
diff --git a/utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py b/utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py
index 100a4fd91..3debd6918 100644
--- a/utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py
+++ b/utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py
@@ -6,19 +6,19 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.common.constants import HTTP_FORBIDDEN
-from opnfv_testapi.resources.handlers import GenericApiHandler
-from opnfv_testapi.resources.testcase_models import Testcase
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import handlers
+from opnfv_testapi.resources import testcase_models
from opnfv_testapi.tornado_swagger import swagger
-class GenericTestcaseHandler(GenericApiHandler):
+class GenericTestcaseHandler(handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericTestcaseHandler, self).__init__(application,
request,
**kwargs)
self.table = self.db_testcases
- self.table_cls = Testcase
+ self.table_cls = testcase_models.Testcase
class TestcaseCLHandler(GenericTestcaseHandler):
@@ -58,12 +58,12 @@ class TestcaseCLHandler(GenericTestcaseHandler):
def p_error(data):
message = 'Could not find project [{}]'.format(data.project_name)
- return HTTP_FORBIDDEN, message
+ return constants.HTTP_FORBIDDEN, message
def tc_error(data):
message = '{} already exists as a testcase in project {}'\
.format(data.name, data.project_name)
- return HTTP_FORBIDDEN, message
+ return constants.HTTP_FORBIDDEN, message
miss_checks = ['name']
db_checks = [(self.db_projects, True, p_query, p_error),
diff --git a/utils/test/testapi/opnfv_testapi/router/url_mappings.py b/utils/test/testapi/opnfv_testapi/router/url_mappings.py
index 0ae3c31c3..39cf006af 100644
--- a/utils/test/testapi/opnfv_testapi/router/url_mappings.py
+++ b/utils/test/testapi/opnfv_testapi/router/url_mappings.py
@@ -6,37 +6,34 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources.handlers import VersionHandler
-from opnfv_testapi.resources.testcase_handlers import TestcaseCLHandler, \
- TestcaseGURHandler
-from opnfv_testapi.resources.pod_handlers import PodCLHandler, PodGURHandler
-from opnfv_testapi.resources.project_handlers import ProjectCLHandler, \
- ProjectGURHandler
-from opnfv_testapi.resources.result_handlers import ResultsCLHandler, \
- ResultsGURHandler
-from opnfv_testapi.resources.scenario_handlers import ScenariosCLHandler
-from opnfv_testapi.resources.scenario_handlers import ScenarioGURHandler
+from opnfv_testapi.resources import handlers
+from opnfv_testapi.resources import pod_handlers
+from opnfv_testapi.resources import project_handlers
+from opnfv_testapi.resources import result_handlers
+from opnfv_testapi.resources import scenario_handlers
+from opnfv_testapi.resources import testcase_handlers
mappings = [
# GET /versions => GET API version
- (r"/versions", VersionHandler),
+ (r"/versions", handlers.VersionHandler),
# few examples:
# 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),
+ (r"/api/v1/pods", pod_handlers.PodCLHandler),
+ (r"/api/v1/pods/([^/]+)", pod_handlers.PodGURHandler),
# few examples:
# GET /projects
# GET /projects/yardstick
- (r"/api/v1/projects", ProjectCLHandler),
- (r"/api/v1/projects/([^/]+)", ProjectGURHandler),
+ (r"/api/v1/projects", project_handlers.ProjectCLHandler),
+ (r"/api/v1/projects/([^/]+)", project_handlers.ProjectGURHandler),
# few examples
# GET /projects/qtip/cases => Get cases for qtip
- (r"/api/v1/projects/([^/]+)/cases", TestcaseCLHandler),
- (r"/api/v1/projects/([^/]+)/cases/([^/]+)", TestcaseGURHandler),
+ (r"/api/v1/projects/([^/]+)/cases", testcase_handlers.TestcaseCLHandler),
+ (r"/api/v1/projects/([^/]+)/cases/([^/]+)",
+ testcase_handlers.TestcaseGURHandler),
# new path to avoid a long depth
# GET /results?project=functest&case=keystone.catalog&pod=1
@@ -44,10 +41,10 @@ mappings = [
# POST /results =>
# Push results with mandatory request payload parameters
# (project, case, and pod)
- (r"/api/v1/results", ResultsCLHandler),
- (r"/api/v1/results/([^/]+)", ResultsGURHandler),
+ (r"/api/v1/results", result_handlers.ResultsCLHandler),
+ (r"/api/v1/results/([^/]+)", result_handlers.ResultsGURHandler),
# scenarios
- (r"/api/v1/scenarios", ScenariosCLHandler),
- (r"/api/v1/scenarios/([^/]+)", ScenarioGURHandler),
+ (r"/api/v1/scenarios", scenario_handlers.ScenariosCLHandler),
+ (r"/api/v1/scenarios/([^/]+)", scenario_handlers.ScenarioGURHandler),
]
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/__init__.py b/utils/test/testapi/opnfv_testapi/tests/unit/common/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/__init__.py
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/noparam.ini b/utils/test/testapi/opnfv_testapi/tests/unit/common/noparam.ini
new file mode 100644
index 000000000..fda2a09e9
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/noparam.ini
@@ -0,0 +1,16 @@
+# to add a new parameter in the config file,
+# the CONF object in config.ini must be updated
+[mongo]
+# URL of the mongo DB
+# Mongo auth url => mongodb://user1:pwd1@host1/?authSource=db1
+url = mongodb://127.0.0.1:27017/
+
+[api]
+# Listening port
+port = 8000
+# With debug_on set to true, error traces will be shown in HTTP responses
+debug = True
+authenticate = False
+
+[swagger]
+base_url = http://localhost:8000
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/normal.ini b/utils/test/testapi/opnfv_testapi/tests/unit/common/normal.ini
new file mode 100644
index 000000000..77cc6c6ee
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/normal.ini
@@ -0,0 +1,17 @@
+# to add a new parameter in the config file,
+# the CONF object in config.ini must be updated
+[mongo]
+# URL of the mongo DB
+# Mongo auth url => mongodb://user1:pwd1@host1/?authSource=db1
+url = mongodb://127.0.0.1:27017/
+dbname = test_results_collection
+
+[api]
+# Listening port
+port = 8000
+# With debug_on set to true, error traces will be shown in HTTP responses
+debug = True
+authenticate = False
+
+[swagger]
+base_url = http://localhost:8000
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/nosection.ini b/utils/test/testapi/opnfv_testapi/tests/unit/common/nosection.ini
new file mode 100644
index 000000000..9988fc0a4
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/nosection.ini
@@ -0,0 +1,11 @@
+# to add a new parameter in the config file,
+# the CONF object in config.ini must be updated
+[api]
+# Listening port
+port = 8000
+# With debug_on set to true, error traces will be shown in HTTP responses
+debug = True
+authenticate = False
+
+[swagger]
+base_url = http://localhost:8000
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/notboolean.ini b/utils/test/testapi/opnfv_testapi/tests/unit/common/notboolean.ini
new file mode 100644
index 000000000..b3f327670
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/notboolean.ini
@@ -0,0 +1,17 @@
+# to add a new parameter in the config file,
+# the CONF object in config.ini must be updated
+[mongo]
+# URL of the mongo DB
+# Mongo auth url => mongodb://user1:pwd1@host1/?authSource=db1
+url = mongodb://127.0.0.1:27017/
+dbname = test_results_collection
+
+[api]
+# Listening port
+port = 8000
+# With debug_on set to true, error traces will be shown in HTTP responses
+debug = True
+authenticate = notboolean
+
+[swagger]
+base_url = http://localhost:8000
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/notint.ini b/utils/test/testapi/opnfv_testapi/tests/unit/common/notint.ini
new file mode 100644
index 000000000..d1b752a34
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/notint.ini
@@ -0,0 +1,17 @@
+# to add a new parameter in the config file,
+# the CONF object in config.ini must be updated
+[mongo]
+# URL of the mongo DB
+# Mongo auth url => mongodb://user1:pwd1@host1/?authSource=db1
+url = mongodb://127.0.0.1:27017/
+dbname = test_results_collection
+
+[api]
+# Listening port
+port = notint
+# With debug_on set to true, error traces will be shown in HTTP responses
+debug = True
+authenticate = False
+
+[swagger]
+base_url = http://localhost:8000
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py b/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py
new file mode 100644
index 000000000..aaff6bb91
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py
@@ -0,0 +1,36 @@
+import ConfigParser
+import os
+
+import pytest
+
+from opnfv_testapi.common import config
+
+
+@pytest.fixture()
+def config_dir():
+ return os.path.dirname(__file__)
+
+
+@pytest.mark.parametrize('exception, config_file, excepted', [
+ (config.ParseError, None, '/etc/opnfv_testapi/config.ini not found'),
+ (ConfigParser.NoSectionError, 'nosection.ini', 'No section:'),
+ (config.ParseError, 'noparam.ini', 'No parameter:'),
+ (config.ParseError, 'notint.ini', 'Not int:'),
+ (config.ParseError, 'notboolean.ini', 'Not boolean:')])
+def pytest_config_exceptions(config_dir, exception, config_file, excepted):
+ file = '{}/{}'.format(config_dir, config_file) if config_file else None
+ with pytest.raises(exception) as error:
+ config.APIConfig().parse(file)
+ assert excepted in str(error.value)
+
+
+def test_config_success():
+ config_dir = os.path.join(os.path.dirname(__file__),
+ '../../../../etc/config.ini')
+ conf = config.APIConfig().parse(config_dir)
+ 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_on is True
+ assert conf.api_authenticate_on is False
+ assert conf.swagger_base_url == 'http://localhost:8000'
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/fake_pymongo.py b/utils/test/testapi/opnfv_testapi/tests/unit/fake_pymongo.py
index 3c4fd01a3..ef74a0857 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/fake_pymongo.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/fake_pymongo.py
@@ -242,3 +242,4 @@ projects = MemDb('projects')
testcases = MemDb('testcases')
results = MemDb('results')
scenarios = MemDb('scenarios')
+tokens = MemDb('tokens')
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_base.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_base.py
index fc780e44c..b955f4a5a 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_base.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_base.py
@@ -7,21 +7,23 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
import json
+from os import path
-from tornado.web import Application
-from tornado.testing import AsyncHTTPTestCase
+import mock
+from tornado import testing
-from opnfv_testapi.router import url_mappings
-from opnfv_testapi.resources.models import CreateResponse
import fake_pymongo
+from opnfv_testapi.cmd import server
+from opnfv_testapi.resources import models
-class TestBase(AsyncHTTPTestCase):
+class TestBase(testing.AsyncHTTPTestCase):
headers = {'Content-Type': 'application/json; charset=UTF-8'}
def setUp(self):
+ self._patch_server()
self.basePath = ''
- self.create_res = CreateResponse
+ self.create_res = models.CreateResponse
self.get_res = None
self.list_res = None
self.update_res = None
@@ -30,12 +32,24 @@ class TestBase(AsyncHTTPTestCase):
self.addCleanup(self._clear)
super(TestBase, self).setUp()
+ def tearDown(self):
+ self.db_patcher.stop()
+
+ def _patch_server(self):
+ server.parse_config([
+ '--config-file',
+ path.join(path.dirname(__file__), 'common/normal.ini')
+ ])
+ self.db_patcher = mock.patch('opnfv_testapi.cmd.server.get_db',
+ self._fake_pymongo)
+ self.db_patcher.start()
+
+ @staticmethod
+ def _fake_pymongo():
+ return fake_pymongo
+
def get_app(self):
- return Application(
- url_mappings.mappings,
- db=fake_pymongo,
- debug=True,
- )
+ return server.make_app()
def create_d(self, *args):
return self.create(self.req_d, *args)
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_fake_pymongo.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_fake_pymongo.py
index 5f50ba867..7c43fca62 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_fake_pymongo.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_fake_pymongo.py
@@ -9,13 +9,13 @@
import unittest
from tornado import gen
-from tornado.testing import AsyncHTTPTestCase, gen_test
-from tornado.web import Application
+from tornado import testing
+from tornado import web
import fake_pymongo
-class MyTest(AsyncHTTPTestCase):
+class MyTest(testing.AsyncHTTPTestCase):
def setUp(self):
super(MyTest, self).setUp()
self.db = fake_pymongo
@@ -23,7 +23,7 @@ class MyTest(AsyncHTTPTestCase):
self.io_loop.run_sync(self.fixture_setup)
def get_app(self):
- return Application()
+ return web.Application()
@gen.coroutine
def fixture_setup(self):
@@ -32,13 +32,13 @@ class MyTest(AsyncHTTPTestCase):
yield self.db.pods.insert({'_id': '1', 'name': 'test1'})
yield self.db.pods.insert({'name': 'test2'})
- @gen_test
+ @testing.gen_test
def test_find_one(self):
user = yield self.db.pods.find_one({'name': 'test1'})
self.assertEqual(user, self.test1)
self.db.pods.remove()
- @gen_test
+ @testing.gen_test
def test_find(self):
cursor = self.db.pods.find()
names = []
@@ -47,7 +47,7 @@ class MyTest(AsyncHTTPTestCase):
names.append(ob.get('name'))
self.assertItemsEqual(names, ['test1', 'test2'])
- @gen_test
+ @testing.gen_test
def test_update(self):
yield self.db.pods.update({'_id': '1'}, {'name': 'new_test1'})
user = yield self.db.pods.find_one({'_id': '1'})
@@ -71,7 +71,7 @@ class MyTest(AsyncHTTPTestCase):
None,
check_keys=False)
- @gen_test
+ @testing.gen_test
def test_remove(self):
yield self.db.pods.remove({'_id': '1'})
user = yield self.db.pods.find_one({'_id': '1'})
@@ -104,7 +104,7 @@ class MyTest(AsyncHTTPTestCase):
def _insert_assert(self, docs, error=None, **kwargs):
self._db_assert('insert', error, docs, **kwargs)
- @gen_test
+ @testing.gen_test
def _db_assert(self, method, error, *args, **kwargs):
name_error = None
try:
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_pod.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_pod.py
index a1184d554..922bd46e2 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_pod.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_pod.py
@@ -8,20 +8,19 @@
##############################################################################
import unittest
-from test_base import TestBase
-from opnfv_testapi.resources.pod_models import PodCreateRequest, Pod, Pods
-from opnfv_testapi.common.constants import HTTP_OK, HTTP_BAD_REQUEST, \
- HTTP_FORBIDDEN, HTTP_NOT_FOUND
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import pod_models
+import test_base as base
-class TestPodBase(TestBase):
+class TestPodBase(base.TestBase):
def setUp(self):
super(TestPodBase, self).setUp()
- self.req_d = PodCreateRequest('zte-1', 'virtual',
- 'zte pod 1', 'ci-pod')
- self.req_e = PodCreateRequest('zte-2', 'metal', 'zte pod 2')
- self.get_res = Pod
- self.list_res = Pods
+ self.req_d = pod_models.PodCreateRequest('zte-1', 'virtual',
+ 'zte pod 1', 'ci-pod')
+ self.req_e = pod_models.PodCreateRequest('zte-2', 'metal', 'zte pod 2')
+ self.get_res = pod_models.Pod
+ self.list_res = pod_models.Pods
self.basePath = '/api/v1/pods'
def assert_get_body(self, pod, req=None):
@@ -38,36 +37,36 @@ class TestPodBase(TestBase):
class TestPodCreate(TestPodBase):
def test_withoutBody(self):
(code, body) = self.create()
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
def test_emptyName(self):
- req_empty = PodCreateRequest('')
+ req_empty = pod_models.PodCreateRequest('')
(code, body) = self.create(req_empty)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_noneName(self):
- req_none = PodCreateRequest(None)
+ req_none = pod_models.PodCreateRequest(None)
(code, body) = self.create(req_none)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_success(self):
code, body = self.create_d()
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_create_body(body)
def test_alreadyExist(self):
self.create_d()
code, body = self.create_d()
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn('already exists', body)
class TestPodGet(TestPodBase):
def test_notExist(self):
code, body = self.get('notExist')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_getOne(self):
self.create_d()
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_project.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_project.py
index 327ddf7b2..afd4a6601 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_project.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_project.py
@@ -8,21 +8,21 @@
##############################################################################
import unittest
-from test_base import TestBase
-from opnfv_testapi.resources.project_models import ProjectCreateRequest, \
- Project, Projects, ProjectUpdateRequest
-from opnfv_testapi.common.constants import HTTP_OK, HTTP_BAD_REQUEST, \
- HTTP_FORBIDDEN, HTTP_NOT_FOUND
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import project_models
+import test_base as base
-class TestProjectBase(TestBase):
+class TestProjectBase(base.TestBase):
def setUp(self):
super(TestProjectBase, self).setUp()
- self.req_d = ProjectCreateRequest('vping', 'vping-ssh test')
- self.req_e = ProjectCreateRequest('doctor', 'doctor test')
- self.get_res = Project
- self.list_res = Projects
- self.update_res = Project
+ self.req_d = project_models.ProjectCreateRequest('vping',
+ 'vping-ssh test')
+ self.req_e = project_models.ProjectCreateRequest('doctor',
+ 'doctor test')
+ self.get_res = project_models.Project
+ self.list_res = project_models.Projects
+ self.update_res = project_models.Project
self.basePath = '/api/v1/projects'
def assert_body(self, project, req=None):
@@ -37,41 +37,41 @@ class TestProjectBase(TestBase):
class TestProjectCreate(TestProjectBase):
def test_withoutBody(self):
(code, body) = self.create()
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
def test_emptyName(self):
- req_empty = ProjectCreateRequest('')
+ req_empty = project_models.ProjectCreateRequest('')
(code, body) = self.create(req_empty)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_noneName(self):
- req_none = ProjectCreateRequest(None)
+ req_none = project_models.ProjectCreateRequest(None)
(code, body) = self.create(req_none)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_success(self):
(code, body) = self.create_d()
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_create_body(body)
def test_alreadyExist(self):
self.create_d()
(code, body) = self.create_d()
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn('already exists', body)
class TestProjectGet(TestProjectBase):
def test_notExist(self):
code, body = self.get('notExist')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_getOne(self):
self.create_d()
code, body = self.get(self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_body(body)
def test_list(self):
@@ -88,23 +88,23 @@ class TestProjectGet(TestProjectBase):
class TestProjectUpdate(TestProjectBase):
def test_withoutBody(self):
code, _ = self.update(None, 'noBody')
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
def test_notFound(self):
code, _ = self.update(self.req_e, 'notFound')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_newNameExist(self):
self.create_d()
self.create_e()
code, body = self.update(self.req_e, self.req_d.name)
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn("already exists", body)
def test_noUpdate(self):
self.create_d()
code, body = self.update(self.req_d, self.req_d.name)
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn("Nothing to update", body)
def test_success(self):
@@ -112,9 +112,9 @@ class TestProjectUpdate(TestProjectBase):
code, body = self.get(self.req_d.name)
_id = body._id
- req = ProjectUpdateRequest('newName', 'new description')
+ req = project_models.ProjectUpdateRequest('newName', 'new description')
code, body = self.update(req, self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assertEqual(_id, body._id)
self.assert_body(body, req)
@@ -126,16 +126,16 @@ class TestProjectUpdate(TestProjectBase):
class TestProjectDelete(TestProjectBase):
def test_notFound(self):
code, body = self.delete('notFound')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_success(self):
self.create_d()
code, body = self.delete(self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assertEqual(body, '')
code, body = self.get(self.req_d.name)
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
if __name__ == '__main__':
unittest.main()
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_result.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_result.py
index 10575a9f5..2c7268eb6 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_result.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_result.py
@@ -7,17 +7,15 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
import copy
-import unittest
from datetime import datetime, timedelta
+import unittest
-from opnfv_testapi.common.constants import HTTP_OK, HTTP_BAD_REQUEST, \
- HTTP_NOT_FOUND
-from opnfv_testapi.resources.pod_models import PodCreateRequest
-from opnfv_testapi.resources.project_models import ProjectCreateRequest
-from opnfv_testapi.resources.result_models import ResultCreateRequest, \
- TestResult, TestResults, ResultUpdateRequest, TI, TIHistory
-from opnfv_testapi.resources.testcase_models import TestcaseCreateRequest
-from test_base import TestBase
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import pod_models
+from opnfv_testapi.resources import project_models
+from opnfv_testapi.resources import result_models
+from opnfv_testapi.resources import testcase_models
+import test_base as base
class Details(object):
@@ -49,7 +47,7 @@ class Details(object):
return t
-class TestResultBase(TestBase):
+class TestResultBase(base.TestBase):
def setUp(self):
self.pod = 'zte-pod1'
self.project = 'functest'
@@ -59,34 +57,41 @@ class TestResultBase(TestBase):
self.build_tag = 'v3.0'
self.scenario = 'odl-l2'
self.criteria = 'passed'
- self.trust_indicator = TI(0.7)
+ self.trust_indicator = result_models.TI(0.7)
self.start_date = "2016-05-23 07:16:09.477097"
self.stop_date = "2016-05-23 07:16:19.477097"
self.update_date = "2016-05-24 07:16:19.477097"
self.update_step = -0.05
super(TestResultBase, self).setUp()
self.details = Details(timestart='0', duration='9s', status='OK')
- self.req_d = ResultCreateRequest(pod_name=self.pod,
- project_name=self.project,
- case_name=self.case,
- installer=self.installer,
- version=self.version,
- start_date=self.start_date,
- stop_date=self.stop_date,
- details=self.details.format(),
- build_tag=self.build_tag,
- scenario=self.scenario,
- criteria=self.criteria,
- trust_indicator=self.trust_indicator)
- self.get_res = TestResult
- self.list_res = TestResults
- self.update_res = TestResult
+ self.req_d = result_models.ResultCreateRequest(
+ pod_name=self.pod,
+ project_name=self.project,
+ case_name=self.case,
+ installer=self.installer,
+ version=self.version,
+ start_date=self.start_date,
+ stop_date=self.stop_date,
+ details=self.details.format(),
+ build_tag=self.build_tag,
+ scenario=self.scenario,
+ criteria=self.criteria,
+ trust_indicator=self.trust_indicator)
+ self.get_res = result_models.TestResult
+ self.list_res = result_models.TestResults
+ self.update_res = result_models.TestResult
self.basePath = '/api/v1/results'
- self.req_pod = PodCreateRequest(self.pod, 'metal', 'zte pod 1')
- self.req_project = ProjectCreateRequest(self.project, 'vping test')
- self.req_testcase = TestcaseCreateRequest(self.case,
- '/cases/vping',
- 'vping-ssh test')
+ self.req_pod = pod_models.PodCreateRequest(
+ self.pod,
+ 'metal',
+ 'zte pod 1')
+ self.req_project = project_models.ProjectCreateRequest(
+ self.project,
+ 'vping test')
+ self.req_testcase = testcase_models.TestcaseCreateRequest(
+ self.case,
+ '/cases/vping',
+ 'vping-ssh test')
self.create_help('/api/v1/pods', self.req_pod)
self.create_help('/api/v1/projects', self.req_project)
self.create_help('/api/v1/projects/%s/cases',
@@ -94,7 +99,7 @@ class TestResultBase(TestBase):
self.project)
def assert_res(self, code, result, req=None):
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
if req is None:
req = self.req_d
self.assertEqual(result.pod_name, req.pod_name)
@@ -129,78 +134,78 @@ class TestResultBase(TestBase):
class TestResultCreate(TestResultBase):
def test_nobody(self):
(code, body) = self.create(None)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('no body', body)
def test_podNotProvided(self):
req = self.req_d
req.pod_name = None
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('pod_name missing', body)
def test_projectNotProvided(self):
req = self.req_d
req.project_name = None
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('project_name missing', body)
def test_testcaseNotProvided(self):
req = self.req_d
req.case_name = None
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('case_name missing', body)
def test_noPod(self):
req = self.req_d
req.pod_name = 'notExistPod'
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
self.assertIn('Could not find pod', body)
def test_noProject(self):
req = self.req_d
req.project_name = 'notExistProject'
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
self.assertIn('Could not find project', body)
def test_noTestcase(self):
req = self.req_d
req.case_name = 'notExistTestcase'
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
self.assertIn('Could not find testcase', body)
def test_success(self):
(code, body) = self.create_d()
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_href(body)
def test_key_with_doc(self):
req = copy.deepcopy(self.req_d)
req.details = {'1.name': 'dot_name'}
(code, body) = self.create(req)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_href(body)
def test_no_ti(self):
- req = ResultCreateRequest(pod_name=self.pod,
- project_name=self.project,
- case_name=self.case,
- installer=self.installer,
- version=self.version,
- start_date=self.start_date,
- stop_date=self.stop_date,
- details=self.details.format(),
- build_tag=self.build_tag,
- scenario=self.scenario,
- criteria=self.criteria)
+ req = result_models.ResultCreateRequest(pod_name=self.pod,
+ project_name=self.project,
+ case_name=self.case,
+ installer=self.installer,
+ version=self.version,
+ start_date=self.start_date,
+ stop_date=self.stop_date,
+ details=self.details.format(),
+ build_tag=self.build_tag,
+ scenario=self.scenario,
+ criteria=self.criteria)
(code, res) = self.create(req)
_id = res.href.split('/')[-1]
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
code, body = self.get(_id)
self.assert_res(code, body, req)
@@ -240,7 +245,7 @@ class TestResultGet(TestResultBase):
def test_queryPeriodNotInt(self):
code, body = self.query(self._set_query('period=a'))
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('period must be int', body)
def test_queryPeriodFail(self):
@@ -253,7 +258,7 @@ class TestResultGet(TestResultBase):
def test_queryLastNotInt(self):
code, body = self.query(self._set_query('last=a'))
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('last must be int', body)
def test_queryLast(self):
@@ -292,7 +297,7 @@ class TestResultGet(TestResultBase):
req = self._create_changed_date(**kwargs)
code, body = self.query(query)
if not found:
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assertEqual(0, len(body.results))
else:
self.assertEqual(1, len(body.results))
@@ -326,10 +331,11 @@ class TestResultUpdate(TestResultBase):
new_ti = copy.deepcopy(self.trust_indicator)
new_ti.current += self.update_step
- new_ti.histories.append(TIHistory(self.update_date, self.update_step))
+ new_ti.histories.append(
+ result_models.TIHistory(self.update_date, self.update_step))
new_data = copy.deepcopy(self.req_d)
new_data.trust_indicator = new_ti
- update = ResultUpdateRequest(trust_indicator=new_ti)
+ update = result_models.ResultUpdateRequest(trust_indicator=new_ti)
code, body = self.update(update, _id)
self.assertEqual(_id, body._id)
self.assert_res(code, body, new_data)
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_scenario.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_scenario.py
index c15dc32ea..7a6e94a93 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_scenario.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_scenario.py
@@ -1,16 +1,14 @@
from copy import deepcopy
+from datetime import datetime
import json
import os
-from datetime import datetime
-from opnfv_testapi.common.constants import HTTP_BAD_REQUEST
-from opnfv_testapi.common.constants import HTTP_FORBIDDEN
-from opnfv_testapi.common.constants import HTTP_OK
+from opnfv_testapi.common import constants
import opnfv_testapi.resources.scenario_models as models
-from test_testcase import TestBase
+import test_base as base
-class TestScenarioBase(TestBase):
+class TestScenarioBase(base.TestBase):
def setUp(self):
super(TestScenarioBase, self).setUp()
self.get_res = models.Scenario
@@ -38,13 +36,13 @@ class TestScenarioBase(TestBase):
return res.href.split('/')[-1]
def assert_res(self, code, scenario, req=None):
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
if req is None:
req = self.req_d
- scenario_dict = scenario.format_http()
- self.assertIsNotNone(scenario_dict['_id'])
- self.assertIsNotNone(scenario_dict['creation_date'])
- self.assertDictContainsSubset(req, scenario_dict)
+ self.assertIsNotNone(scenario._id)
+ self.assertIsNotNone(scenario.creation_date)
+
+ scenario == models.Scenario.from_dict(req)
@staticmethod
def _set_query(*args):
@@ -61,29 +59,29 @@ class TestScenarioBase(TestBase):
class TestScenarioCreate(TestScenarioBase):
def test_withoutBody(self):
(code, body) = self.create()
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
def test_emptyName(self):
req_empty = models.ScenarioCreateRequest('')
(code, body) = self.create(req_empty)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_noneName(self):
req_none = models.ScenarioCreateRequest(None)
(code, body) = self.create(req_none)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_success(self):
(code, body) = self.create_d()
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_create_body(body)
def test_alreadyExist(self):
self.create_d()
(code, body) = self.create_d()
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn('already exists', body)
@@ -126,7 +124,7 @@ class TestScenarioGet(TestScenarioBase):
def _query_and_assert(self, query, found=True, reqs=None):
code, body = self.query(query)
if not found:
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assertEqual(0, len(body.scenarios))
else:
self.assertEqual(len(reqs), len(body.scenarios))
@@ -296,10 +294,23 @@ class TestScenarioUpdate(TestScenarioBase):
def _update_and_assert(self, update_req, new_scenario, name=None):
code, _ = self.update(update_req, self.scenario)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self._get_and_assert(self._none_default(name, self.scenario),
new_scenario)
@staticmethod
def _none_default(check, default):
return check if check else default
+
+
+class TestScenarioDelete(TestScenarioBase):
+ def test_notFound(self):
+ code, body = self.delete('notFound')
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
+
+ def test_success(self):
+ scenario = self.create_return_name(self.req_d)
+ code, _ = self.delete(scenario)
+ self.assertEqual(code, constants.HTTP_OK)
+ code, _ = self.get(scenario)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_testcase.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_testcase.py
index cb767844a..c0494db5d 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_testcase.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_testcase.py
@@ -6,35 +6,33 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-import unittest
import copy
+import unittest
-from test_base import TestBase
-from opnfv_testapi.resources.testcase_models import TestcaseCreateRequest, \
- Testcase, Testcases, TestcaseUpdateRequest
-from opnfv_testapi.resources.project_models import ProjectCreateRequest
-from opnfv_testapi.common.constants import HTTP_OK, HTTP_BAD_REQUEST, \
- HTTP_FORBIDDEN, HTTP_NOT_FOUND
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import project_models
+from opnfv_testapi.resources import testcase_models
+import test_base as base
-class TestCaseBase(TestBase):
+class TestCaseBase(base.TestBase):
def setUp(self):
super(TestCaseBase, self).setUp()
- self.req_d = TestcaseCreateRequest('vping_1',
- '/cases/vping_1',
- 'vping-ssh test')
- self.req_e = TestcaseCreateRequest('doctor_1',
- '/cases/doctor_1',
- 'create doctor')
- self.update_d = TestcaseUpdateRequest('vping_1',
- 'vping-ssh test',
- 'functest')
- self.update_e = TestcaseUpdateRequest('doctor_1',
- 'create doctor',
- 'functest')
- self.get_res = Testcase
- self.list_res = Testcases
- self.update_res = Testcase
+ self.req_d = testcase_models.TestcaseCreateRequest('vping_1',
+ '/cases/vping_1',
+ 'vping-ssh test')
+ self.req_e = testcase_models.TestcaseCreateRequest('doctor_1',
+ '/cases/doctor_1',
+ 'create doctor')
+ self.update_d = testcase_models.TestcaseUpdateRequest('vping_1',
+ 'vping-ssh test',
+ 'functest')
+ self.update_e = testcase_models.TestcaseUpdateRequest('doctor_1',
+ 'create doctor',
+ 'functest')
+ self.get_res = testcase_models.Testcase
+ self.list_res = testcase_models.Testcases
+ self.update_res = testcase_models.Testcase
self.basePath = '/api/v1/projects/%s/cases'
self.create_project()
@@ -57,7 +55,8 @@ class TestCaseBase(TestBase):
self.assertIsNotNone(new.creation_date)
def create_project(self):
- req_p = ProjectCreateRequest('functest', 'vping-ssh test')
+ req_p = project_models.ProjectCreateRequest('functest',
+ 'vping-ssh test')
self.create_help('/api/v1/projects', req_p)
self.project = req_p.name
@@ -80,46 +79,46 @@ class TestCaseBase(TestBase):
class TestCaseCreate(TestCaseBase):
def test_noBody(self):
(code, body) = self.create(None, 'vping')
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
def test_noProject(self):
code, body = self.create(self.req_d, 'noProject')
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn('Could not find project', body)
def test_emptyName(self):
- req_empty = TestcaseCreateRequest('')
+ req_empty = testcase_models.TestcaseCreateRequest('')
(code, body) = self.create(req_empty, self.project)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_noneName(self):
- req_none = TestcaseCreateRequest(None)
+ req_none = testcase_models.TestcaseCreateRequest(None)
(code, body) = self.create(req_none, self.project)
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
self.assertIn('name missing', body)
def test_success(self):
code, body = self.create_d()
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_create_body(body, None, self.project)
def test_alreadyExist(self):
self.create_d()
code, body = self.create_d()
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn('already exists', body)
class TestCaseGet(TestCaseBase):
def test_notExist(self):
code, body = self.get('notExist')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_getOne(self):
self.create_d()
code, body = self.get(self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assert_body(body)
def test_list(self):
@@ -136,23 +135,23 @@ class TestCaseGet(TestCaseBase):
class TestCaseUpdate(TestCaseBase):
def test_noBody(self):
code, _ = self.update(case='noBody')
- self.assertEqual(code, HTTP_BAD_REQUEST)
+ self.assertEqual(code, constants.HTTP_BAD_REQUEST)
def test_notFound(self):
code, _ = self.update(self.update_e, 'notFound')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_newNameExist(self):
self.create_d()
self.create_e()
code, body = self.update(self.update_e, self.req_d.name)
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn("already exists", body)
def test_noUpdate(self):
self.create_d()
code, body = self.update(self.update_d, self.req_d.name)
- self.assertEqual(code, HTTP_FORBIDDEN)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
self.assertIn("Nothing to update", body)
def test_success(self):
@@ -161,7 +160,7 @@ class TestCaseUpdate(TestCaseBase):
_id = body._id
code, body = self.update(self.update_e, self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assertEqual(_id, body._id)
self.assert_update_body(self.req_d, body, self.update_e)
@@ -174,22 +173,22 @@ class TestCaseUpdate(TestCaseBase):
update = copy.deepcopy(self.update_d)
update.description = {'2. change': 'dollar change'}
code, body = self.update(update, self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
class TestCaseDelete(TestCaseBase):
def test_notFound(self):
code, body = self.delete('notFound')
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
def test_success(self):
self.create_d()
code, body = self.delete(self.req_d.name)
- self.assertEqual(code, HTTP_OK)
+ self.assertEqual(code, constants.HTTP_OK)
self.assertEqual(body, '')
code, body = self.get(self.req_d.name)
- self.assertEqual(code, HTTP_NOT_FOUND)
+ self.assertEqual(code, constants.HTTP_NOT_FOUND)
if __name__ == '__main__':
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_token.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_token.py
new file mode 100644
index 000000000..19b9e3e07
--- /dev/null
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_token.py
@@ -0,0 +1,118 @@
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import unittest
+
+from tornado import web
+
+import fake_pymongo
+from opnfv_testapi.common import constants
+from opnfv_testapi.resources import project_models
+from opnfv_testapi.router import url_mappings
+import test_base as base
+
+
+class TestToken(base.TestBase):
+ def get_app(self):
+ return web.Application(
+ url_mappings.mappings,
+ db=fake_pymongo,
+ debug=True,
+ auth=True
+ )
+
+
+class TestTokenCreateProject(TestToken):
+ def setUp(self):
+ super(TestTokenCreateProject, self).setUp()
+ self.req_d = project_models.ProjectCreateRequest('vping')
+ fake_pymongo.tokens.insert({"access_token": "12345"})
+ self.basePath = '/api/v1/projects'
+
+ def test_projectCreateTokenInvalid(self):
+ self.headers['X-Auth-Token'] = '1234'
+ code, body = self.create_d()
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
+ self.assertIn('Invalid Token.', body)
+
+ def test_projectCreateTokenUnauthorized(self):
+ self.headers.pop('X-Auth-Token')
+ code, body = self.create_d()
+ self.assertEqual(code, constants.HTTP_UNAUTHORIZED)
+ self.assertIn('No Authentication Header.', body)
+
+ def test_projectCreateTokenSuccess(self):
+ self.headers['X-Auth-Token'] = '12345'
+ code, body = self.create_d()
+ self.assertEqual(code, constants.HTTP_OK)
+
+
+class TestTokenDeleteProject(TestToken):
+ def setUp(self):
+ super(TestTokenDeleteProject, self).setUp()
+ self.req_d = project_models.ProjectCreateRequest('vping')
+ fake_pymongo.tokens.insert({"access_token": "12345"})
+ self.basePath = '/api/v1/projects'
+
+ def test_projectDeleteTokenIvalid(self):
+ self.headers['X-Auth-Token'] = '12345'
+ self.create_d()
+ self.headers['X-Auth-Token'] = '1234'
+ code, body = self.delete(self.req_d.name)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
+ self.assertIn('Invalid Token.', body)
+
+ def test_projectDeleteTokenUnauthorized(self):
+ self.headers['X-Auth-Token'] = '12345'
+ self.create_d()
+ self.headers.pop('X-Auth-Token')
+ code, body = self.delete(self.req_d.name)
+ self.assertEqual(code, constants.HTTP_UNAUTHORIZED)
+ self.assertIn('No Authentication Header.', body)
+
+ def test_projectDeleteTokenSuccess(self):
+ self.headers['X-Auth-Token'] = '12345'
+ self.create_d()
+ code, body = self.delete(self.req_d.name)
+ self.assertEqual(code, constants.HTTP_OK)
+
+
+class TestTokenUpdateProject(TestToken):
+ def setUp(self):
+ super(TestTokenUpdateProject, self).setUp()
+ self.req_d = project_models.ProjectCreateRequest('vping')
+ fake_pymongo.tokens.insert({"access_token": "12345"})
+ self.basePath = '/api/v1/projects'
+
+ def test_projectUpdateTokenIvalid(self):
+ self.headers['X-Auth-Token'] = '12345'
+ self.create_d()
+ code, body = self.get(self.req_d.name)
+ self.headers['X-Auth-Token'] = '1234'
+ req = project_models.ProjectUpdateRequest('newName', 'new description')
+ code, body = self.update(req, self.req_d.name)
+ self.assertEqual(code, constants.HTTP_FORBIDDEN)
+ self.assertIn('Invalid Token.', body)
+
+ def test_projectUpdateTokenUnauthorized(self):
+ self.headers['X-Auth-Token'] = '12345'
+ self.create_d()
+ code, body = self.get(self.req_d.name)
+ self.headers.pop('X-Auth-Token')
+ req = project_models.ProjectUpdateRequest('newName', 'new description')
+ code, body = self.update(req, self.req_d.name)
+ self.assertEqual(code, constants.HTTP_UNAUTHORIZED)
+ self.assertIn('No Authentication Header.', body)
+
+ def test_projectUpdateTokenSuccess(self):
+ self.headers['X-Auth-Token'] = '12345'
+ self.create_d()
+ code, body = self.get(self.req_d.name)
+ req = project_models.ProjectUpdateRequest('newName', 'new description')
+ code, body = self.update(req, self.req_d.name)
+ self.assertEqual(code, constants.HTTP_OK)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/test_version.py b/utils/test/testapi/opnfv_testapi/tests/unit/test_version.py
index b6fbf45dc..c8f3f5062 100644
--- a/utils/test/testapi/opnfv_testapi/tests/unit/test_version.py
+++ b/utils/test/testapi/opnfv_testapi/tests/unit/test_version.py
@@ -8,14 +8,14 @@
##############################################################################
import unittest
-from test_base import TestBase
-from opnfv_testapi.resources.models import Versions
+from opnfv_testapi.resources import models
+import test_base as base
-class TestVersionBase(TestBase):
+class TestVersionBase(base.TestBase):
def setUp(self):
super(TestVersionBase, self).setUp()
- self.list_res = Versions
+ self.list_res = models.Versions
self.basePath = '/versions'