summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorchenjiankun <chenjiankun1@huawei.com>2016-11-17 08:01:14 +0000
committerchenjiankun <chenjiankun1@huawei.com>2016-11-21 08:59:40 +0000
commit0e23c697e6329a57ba168cc57886b436ea87cdc4 (patch)
tree9344c63ed5296375dda7b0f0f2a3d85c06d7048e /api
parenteeeca4f0cdeff152ec061bb9b40ae305547c027e (diff)
Create API to run test cases
JIRA: YARDSTICK-413 Change-Id: Ibf58b50b568fae3f2eea985b25ee33be0a3666b7 Signed-off-by: chenjiankun <chenjiankun1@huawei.com>
Diffstat (limited to 'api')
-rw-r--r--api/__init__.py0
-rw-r--r--api/actions/__init__.py0
-rw-r--r--api/actions/test.py40
-rw-r--r--api/conf.py17
-rw-r--r--api/server.py19
-rw-r--r--api/urls.py7
-rw-r--r--api/utils/__init__.py0
-rw-r--r--api/utils/common.py41
-rw-r--r--api/utils/daemonthread.py36
-rw-r--r--api/utils/influx.py55
-rw-r--r--api/views.py29
11 files changed, 244 insertions, 0 deletions
diff --git a/api/__init__.py b/api/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/__init__.py
diff --git a/api/actions/__init__.py b/api/actions/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/actions/__init__.py
diff --git a/api/actions/test.py b/api/actions/test.py
new file mode 100644
index 000000000..0de70bb71
--- /dev/null
+++ b/api/actions/test.py
@@ -0,0 +1,40 @@
+import uuid
+import json
+import os
+import logging
+
+from api import conf
+from api.utils import common as common_utils
+
+logger = logging.getLogger(__name__)
+
+
+def runTestCase(args):
+ try:
+ opts = args.get('opts', {})
+ testcase = args['testcase']
+ except KeyError:
+ logger.error('Lack of testcase argument')
+ result = {
+ 'status': 'error',
+ 'message': 'need testcase name'
+ }
+ return json.dumps(result)
+
+ testcase = os.path.join(conf.TEST_CASE_PATH,
+ conf.TEST_CASE_PRE + testcase + '.yaml')
+
+ task_id = str(uuid.uuid4())
+
+ command_list = ['task', 'start']
+ command_list = common_utils.get_command_list(command_list, opts, testcase)
+ logger.debug('The command_list is: %s', command_list)
+
+ logger.debug('Start to execute command list')
+ common_utils.exec_command_task(command_list, task_id)
+
+ result = {
+ 'status': 'success',
+ 'task_id': task_id
+ }
+ return json.dumps(result)
diff --git a/api/conf.py b/api/conf.py
new file mode 100644
index 000000000..b5553f452
--- /dev/null
+++ b/api/conf.py
@@ -0,0 +1,17 @@
+from pyroute2 import IPDB
+
+
+# configuration for influxdb
+with IPDB() as ip:
+ GATEWAY_IP = ip.routes['default'].gateway
+PORT = 8086
+
+TEST_ACTION = ['runTestCase']
+
+TEST_CASE_PATH = '../tests/opnfv/test_cases/'
+
+TEST_CASE_PRE = 'opnfv_yardstick_'
+
+TEST_SUITE_PATH = '../tests/opnfv/test_suites/'
+
+OUTPUT_CONFIG_FILE_PATH = '/etc/yardstick/yardstick.conf'
diff --git a/api/server.py b/api/server.py
new file mode 100644
index 000000000..d0e4d30a2
--- /dev/null
+++ b/api/server.py
@@ -0,0 +1,19 @@
+import logging
+
+from flask import Flask
+from flask_restful import Api
+
+from api.urls import urlpatterns
+
+logger = logging.getLogger(__name__)
+
+app = Flask(__name__)
+
+api = Api(app)
+
+reduce(lambda a, b: a.add_resource(b.resource, b.url,
+ endpoint=b.endpoint) or a, urlpatterns, api)
+
+if __name__ == '__main__':
+ logger.info('Starting server')
+ app.run(host='0.0.0.0')
diff --git a/api/urls.py b/api/urls.py
new file mode 100644
index 000000000..9fa0bc935
--- /dev/null
+++ b/api/urls.py
@@ -0,0 +1,7 @@
+from api import views
+from api.utils.common import Url
+
+
+urlpatterns = [
+ Url('/yardstick/test/action', views.Test, 'test')
+]
diff --git a/api/utils/__init__.py b/api/utils/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/utils/__init__.py
diff --git a/api/utils/common.py b/api/utils/common.py
new file mode 100644
index 000000000..9d7998abd
--- /dev/null
+++ b/api/utils/common.py
@@ -0,0 +1,41 @@
+import collections
+
+from api.utils.daemonthread import DaemonThread
+from yardstick.cmd.cli import YardstickCLI
+
+
+def translate_to_str(object):
+ if isinstance(object, collections.Mapping):
+ return {str(k): translate_to_str(v) for k, v in object.items()}
+ elif isinstance(object, list):
+ return [translate_to_str(ele) for ele in object]
+ elif isinstance(object, unicode):
+ return str(object)
+ return object
+
+
+def get_command_list(command_list, opts, args):
+
+ command_list.append(args)
+
+ command_list.extend(('--{}'.format(k) for k in opts if 'task-args' != k))
+
+ task_args = opts.get('task_args', '')
+ if task_args:
+ command_list.extend(['--task-args', task_args])
+
+ return command_list
+
+
+def exec_command_task(command_list, task_id): # pragma: no cover
+ daemonthread = DaemonThread(YardstickCLI().api, (command_list, task_id))
+ daemonthread.start()
+
+
+class Url(object):
+
+ def __init__(self, url, resource, endpoint):
+ super(Url, self).__init__()
+ self.url = url
+ self.resource = resource
+ self.endpoint = endpoint
diff --git a/api/utils/daemonthread.py b/api/utils/daemonthread.py
new file mode 100644
index 000000000..77a0f6ab7
--- /dev/null
+++ b/api/utils/daemonthread.py
@@ -0,0 +1,36 @@
+import threading
+import os
+import datetime
+import errno
+
+from api import conf
+from api.utils.influx import write_data_tasklist
+
+
+class DaemonThread(threading.Thread):
+
+ def __init__(self, method, args):
+ super(DaemonThread, self).__init__(target=method, args=args)
+ self.method = method
+ self.command_list = args[0]
+ self.task_id = args[1]
+
+ def run(self):
+ timestamp = datetime.datetime.now()
+
+ try:
+ write_data_tasklist(self.task_id, timestamp, 0)
+ self.method(self.command_list, self.task_id)
+ write_data_tasklist(self.task_id, timestamp, 1)
+ except Exception as e:
+ write_data_tasklist(self.task_id, timestamp, 2, error=str(e))
+ finally:
+ _handle_testsuite_file(self.task_id)
+
+
+def _handle_testsuite_file(task_id):
+ try:
+ os.remove(os.path.join(conf.TEST_SUITE_PATH, task_id + '.yaml'))
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
diff --git a/api/utils/influx.py b/api/utils/influx.py
new file mode 100644
index 000000000..52a90b61c
--- /dev/null
+++ b/api/utils/influx.py
@@ -0,0 +1,55 @@
+import logging
+from urlparse import urlsplit
+
+from influxdb import InfluxDBClient
+import ConfigParser
+
+from api import conf
+
+logger = logging.getLogger(__name__)
+
+
+def get_data_db_client():
+ parser = ConfigParser.ConfigParser()
+ try:
+ parser.read(conf.OUTPUT_CONFIG_FILE_PATH)
+ dispatcher = parser.get('DEFAULT', 'dispatcher')
+
+ if 'influxdb' != dispatcher:
+ raise RuntimeError
+
+ ip = _get_ip(parser.get('dispatcher_influxdb', 'target'))
+ username = parser.get('dispatcher_influxdb', 'username')
+ password = parser.get('dispatcher_influxdb', 'password')
+ db_name = parser.get('dispatcher_influxdb', 'db_name')
+ return InfluxDBClient(ip, conf.PORT, username, password, db_name)
+ except ConfigParser.NoOptionError:
+ logger.error('can not find the key')
+ raise
+
+
+def _get_ip(url):
+ return urlsplit(url).netloc.split(':')[0]
+
+
+def _write_data(measurement, field, timestamp, tags):
+ point = {
+ 'measurement': measurement,
+ 'fields': field,
+ 'time': timestamp,
+ 'tags': tags
+ }
+
+ try:
+ client = get_data_db_client()
+
+ logger.debug('Start to write data: %s', point)
+ client.write_points([point])
+ except RuntimeError:
+ logger.debug('dispatcher is not influxdb')
+
+
+def write_data_tasklist(task_id, timestamp, status, error=''):
+ field = {'status': status, 'error': error}
+ tags = {'task_id': task_id}
+ _write_data('tasklist', field, timestamp, tags)
diff --git a/api/views.py b/api/views.py
new file mode 100644
index 000000000..883091222
--- /dev/null
+++ b/api/views.py
@@ -0,0 +1,29 @@
+import json
+import logging
+
+from flask import request
+from flask_restful import Resource
+
+from api.utils import common as common_utils
+from api.actions import test as test_action
+from api import conf
+
+logger = logging.getLogger(__name__)
+
+
+class Test(Resource):
+ def post(self):
+ action = common_utils.translate_to_str(request.json.get('action', ''))
+ args = common_utils.translate_to_str(request.json.get('args', {}))
+ logger.debug('Input args is: action: %s, args: %s', action, args)
+
+ if action not in conf.TEST_ACTION:
+ logger.error('Wrong action')
+ result = {
+ 'status': 'error',
+ 'message': 'wrong action'
+ }
+ return json.dumps(result)
+
+ method = getattr(test_action, action)
+ return method(args)