parser script and step class in backend code of testing-scheduler
[bottlenecks.git] / testing-scheduler / server / src / test_parser.py
diff --git a/testing-scheduler/server/src/test_parser.py b/testing-scheduler/server/src/test_parser.py
new file mode 100644 (file)
index 0000000..7b47151
--- /dev/null
@@ -0,0 +1,315 @@
+#!/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
+\r
+import click\r
+import os\r
+import yaml\r
+import json\r
+import collections\r
+from src.step.step_manager import TestStepManager\r
+from src.conductor_processor.workflow import WorkflowFile\r
+from conductorclient.run_new_workflow import WorkflowMgr\r
+\r
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))\r
+CONDUCTOR_SERVER_ADDR = "http://conductor_conductor-server_1:8080"\r
+STORE_TASK_PATH = "/tmp/generate_task.json"\r
+STORE_WF_PATH = "/tmp/generate_workflow.json"\r
+\r
+\r
+@click.command()\r
+@click.option("--filepath", help="file path of test case")\r
+def cmdParse(filepath):\r
+    parse(filepath)\r
+\r
+\r
+def parse(filepath):\r
+    filePrefix, fileName = os.path.split(filepath)\r
+    print '------------ start to parse the test case:' + \\r
+        '%s ----------------' % fileName\r
+    with open(filepath) as f:\r
+        yaml_file = yaml.load(f)\r
+        parseTestcase(yaml_file['schema'], fileName)\r
+\r
+    workflowId = runWorkFlow()\r
+    print '------------------- parse executes end -------------------------'\r
+\r
+    return workflowId\r
+\r
+\r
+def parseTestcase(schema, tcName='testcase0'):\r
+    if schema is None:\r
+        return parseLog(False, reason='schema not found.')\r
+    steps = schema['steps']\r
+    if steps is None:\r
+        return parseLog(False, reason='steps is invalid.')\r
+    flows = schema['flows']\r
+    if flows is None:\r
+        return parseLog(False, reasion='flows is invalid.')\r
+    # steps is a list, step is dict. no json here.\r
+    # steps = sorted(steps, sortById)\r
+\r
+    # load context\r
+    contextDict = {}\r
+    contextDir = os.path.join(BASE_DIR, "env", "context", "context.yaml")\r
+    with open(contextDir, "r") as f:\r
+        contextDict = yaml.load(f)\r
+    #\r
+    testStepMgr = TestStepManager(contextDict)\r
+\r
+    stepObjArr = []\r
+    for step in steps:\r
+        if 'args' not in step:\r
+            step['args'] = {}\r
+        # type and action can be extended, default couple is 'test' & 'start'.\r
+        if 'type' not in step:\r
+            step['type'] = 'test'\r
+            step['action'] = 'start'\r
+\r
+        stepObj = testStepMgr.getStepObj(\r
+            step['type'], step['id'], step['name'], step['service'],\r
+            step['action'], step['args'])\r
+        stepObjArr.append(stepObj)\r
+\r
+    # generate workflow by 'flow' and 'step'\r
+    tcName = os.path.splitext(tcName)[0]\r
+    wfFileObj = WorkflowFile(tcName)\r
+    workflowDict, taskMetaList = wfFileObj.generateMetaData(flows, stepObjArr)\r
+\r
+    with open(STORE_TASK_PATH, 'w') as f:\r
+        f.write(json.dumps({'task_group': taskMetaList}, indent=True))\r
+    with open(STORE_WF_PATH, 'w') as f:\r
+        f.write(json.dumps(workflowDict, indent=True))\r
+\r
+\r
+def parseWebTestcase(webTestcase):\r
+    print 'parseWebTestcase----------------------------'\r
+\r
+    stepList = webTestcase['stepList']\r
+    mainOrdersList = webTestcase['mainOrdersList']\r
+    subflowList = webTestcase['subflowList']\r
+\r
+    parseData = collections.OrderedDict()\r
+    parseData['schema'] = collections.OrderedDict()\r
+    parseData['schema']['steps'] = []\r
+    parseData['schema']['flows'] = []\r
+\r
+    parseStepList = parseData['schema']['steps']\r
+    parseFlowList = parseData['schema']['flows']\r
+    stepIndexDict = {}\r
+    # parse stepList\r
+    for index in range(len(stepList)):\r
+        stepItem = stepList[index]\r
+        parseStep = collections.OrderedDict()\r
+\r
+        parseStep['id'] = index + 1\r
+        parseStep['name'] = stepItem['name']\r
+        parseStep['service'] = collections.OrderedDict()\r
+        parseStep['service']['name'] = stepItem['service']\r
+        parseStep['service']['interface'] = stepItem['action']\r
+        parseStep['action'] = 'start'\r
+        parseStep['args'] = {}\r
+        for paramItem in stepItem['params']:\r
+            parseStep['args'][paramItem['key']] = transParamString(\r
+                paramItem['value'])\r
+\r
+        parseStepList.append(parseStep)\r
+        stepIndexDict[parseStep['name']] = parseStep['id']\r
+    # parse flows\r
+    # parse mainflow\r
+    print stepIndexDict\r
+    typeDict = {1: 'normal', 2: 'switch', 3: 'parallel'}\r
+    mainFlow = collections.OrderedDict()\r
+    mainFlow['name'] = 'main'\r
+    mainFlow['orders'] = []\r
+    mainFlow['orders'] = parseOrderList(\r
+        mainOrdersList, stepIndexDict, typeDict)\r
+    parseFlowList.append(mainFlow)\r
+\r
+    # parse subflow\r
+    for subflowItem in subflowList:\r
+        replaceSubflow = collections.OrderedDict()\r
+        replaceSubflow['name'] = subflowItem['name']\r
+        replaceSubflow['orders'] = parseOrderList(\r
+            subflowItem['orderList'], stepIndexDict, typeDict)\r
+        parseFlowList.append(replaceSubflow)\r
+\r
+    print 'END parseWebTestcase----------------------------'\r
+    return parseData\r
+\r
+\r
+# parse orderlist from web edition to server edition\r
+def parseOrderList(orderList, stepIndexDict, typeDict):\r
+    replaceList = []\r
+    for orderItem in orderList:\r
+        replaceOrder = collections.OrderedDict()\r
+        orderType = typeDict[orderItem['type']]\r
+        replaceOrder['type'] = orderType\r
+        if orderType == 'normal':\r
+            stepId = stepIndexDict[orderItem['step']]\r
+            replaceOrder['step'] = stepId\r
+        elif orderType == 'switch':\r
+            replaceOrder['value'] = orderItem['value']\r
+            replaceOrder['cases'] = collections.OrderedDict()\r
+            for caseItem in orderItem['cases']:\r
+                caseValue = caseItem['value']\r
+                caseOrderType = caseItem['orderType']\r
+                caseOrderValue = caseItem['orderValue']\r
+                if caseOrderType == "step":\r
+                    orderInCase = collections.OrderedDict()\r
+                    orderInCase['type'] = 'normal'\r
+                    orderInCase['step'] = stepIndexDict[caseOrderValue]\r
+                    replaceOrder['cases'][caseValue] = [orderInCase]\r
+                else:\r
+                    replaceOrder['cases'][caseValue] = caseOrderValue\r
+        else:\r
+            replaceOrder['parallel'] = collections.OrderedDict()\r
+            pIndex = 1\r
+            for branchItem in orderItem['branches']:\r
+                pKey = 'p' + str(pIndex)\r
+                branchOrderType = branchItem['orderType']\r
+                branchOrderValue = branchItem['orderValue']\r
+                if branchOrderType == "step":\r
+                    replaceBranchItem = collections.OrderedDict()\r
+                    replaceBranchItem['type'] = 'normal'\r
+                    replaceBranchItem['step'] = stepIndexDict[branchOrderValue]\r
+                    replaceOrder['parallel'][pKey] = [replaceBranchItem]\r
+                else:\r
+                    replaceOrder['parallel'][pKey] = branchOrderValue\r
+                pIndex += 1\r
+        replaceList.append(replaceOrder)\r
+    return replaceList\r
+\r
+\r
+def transParamString(val):\r
+    if type(val) != str:\r
+        return val\r
+    if '.' not in val:\r
+        if val.isdigit():\r
+            return int(val)\r
+    try:\r
+        f = float(val)\r
+        return f\r
+    except ValueError:\r
+        return val\r
+\r
+\r
+def getWebTestcase(originTcDict):\r
+    print "getWebTestcase----------------------------------"\r
+    webTcDict = {\r
+        "stepList": [],\r
+        "mainOrdersList": [],\r
+        "subflowList": []\r
+    }\r
+    stepList = webTcDict['stepList']\r
+    subflowList = webTcDict['subflowList']\r
+    if originTcDict is None:\r
+        return webTcDict\r
+    originContent = originTcDict['schema']\r
+    originSteps = originContent['steps']\r
+    stepIndexDict = {}\r
+    # transform steps to stepList\r
+    for stepItem in originSteps:\r
+        replaceStep = {}\r
+        replaceStep['name'] = stepItem['name']\r
+        replaceStep['service'] = stepItem['service']['name']\r
+        replaceStep['action'] = stepItem['service']['interface']\r
+        replaceStep['params'] = []\r
+        if 'args' in stepItem:\r
+            for (key, value) in stepItem['args'].items():\r
+                replaceParam = {}\r
+                replaceParam['key'] = key\r
+                replaceParam['value'] = value\r
+                replaceStep['params'].append(replaceParam)\r
+        stepList.append(replaceStep)\r
+        stepIndexDict[stepItem['id']] = stepItem['name']\r
+\r
+    # transform main flow\r
+    originFlows = originContent['flows']\r
+    originMainflow = {}\r
+    for flowIndex in range(len(originFlows)):\r
+        flowItem = originFlows[flowIndex]\r
+        if flowItem['name'] == 'main':\r
+            originMainflow = flowItem\r
+            originFlows.pop(flowIndex)\r
+            break\r
+    typeDict = {'normal': 1, 'switch': 2, 'parallel': 3}\r
+    webTcDict['mainOrdersList'] = getOrderList(\r
+        originMainflow['orders'], stepIndexDict, typeDict)\r
+\r
+    # transform subflows\r
+    for originSubflow in originFlows:\r
+        replaceSubflow = {}\r
+        replaceSubflow['name'] = originSubflow['name']\r
+        replaceSubflow['orderList'] = getOrderList(\r
+            originSubflow['orders'], stepIndexDict, typeDict)\r
+        subflowList.append(replaceSubflow)\r
+\r
+    # return web edition of testcase\r
+    print "END getWebTestcase----------------------------------"\r
+    return webTcDict\r
+\r
+\r
+def getOrderList(originOrderList, stepIndexDict, typeDict):\r
+    replaceOrderList = []\r
+    for orderItem in originOrderList:\r
+        replaceOrderItem = {}\r
+        orderType = orderItem['type']\r
+        replaceOrderItem['type'] = typeDict[orderType]\r
+        if orderType == 'normal':\r
+            stepName = stepIndexDict[orderItem['step']]\r
+            replaceOrderItem['step'] = stepName\r
+        elif orderType == 'switch':\r
+            replaceOrderItem['value'] = orderItem['value']\r
+            replaceOrderItem['cases'] = []\r
+            for (caseValue, ordersInCase) in orderItem['cases'].items():\r
+                replaceCase = {}\r
+                replaceCase['value'] = caseValue\r
+                if type(ordersInCase) == list:\r
+                    replaceCase['orderType'] = 'step'\r
+                    caseStepName = stepIndexDict[ordersInCase[0]['step']]\r
+                    replaceCase['orderValue'] = caseStepName\r
+                else:\r
+                    replaceCase['orderType'] = 'flow'\r
+                    replaceCase['orderValue'] = ordersInCase\r
+                replaceOrderItem['cases'].append(replaceCase)\r
+        else:\r
+            replaceOrderItem['branches'] = []\r
+            for paraIndex in orderItem['parallel']:\r
+                paraItem = orderItem['parallel'][paraIndex]\r
+                replaceBranch = {}\r
+                if type(paraItem) == list:\r
+                    replaceBranch['orderType'] = 'step'\r
+                    branchStepName = stepIndexDict[paraItem[0]['step']]\r
+                    replaceBranch['orderValue'] = branchStepName\r
+                else:\r
+                    replaceBranch['orderType'] = 'flow'\r
+                    replaceBranch['orderValue'] = paraItem\r
+                replaceOrderItem['branches'].append(replaceBranch)\r
+        replaceOrderList.append(replaceOrderItem)\r
+\r
+    return replaceOrderList\r
+\r
+\r
+def runWorkFlow():\r
+    wfMgr = WorkflowMgr(CONDUCTOR_SERVER_ADDR)\r
+    wfMgr.setTaskDefFromFile(STORE_TASK_PATH)\r
+    wfMgr.setWorkflowFromFile(STORE_WF_PATH)\r
+    inputParam = {'input': 'fake'}\r
+    workflowId = wfMgr.startWorkflow(inputParam)\r
+    return workflowId\r
+\r
+\r
+def parseLog(flag, **msg):\r
+    return {'result': flag, 'message': msg}\r
+\r
+\r
+if __name__ == "__main__":\r
+    cmdParse()\r