b9cbd9285c57a9a35e63d275abf39ac8c54ed9a5
[bottlenecks.git] / testing-scheduler / server / src / rest / router.py
1 ##############################################################################\r
2 # Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
3 #\r
4 # All rights reserved. This program and the accompanying materials\r
5 # are made available under the terms of the Apache License, Version 2.0\r
6 # which accompanies this distribution, and is available at\r
7 # http://www.apache.org/licenses/LICENSE-2.0\r
8 ##############################################################################\r
9 \r
10 from flask import Flask\r
11 from flask import jsonify\r
12 from flask import request\r
13 from flask_cors import CORS\r
14 import os\r
15 import json\r
16 import time\r
17 import pyaml\r
18 import yaml\r
19 import traceback\r
20 \r
21 import src.test_parser as test_parser\r
22 \r
23 \r
24 BASE_DIR = os.path.abspath(os.path.dirname(__file__))\r
25 TESTSUITE_DIR = os.path.join(BASE_DIR, "..", "..", "test", "test_case")\r
26 SERVICE_DIR = os.path.join(BASE_DIR, "..", "env", "service")\r
27 CONTEXT_FILE_DIR = os.path.join(BASE_DIR, "..", "env", "context",\r
28                                 "context.yaml")\r
29 app = Flask(__name__)\r
30 CORS(app)\r
31 \r
32 \r
33 ###############\r
34 # 1. EXECUTE API\r
35 ###########################################################################\r
36 @app.route("/")\r
37 def hello():\r
38     return "Hello, World! This is a greet from parser." + SERVICE_DIR\r
39 \r
40 \r
41 @app.route("/execute/testcase", methods=['POST'])\r
42 def runTestcase():\r
43     suiteName = request.values.get('suiteName')\r
44     caseName = request.values.get('caseName')\r
45     try:\r
46         casePath = os.path.join(TESTSUITE_DIR, suiteName, caseName)\r
47         if os.path.exists(casePath):\r
48             workflowId = test_parser.parse(casePath)\r
49             if workflowId is None or workflowId == '':\r
50                 return jsonify({"code": 500, "error": "Server Error."})\r
51             return jsonify({"code": 200, "result": {"workflowId": workflowId}})\r
52         else:\r
53             return jsonify({"code": 300, "error": "no such test case:  %s" %\r
54                            (os.path.join(suiteName, caseName))})\r
55     except BaseException, e:\r
56         return returnServerError(e)\r
57 \r
58 \r
59 @app.route("/story-content")\r
60 def getStoryContent():\r
61     try:\r
62         story_name = request.args['story']\r
63         service_name = request.args['service']\r
64         storyFileDir = os.path.join("/tmp", "generate_workflow.json")\r
65         with open(storyFileDir, "r") as f:\r
66             storyContent = f.read()\r
67     except BaseException, e:\r
68         return returnServerError(e)\r
69 \r
70     result = {"code": 200, "result":\r
71               {"service": service_name, "story": story_name,\r
72                "content": storyContent}}\r
73     return jsonify(result)\r
74 \r
75 \r
76 ###############\r
77 # 2. TESTCASE CRUD\r
78 ###########################################################################\r
79 @app.route("/testsuite/list")\r
80 def getAllSuite():\r
81     res = []\r
82     id = 1\r
83     try:\r
84         for fileName in os.listdir(TESTSUITE_DIR):\r
85             suiteInfo = {}\r
86             suiteInfo["id"] = id\r
87             suiteInfo["testsuite"] = fileName\r
88             res.append(suiteInfo)\r
89             id = id + 1\r
90     except BaseException, e:\r
91         print e\r
92         app.logger.error(traceback.format_exc())\r
93         return jsonify({"code": 500, "error": "Server error"})\r
94 \r
95     return jsonify({"code": 200, "result": res})\r
96 \r
97 \r
98 @app.route("/testsuite/content")\r
99 def getSuiteContent():\r
100     res = []\r
101     id = 1\r
102     try:\r
103         suiteName = request.values.get("suiteName")\r
104         exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
105         if os.path.exists(exSuitePath):\r
106             for fileName in os.listdir(exSuitePath):\r
107                 tcInfo = {}\r
108                 tcInfo["id"] = id\r
109                 tcInfo["testcase"] = fileName\r
110                 res.append(tcInfo)\r
111                 id = id + 1\r
112         else:\r
113             return jsonify({"code": 300, "error": "no such test suite!"})\r
114     except BaseException, e:\r
115         print e\r
116         app.logger.error(traceback.format_exc())\r
117         return jsonify({"code": 500, "error": "Server error"})\r
118 \r
119     return jsonify({"code": 200, "result": res})\r
120 \r
121 \r
122 @app.route("/testcase/content")\r
123 def getTCContent():\r
124     res = ""\r
125     editorRes = ""\r
126     try:\r
127         suiteName = request.values.get("suiteName")\r
128         caseName = request.values.get("caseName")\r
129         casePath = os.path.join(suiteName, caseName)\r
130         casePath = os.path.join(TESTSUITE_DIR, casePath)\r
131         if os.path.exists(casePath):\r
132             with open(casePath, "r") as f:\r
133                 fileContent = f.read()\r
134             res = fileContent\r
135             editorRes = test_parser.getWebTestcase(yaml.load(res))\r
136         else:\r
137             return jsonify({"code": 300, "error": "no such file!"})\r
138     except BaseException, e:\r
139         print e\r
140         app.logger.error(traceback.format_exc())\r
141         return jsonify({"code": 500, "error": "Server error"})\r
142 \r
143     return jsonify({"code": 200, "result":\r
144                     {"content": res, "editorContent": editorRes}})\r
145 \r
146 \r
147 @app.route("/testsuite/new", methods=['POST'])\r
148 def addNewSuite():\r
149     try:\r
150         suiteName = request.values.get("suiteName")\r
151         for fileName in os.listdir(TESTSUITE_DIR):\r
152             if fileName == suiteName:\r
153                 return jsonify({"code": 300,\r
154                                 "error": "testsuite already exists!"})\r
155         testSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
156         os.mkdir(testSuitePath)\r
157     except BaseException, e:\r
158         return returnServerError(e)\r
159 \r
160     return jsonify({"code": 200, "result": "ok"})\r
161 \r
162 \r
163 @app.route("/testsuite/delete", methods=['POST'])\r
164 def deleteSuite():\r
165     try:\r
166         suiteName = request.values.get("suiteName")\r
167         for fileName in os.listdir(TESTSUITE_DIR):\r
168             if fileName == suiteName:\r
169                 testSuitePath = os.path.join(TESTSUITE_DIR, fileName)\r
170                 del_file(testSuitePath)\r
171                 os.rmdir(testSuitePath)\r
172                 return jsonify({"code": 200, "result": "ok"})\r
173     except BaseException, e:\r
174         return returnServerError(e)\r
175 \r
176     return jsonify({"code": 300, "error": "no such testsuite!"})\r
177 \r
178 \r
179 def del_file(path):\r
180     for i in os.listdir(path):\r
181         path_file = os.path.join(path, i)\r
182         if os.path.isfile(path_file):\r
183             os.remove(path_file)\r
184         else:\r
185             del_file(path_file)\r
186 \r
187 \r
188 @app.route("/testcase/new", methods=['POST'])\r
189 def createTestcase():\r
190     try:\r
191         suiteName = request.values.get("suiteName")\r
192         caseName = request.values.get("caseName")\r
193         exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
194         if os.path.exists(exSuitePath):\r
195             for fileName in os.listdir(exSuitePath):\r
196                 if fileName == caseName:\r
197                     return jsonify({"code": 301,\r
198                                     "error": "testcase already exists!"})\r
199             casePath = os.path.join(exSuitePath, caseName)\r
200             with open(casePath, "w") as f:\r
201                 # the next line is a placeholder.\r
202                 print f\r
203         else:\r
204             return jsonify({"code": 300, "error": "no such test suite!"})\r
205     except BaseException, e:\r
206         return returnServerError(e)\r
207 \r
208     return jsonify({"code": 200, "result": "ok"})\r
209 \r
210 \r
211 @app.route("/testcase/delete", methods=['POST'])\r
212 def deleteTestcase():\r
213     try:\r
214         suiteName = request.values.get("suiteName")\r
215         caseName = request.values.get("caseName")\r
216         exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
217         if os.path.exists(exSuitePath):\r
218             for fileName in os.listdir(exSuitePath):\r
219                 if fileName == caseName:\r
220                     casePath = os.path.join(exSuitePath, caseName)\r
221                     os.remove(casePath)\r
222                     return jsonify({"code": 200, "result": "ok"})\r
223             return jsonify({"code": 301, "error": "no such test case!"})\r
224         else:\r
225             return jsonify({"code": 300, "error": "no such test suite!"})\r
226     except BaseException, e:\r
227         return returnServerError(e)\r
228 \r
229 \r
230 @app.route("/testcase/save", methods=["POST"])\r
231 def saveTCContent():\r
232     try:\r
233         suiteName = request.values.get("suiteName")\r
234         caseName = request.values.get("caseName")\r
235         stepList = json.loads(request.values.get("stepList"))\r
236         subflowList = json.loads(request.values.get("subflowList"))\r
237         mainOrdersList = json.loads(request.values.get("mainOrdersList"))\r
238         jsonObj = {"stepList": stepList, "subflowList": subflowList,\r
239                    "mainOrdersList": mainOrdersList}\r
240         parseData = test_parser.parseWebTestcase(jsonObj)\r
241 \r
242         casePath = os.path.join(suiteName, caseName)\r
243         casePath = os.path.join(TESTSUITE_DIR, casePath)\r
244         if os.path.exists(casePath):\r
245             with open(casePath, "w") as f:\r
246                 pyaml.dump(parseData, f, safe=True)\r
247         else:\r
248             return jsonify({"code": 300, "error": "no such file!"})\r
249     except BaseException, e:\r
250         return returnServerError(e)\r
251 \r
252     return jsonify({"code": 200, "result": "save success"})\r
253 \r
254 \r
255 ###############\r
256 # 3.1 API FOR SERVICE\r
257 ############################################################\r
258 @app.route("/service/list")\r
259 def getAllServices():\r
260     res = []\r
261     try:\r
262         for fileName in os.listdir(SERVICE_DIR):\r
263             serviceName = os.path.splitext(fileName)[0]\r
264             res.append(serviceName)\r
265     except BaseException, e:\r
266         return returnServerError(e)\r
267 \r
268     return jsonify({"code": 200, "result": res})\r
269 \r
270 \r
271 @app.route("/service/content")\r
272 def getServiceContent():\r
273     res = {}\r
274     try:\r
275         serviceName = request.values.get("serviceName")\r
276         for fileName in os.listdir(SERVICE_DIR):\r
277             if serviceName == os.path.splitext(fileName)[0]:\r
278                 res["actions"] = []\r
279                 filePath = os.path.join(SERVICE_DIR, fileName)\r
280                 with open(filePath, "r") as f:\r
281                     content = yaml.load(f)\r
282                     apisArr = content[serviceName]['apis']\r
283                     for i in range(len(apisArr)):\r
284                         apisArr[i].pop("method")\r
285                         apisArr[i].pop("baseuri")\r
286                     res["actions"] = apisArr\r
287     except BaseException, e:\r
288         return returnServerError(e)\r
289 \r
290     if res == {}:\r
291         return jsonify({"code": 300, "error": "no such service!"})\r
292 \r
293     return jsonify({"code": 200, "result": res})\r
294 \r
295 \r
296 def paramTransform(paramDict):\r
297     res = []\r
298     for (key, value) in paramDict.items():\r
299         paramJson = {}\r
300         paramJson["name"] = key\r
301         paramJson["description"] = value["help"]\r
302         if "params" in value:\r
303             paramJson["params"] = paramTransform(value["params"])\r
304         res.append(paramJson)\r
305     return res\r
306 \r
307 \r
308 @app.route("/service/action_response")\r
309 def actionResponse():\r
310     res = {}\r
311     try:\r
312         serviceName = request.values.get("serviceName")\r
313         actionName = request.values.get("actionName")\r
314         for fileName in os.listdir(SERVICE_DIR):\r
315             if serviceName == os.path.splitext(fileName)[0]:\r
316                 res["responseParams"] = []\r
317                 filePath = os.path.join(SERVICE_DIR, fileName)\r
318                 with open(filePath, "r") as f:\r
319                     content = yaml.load(f)\r
320                     apisArr = content[serviceName]['apis']\r
321                 for i in range(len(apisArr)):\r
322                     if actionName == apisArr[i]['name'] and (\r
323                        "response" in apisArr[i]):\r
324                         res["responseParams"] = apisArr[i]["response"]\r
325     except BaseException, e:\r
326         return returnServerError(e)\r
327     if res == {}:\r
328         return jsonify({"code": 300, "error": "no such service!"})\r
329     return jsonify({"code": 200, "result": res})\r
330 \r
331 \r
332 ###############\r
333 # 3.2 API FOR ENVIRONMENT SERVICE AND CONTEXT\r
334 ###########################################################################\r
335 @app.route('/env/getAllServices')\r
336 def getAllService():\r
337     res = []\r
338     id = 1\r
339     try:\r
340         for fileName in os.listdir(SERVICE_DIR):\r
341             item = {}\r
342             item['id'] = id\r
343             item['name'] = os.path.splitext(fileName)[0]\r
344             filePath = os.path.join(SERVICE_DIR, fileName)\r
345             filemt = time.localtime(os.stat(filePath).st_mtime)\r
346             item['time'] = time.strftime("%Y-%m-%d", filemt)\r
347             res.append(item)\r
348             id = id + 1\r
349     except BaseException, e:\r
350         return returnServerError(e)\r
351     return jsonify({"code": 200, "result": res})\r
352 \r
353 \r
354 @app.route('/env/getService')\r
355 def getService():\r
356     try:\r
357         serviceName = request.values.get('serviceName')\r
358         serviceFile = serviceName + '.yaml'\r
359         servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
360         if os.path.exists(servicePath):\r
361             with open(servicePath, "r") as f:\r
362                 serviceDict = yaml.load(f)\r
363                 serviceDict = serviceDict[serviceName]\r
364             return jsonify({"code": 200, "result": serviceDict})\r
365         else:\r
366             return jsonify({"code": 300, "error": "no such service!"})\r
367     except BaseException, e:\r
368         return returnServerError(e)\r
369 \r
370 \r
371 @app.route('/env/createService', methods=['POST'])\r
372 def createService():\r
373     try:\r
374         name = str(request.values.get('name'))\r
375         ip = str(request.values.get('ip'))\r
376         port = int(request.values.get('port'))\r
377         apis = json.loads(request.values.get('apis'))\r
378         service = {\r
379             name: {\r
380                 'ip': ip,\r
381                 'port': port,\r
382                 'apis': apis\r
383             }\r
384         }\r
385         serviceJson = json.dumps(service, indent=True)\r
386         print serviceJson\r
387         app.logger.debug(service)\r
388 \r
389         serviceFile = name + '.yaml'\r
390         servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
391         with open(servicePath, 'w') as f:\r
392             pyaml.dump(service, f, safe=True)\r
393     except BaseException, e:\r
394         return returnServerError(e)\r
395     return jsonify({"code": 200, "result": "create success!"})\r
396 \r
397 \r
398 @app.route('/env/editService', methods=['POST'])\r
399 def editService():\r
400     try:\r
401         oldName = str(request.values.get('oldName'))\r
402         name = str(request.values.get('newName'))\r
403         ip = str(request.values.get('ip'))\r
404         port = int(request.values.get('port'))\r
405         apis = json.loads(request.values.get('apis'))\r
406         app.logger.debug(apis)\r
407         service = {\r
408             name: {\r
409                 'ip': ip,\r
410                 'port': port,\r
411                 'apis': apis\r
412             }\r
413         }\r
414         serviceJson = json.dumps(service, indent=True)\r
415         print serviceJson\r
416         app.logger.debug(service)\r
417 \r
418         for fileName in os.listdir(SERVICE_DIR):\r
419             serviceName = os.path.splitext(fileName)[0]\r
420             if serviceName == oldName:\r
421                 filePath = os.path.join(SERVICE_DIR, fileName)\r
422                 os.remove(filePath)\r
423 \r
424         serviceFile = name + '.yaml'\r
425         servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
426         with open(servicePath, 'w') as f:\r
427             pyaml.dump(service, f, safe=True)\r
428     except BaseException, e:\r
429         return returnServerError(e)\r
430     return jsonify({"code": 200, "result": "edit success!"})\r
431 \r
432 \r
433 @app.route('/env/deleteService', methods=['POST'])\r
434 def deleteService():\r
435     try:\r
436         name = str(request.values.get('serviceName'))\r
437 \r
438         for fileName in os.listdir(SERVICE_DIR):\r
439             serviceName = os.path.splitext(fileName)[0]\r
440             if serviceName == name:\r
441                 filePath = os.path.join(SERVICE_DIR, fileName)\r
442                 os.remove(filePath)\r
443     except BaseException, e:\r
444         return returnServerError(e)\r
445     return jsonify({"code": 200, "result": "delete success!"})\r
446 \r
447 \r
448 @app.route('/env/getContext')\r
449 def getContext():\r
450     try:\r
451         with open(CONTEXT_FILE_DIR, "r") as f:\r
452             fileContent = f.read()\r
453         res = fileContent\r
454     except BaseException, e:\r
455         return returnServerError(e)\r
456     return jsonify({"code": 200, "result": {"context": res}})\r
457 \r
458 \r
459 @app.route('/env/editContext', methods=['POST'])\r
460 def editContext():\r
461     try:\r
462         context = request.values.get("context")\r
463         test = yaml.load(context)\r
464         print test\r
465         with open(CONTEXT_FILE_DIR, "w") as f:\r
466             f.write(context)\r
467     except yaml.constructor.ConstructorError, e:\r
468         app.logger.error(traceback.format_exc())\r
469         return jsonify({"code": 500, "error":\r
470                         "context content error: not a .yaml file!"})\r
471     except BaseException, e:\r
472         return returnServerError(e)\r
473 \r
474     return jsonify({"code": 200, "result": "edit context success!"})\r
475 ###########################################################################\r
476 \r
477 \r
478 def returnServerError(e, msg="Server Error"):\r
479     print e\r
480     app.logger.error(traceback.format_exc())\r
481     return jsonify({"code": 500, "error": msg})\r
482 \r
483 \r
484 if __name__ == "__main__":\r
485     app.run(host='0.0.0.0', port=5310)\r