provide REST api for frontend of testing-scheduler 09/60009/3
authorLeoQi <QibinZheng2014@tongji.edu.cn>
Thu, 19 Jul 2018 18:47:26 +0000 (02:47 +0800)
committerLeoQi <QibinZheng2014@tongji.edu.cn>
Thu, 30 Aug 2018 10:55:59 +0000 (18:55 +0800)
JIRA: BOTTLENECK-235

the REST api code in backend part.

Change-Id: I1f53ed5f0f87e6908ff4fd27f752ec2c185dc9be
Signed-off-by: Zheng Qibin <QibinZheng2014@tongji.edu.cn>
testing-scheduler/server/src/rest/__init__.py [new file with mode: 0644]
testing-scheduler/server/src/rest/router.py [new file with mode: 0644]
testing-scheduler/server/src/rest/test_service_demo.py [new file with mode: 0644]

diff --git a/testing-scheduler/server/src/rest/__init__.py b/testing-scheduler/server/src/rest/__init__.py
new file mode 100644 (file)
index 0000000..b513903
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env python\r
+\r
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/src/rest/router.py b/testing-scheduler/server/src/rest/router.py
new file mode 100644 (file)
index 0000000..b9cbd92
--- /dev/null
@@ -0,0 +1,485 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+from flask import Flask\r
+from flask import jsonify\r
+from flask import request\r
+from flask_cors import CORS\r
+import os\r
+import json\r
+import time\r
+import pyaml\r
+import yaml\r
+import traceback\r
+\r
+import src.test_parser as test_parser\r
+\r
+\r
+BASE_DIR = os.path.abspath(os.path.dirname(__file__))\r
+TESTSUITE_DIR = os.path.join(BASE_DIR, "..", "..", "test", "test_case")\r
+SERVICE_DIR = os.path.join(BASE_DIR, "..", "env", "service")\r
+CONTEXT_FILE_DIR = os.path.join(BASE_DIR, "..", "env", "context",\r
+                                "context.yaml")\r
+app = Flask(__name__)\r
+CORS(app)\r
+\r
+\r
+###############\r
+# 1. EXECUTE API\r
+###########################################################################\r
+@app.route("/")\r
+def hello():\r
+    return "Hello, World! This is a greet from parser." + SERVICE_DIR\r
+\r
+\r
+@app.route("/execute/testcase", methods=['POST'])\r
+def runTestcase():\r
+    suiteName = request.values.get('suiteName')\r
+    caseName = request.values.get('caseName')\r
+    try:\r
+        casePath = os.path.join(TESTSUITE_DIR, suiteName, caseName)\r
+        if os.path.exists(casePath):\r
+            workflowId = test_parser.parse(casePath)\r
+            if workflowId is None or workflowId == '':\r
+                return jsonify({"code": 500, "error": "Server Error."})\r
+            return jsonify({"code": 200, "result": {"workflowId": workflowId}})\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such test case:  %s" %\r
+                           (os.path.join(suiteName, caseName))})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+\r
+@app.route("/story-content")\r
+def getStoryContent():\r
+    try:\r
+        story_name = request.args['story']\r
+        service_name = request.args['service']\r
+        storyFileDir = os.path.join("/tmp", "generate_workflow.json")\r
+        with open(storyFileDir, "r") as f:\r
+            storyContent = f.read()\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    result = {"code": 200, "result":\r
+              {"service": service_name, "story": story_name,\r
+               "content": storyContent}}\r
+    return jsonify(result)\r
+\r
+\r
+###############\r
+# 2. TESTCASE CRUD\r
+###########################################################################\r
+@app.route("/testsuite/list")\r
+def getAllSuite():\r
+    res = []\r
+    id = 1\r
+    try:\r
+        for fileName in os.listdir(TESTSUITE_DIR):\r
+            suiteInfo = {}\r
+            suiteInfo["id"] = id\r
+            suiteInfo["testsuite"] = fileName\r
+            res.append(suiteInfo)\r
+            id = id + 1\r
+    except BaseException, e:\r
+        print e\r
+        app.logger.error(traceback.format_exc())\r
+        return jsonify({"code": 500, "error": "Server error"})\r
+\r
+    return jsonify({"code": 200, "result": res})\r
+\r
+\r
+@app.route("/testsuite/content")\r
+def getSuiteContent():\r
+    res = []\r
+    id = 1\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
+        if os.path.exists(exSuitePath):\r
+            for fileName in os.listdir(exSuitePath):\r
+                tcInfo = {}\r
+                tcInfo["id"] = id\r
+                tcInfo["testcase"] = fileName\r
+                res.append(tcInfo)\r
+                id = id + 1\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such test suite!"})\r
+    except BaseException, e:\r
+        print e\r
+        app.logger.error(traceback.format_exc())\r
+        return jsonify({"code": 500, "error": "Server error"})\r
+\r
+    return jsonify({"code": 200, "result": res})\r
+\r
+\r
+@app.route("/testcase/content")\r
+def getTCContent():\r
+    res = ""\r
+    editorRes = ""\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        caseName = request.values.get("caseName")\r
+        casePath = os.path.join(suiteName, caseName)\r
+        casePath = os.path.join(TESTSUITE_DIR, casePath)\r
+        if os.path.exists(casePath):\r
+            with open(casePath, "r") as f:\r
+                fileContent = f.read()\r
+            res = fileContent\r
+            editorRes = test_parser.getWebTestcase(yaml.load(res))\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such file!"})\r
+    except BaseException, e:\r
+        print e\r
+        app.logger.error(traceback.format_exc())\r
+        return jsonify({"code": 500, "error": "Server error"})\r
+\r
+    return jsonify({"code": 200, "result":\r
+                    {"content": res, "editorContent": editorRes}})\r
+\r
+\r
+@app.route("/testsuite/new", methods=['POST'])\r
+def addNewSuite():\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        for fileName in os.listdir(TESTSUITE_DIR):\r
+            if fileName == suiteName:\r
+                return jsonify({"code": 300,\r
+                                "error": "testsuite already exists!"})\r
+        testSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
+        os.mkdir(testSuitePath)\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    return jsonify({"code": 200, "result": "ok"})\r
+\r
+\r
+@app.route("/testsuite/delete", methods=['POST'])\r
+def deleteSuite():\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        for fileName in os.listdir(TESTSUITE_DIR):\r
+            if fileName == suiteName:\r
+                testSuitePath = os.path.join(TESTSUITE_DIR, fileName)\r
+                del_file(testSuitePath)\r
+                os.rmdir(testSuitePath)\r
+                return jsonify({"code": 200, "result": "ok"})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    return jsonify({"code": 300, "error": "no such testsuite!"})\r
+\r
+\r
+def del_file(path):\r
+    for i in os.listdir(path):\r
+        path_file = os.path.join(path, i)\r
+        if os.path.isfile(path_file):\r
+            os.remove(path_file)\r
+        else:\r
+            del_file(path_file)\r
+\r
+\r
+@app.route("/testcase/new", methods=['POST'])\r
+def createTestcase():\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        caseName = request.values.get("caseName")\r
+        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
+        if os.path.exists(exSuitePath):\r
+            for fileName in os.listdir(exSuitePath):\r
+                if fileName == caseName:\r
+                    return jsonify({"code": 301,\r
+                                    "error": "testcase already exists!"})\r
+            casePath = os.path.join(exSuitePath, caseName)\r
+            with open(casePath, "w") as f:\r
+                # the next line is a placeholder.\r
+                print f\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such test suite!"})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    return jsonify({"code": 200, "result": "ok"})\r
+\r
+\r
+@app.route("/testcase/delete", methods=['POST'])\r
+def deleteTestcase():\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        caseName = request.values.get("caseName")\r
+        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
+        if os.path.exists(exSuitePath):\r
+            for fileName in os.listdir(exSuitePath):\r
+                if fileName == caseName:\r
+                    casePath = os.path.join(exSuitePath, caseName)\r
+                    os.remove(casePath)\r
+                    return jsonify({"code": 200, "result": "ok"})\r
+            return jsonify({"code": 301, "error": "no such test case!"})\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such test suite!"})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+\r
+@app.route("/testcase/save", methods=["POST"])\r
+def saveTCContent():\r
+    try:\r
+        suiteName = request.values.get("suiteName")\r
+        caseName = request.values.get("caseName")\r
+        stepList = json.loads(request.values.get("stepList"))\r
+        subflowList = json.loads(request.values.get("subflowList"))\r
+        mainOrdersList = json.loads(request.values.get("mainOrdersList"))\r
+        jsonObj = {"stepList": stepList, "subflowList": subflowList,\r
+                   "mainOrdersList": mainOrdersList}\r
+        parseData = test_parser.parseWebTestcase(jsonObj)\r
+\r
+        casePath = os.path.join(suiteName, caseName)\r
+        casePath = os.path.join(TESTSUITE_DIR, casePath)\r
+        if os.path.exists(casePath):\r
+            with open(casePath, "w") as f:\r
+                pyaml.dump(parseData, f, safe=True)\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such file!"})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    return jsonify({"code": 200, "result": "save success"})\r
+\r
+\r
+###############\r
+# 3.1 API FOR SERVICE\r
+############################################################\r
+@app.route("/service/list")\r
+def getAllServices():\r
+    res = []\r
+    try:\r
+        for fileName in os.listdir(SERVICE_DIR):\r
+            serviceName = os.path.splitext(fileName)[0]\r
+            res.append(serviceName)\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    return jsonify({"code": 200, "result": res})\r
+\r
+\r
+@app.route("/service/content")\r
+def getServiceContent():\r
+    res = {}\r
+    try:\r
+        serviceName = request.values.get("serviceName")\r
+        for fileName in os.listdir(SERVICE_DIR):\r
+            if serviceName == os.path.splitext(fileName)[0]:\r
+                res["actions"] = []\r
+                filePath = os.path.join(SERVICE_DIR, fileName)\r
+                with open(filePath, "r") as f:\r
+                    content = yaml.load(f)\r
+                    apisArr = content[serviceName]['apis']\r
+                    for i in range(len(apisArr)):\r
+                        apisArr[i].pop("method")\r
+                        apisArr[i].pop("baseuri")\r
+                    res["actions"] = apisArr\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    if res == {}:\r
+        return jsonify({"code": 300, "error": "no such service!"})\r
+\r
+    return jsonify({"code": 200, "result": res})\r
+\r
+\r
+def paramTransform(paramDict):\r
+    res = []\r
+    for (key, value) in paramDict.items():\r
+        paramJson = {}\r
+        paramJson["name"] = key\r
+        paramJson["description"] = value["help"]\r
+        if "params" in value:\r
+            paramJson["params"] = paramTransform(value["params"])\r
+        res.append(paramJson)\r
+    return res\r
+\r
+\r
+@app.route("/service/action_response")\r
+def actionResponse():\r
+    res = {}\r
+    try:\r
+        serviceName = request.values.get("serviceName")\r
+        actionName = request.values.get("actionName")\r
+        for fileName in os.listdir(SERVICE_DIR):\r
+            if serviceName == os.path.splitext(fileName)[0]:\r
+                res["responseParams"] = []\r
+                filePath = os.path.join(SERVICE_DIR, fileName)\r
+                with open(filePath, "r") as f:\r
+                    content = yaml.load(f)\r
+                    apisArr = content[serviceName]['apis']\r
+                for i in range(len(apisArr)):\r
+                    if actionName == apisArr[i]['name'] and (\r
+                       "response" in apisArr[i]):\r
+                        res["responseParams"] = apisArr[i]["response"]\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+    if res == {}:\r
+        return jsonify({"code": 300, "error": "no such service!"})\r
+    return jsonify({"code": 200, "result": res})\r
+\r
+\r
+###############\r
+# 3.2 API FOR ENVIRONMENT SERVICE AND CONTEXT\r
+###########################################################################\r
+@app.route('/env/getAllServices')\r
+def getAllService():\r
+    res = []\r
+    id = 1\r
+    try:\r
+        for fileName in os.listdir(SERVICE_DIR):\r
+            item = {}\r
+            item['id'] = id\r
+            item['name'] = os.path.splitext(fileName)[0]\r
+            filePath = os.path.join(SERVICE_DIR, fileName)\r
+            filemt = time.localtime(os.stat(filePath).st_mtime)\r
+            item['time'] = time.strftime("%Y-%m-%d", filemt)\r
+            res.append(item)\r
+            id = id + 1\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+    return jsonify({"code": 200, "result": res})\r
+\r
+\r
+@app.route('/env/getService')\r
+def getService():\r
+    try:\r
+        serviceName = request.values.get('serviceName')\r
+        serviceFile = serviceName + '.yaml'\r
+        servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
+        if os.path.exists(servicePath):\r
+            with open(servicePath, "r") as f:\r
+                serviceDict = yaml.load(f)\r
+                serviceDict = serviceDict[serviceName]\r
+            return jsonify({"code": 200, "result": serviceDict})\r
+        else:\r
+            return jsonify({"code": 300, "error": "no such service!"})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+\r
+@app.route('/env/createService', methods=['POST'])\r
+def createService():\r
+    try:\r
+        name = str(request.values.get('name'))\r
+        ip = str(request.values.get('ip'))\r
+        port = int(request.values.get('port'))\r
+        apis = json.loads(request.values.get('apis'))\r
+        service = {\r
+            name: {\r
+                'ip': ip,\r
+                'port': port,\r
+                'apis': apis\r
+            }\r
+        }\r
+        serviceJson = json.dumps(service, indent=True)\r
+        print serviceJson\r
+        app.logger.debug(service)\r
+\r
+        serviceFile = name + '.yaml'\r
+        servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
+        with open(servicePath, 'w') as f:\r
+            pyaml.dump(service, f, safe=True)\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+    return jsonify({"code": 200, "result": "create success!"})\r
+\r
+\r
+@app.route('/env/editService', methods=['POST'])\r
+def editService():\r
+    try:\r
+        oldName = str(request.values.get('oldName'))\r
+        name = str(request.values.get('newName'))\r
+        ip = str(request.values.get('ip'))\r
+        port = int(request.values.get('port'))\r
+        apis = json.loads(request.values.get('apis'))\r
+        app.logger.debug(apis)\r
+        service = {\r
+            name: {\r
+                'ip': ip,\r
+                'port': port,\r
+                'apis': apis\r
+            }\r
+        }\r
+        serviceJson = json.dumps(service, indent=True)\r
+        print serviceJson\r
+        app.logger.debug(service)\r
+\r
+        for fileName in os.listdir(SERVICE_DIR):\r
+            serviceName = os.path.splitext(fileName)[0]\r
+            if serviceName == oldName:\r
+                filePath = os.path.join(SERVICE_DIR, fileName)\r
+                os.remove(filePath)\r
+\r
+        serviceFile = name + '.yaml'\r
+        servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
+        with open(servicePath, 'w') as f:\r
+            pyaml.dump(service, f, safe=True)\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+    return jsonify({"code": 200, "result": "edit success!"})\r
+\r
+\r
+@app.route('/env/deleteService', methods=['POST'])\r
+def deleteService():\r
+    try:\r
+        name = str(request.values.get('serviceName'))\r
+\r
+        for fileName in os.listdir(SERVICE_DIR):\r
+            serviceName = os.path.splitext(fileName)[0]\r
+            if serviceName == name:\r
+                filePath = os.path.join(SERVICE_DIR, fileName)\r
+                os.remove(filePath)\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+    return jsonify({"code": 200, "result": "delete success!"})\r
+\r
+\r
+@app.route('/env/getContext')\r
+def getContext():\r
+    try:\r
+        with open(CONTEXT_FILE_DIR, "r") as f:\r
+            fileContent = f.read()\r
+        res = fileContent\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+    return jsonify({"code": 200, "result": {"context": res}})\r
+\r
+\r
+@app.route('/env/editContext', methods=['POST'])\r
+def editContext():\r
+    try:\r
+        context = request.values.get("context")\r
+        test = yaml.load(context)\r
+        print test\r
+        with open(CONTEXT_FILE_DIR, "w") as f:\r
+            f.write(context)\r
+    except yaml.constructor.ConstructorError, e:\r
+        app.logger.error(traceback.format_exc())\r
+        return jsonify({"code": 500, "error":\r
+                        "context content error: not a .yaml file!"})\r
+    except BaseException, e:\r
+        return returnServerError(e)\r
+\r
+    return jsonify({"code": 200, "result": "edit context success!"})\r
+###########################################################################\r
+\r
+\r
+def returnServerError(e, msg="Server Error"):\r
+    print e\r
+    app.logger.error(traceback.format_exc())\r
+    return jsonify({"code": 500, "error": msg})\r
+\r
+\r
+if __name__ == "__main__":\r
+    app.run(host='0.0.0.0', port=5310)\r
diff --git a/testing-scheduler/server/src/rest/test_service_demo.py b/testing-scheduler/server/src/rest/test_service_demo.py
new file mode 100644 (file)
index 0000000..e6f4e38
--- /dev/null
@@ -0,0 +1,77 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+from flask import Flask\r
+from flask_cors import CORS\r
+from flask import request\r
+from flask import jsonify\r
+import time\r
+import json\r
+from random import randint\r
+\r
+app = Flask(__name__)\r
+CORS(app)\r
+\r
+\r
+@app.route("/greet")\r
+def greet():\r
+    return "hello"\r
+\r
+\r
+@app.route("/answer", methods=["POST"])\r
+def answer():\r
+    app.logger.debug(request.form)\r
+    app.logger.debug(request.data)\r
+    if jsonify(request.form) != {} and 'ping' in request.form:\r
+        return "answer: ping is: \"" + request.form['ping'] + "\" end."\r
+    elif request.data != "":\r
+        requestDict = json.loads(request.data)\r
+        if 'ping' in requestDict:\r
+            return "answer: the ping is: \"" + requestDict['ping'] + "\" end."\r
+    else:\r
+        return "answer ping is null"\r
+\r
+\r
+@app.route("/answer2", methods=["POST"])\r
+def answer2():\r
+    return "ok"\r
+\r
+\r
+@app.route("/five")\r
+def sleepFiveSeconds():\r
+    time.sleep(5)\r
+    return "five: receive the request."\r
+\r
+\r
+@app.route("/ten")\r
+def sleepTenSeconds():\r
+    time.sleep(10)\r
+    return "ten: receive the request."\r
+\r
+\r
+@app.route("/switch")\r
+def switchValue():\r
+    value = randint(0, 10)\r
+    if value > 4:\r
+        return jsonify({'code': 200, 'result': 'A'})\r
+    else:\r
+        return jsonify({'code': 200, 'result': 'B'})\r
+\r
+\r
+@app.route("/switch_2")\r
+def switchValue_2():\r
+    value = randint(0, 10)\r
+    if value > 4:\r
+        return jsonify({'code': 200, 'result': 'C'})\r
+    else:\r
+        return jsonify({'code': 200, 'result': 'D'})\r
+\r
+\r
+if __name__ == "__main__":\r
+    app.run(host='0.0.0.0', port=5312, debug=True)\r