aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpmikus <pmikus@cisco.com>2016-06-06 11:09:24 +0100
committerMiroslav Miklus <mmiklus@cisco.com>2016-06-18 10:02:26 +0000
commitfc5f239ab548898d82c55b0ceaae3dde3be98318 (patch)
treea7adf714c2b942eb40b426ce53faa16383742cf1
parenta4eb9283c92fcd80aaf7cf5866d4fbd20c957b65 (diff)
Process output of robot to XML file for Plot plugin
- JIRA: CSIT-135 - Process output of robot output.xml to XML file for Plot plugin Change-Id: I5e077d81f4c93f66eb208ecc2a38a9f6ca2fe307 Signed-off-by: pmikus <pmikus@cisco.com>
-rwxr-xr-xbootstrap-verify-perf.sh6
-rwxr-xr-xresources/tools/robot_output_parser.py146
2 files changed, 57 insertions, 95 deletions
diff --git a/bootstrap-verify-perf.sh b/bootstrap-verify-perf.sh
index 925e3a6b98..8bf7f796a2 100755
--- a/bootstrap-verify-perf.sh
+++ b/bootstrap-verify-perf.sh
@@ -28,7 +28,7 @@ INSTALLATION_DIR="/tmp/install_dir"
PYBOT_ARGS="--noncritical MULTI_THREAD"
-ARCHIVE_ARTIFACTS=(log.html output.xml report.html output_perf_data.json)
+ARCHIVE_ARTIFACTS=(log.html output.xml report.html output_perf_data.xml)
# If we run this script from CSIT jobs we want to use stable vpp version
if [[ ${JOB_NAME} == csit-* ]] ;
@@ -167,6 +167,7 @@ case "$TEST_TAG" in
-L TRACE \
-v TOPOLOGY_PATH:${WORKING_TOPOLOGY} \
-s "performance.Long_Xconnect_Dot1q*" \
+ RETURN_STATUS=$(echo $?)
;;
PERFTEST_NDR )
pybot ${PYBOT_ARGS} \
@@ -174,6 +175,7 @@ case "$TEST_TAG" in
-v TOPOLOGY_PATH:${WORKING_TOPOLOGY} \
-s performance -i NDR \
tests/
+ RETURN_STATUS=$(echo $?)
;;
PERFTEST_PDR )
pybot ${PYBOT_ARGS} \
@@ -198,7 +200,7 @@ echo Post-processing test data...
python ${CUR_DIR}/resources/tools/robot_output_parser.py \
-i ${CUR_DIR}/output.xml \
- -o ${CUR_DIR}/output_perf_data.json \
+ -o ${CUR_DIR}/output_perf_data.xml \
-v ${VPP_STABLE_VER}
if [ ! $? -eq 0 ]; then
echo "Parsing ${CUR_DIR}/output.xml failed"
diff --git a/resources/tools/robot_output_parser.py b/resources/tools/robot_output_parser.py
index 28a9f268ef..ad1fbfae2a 100755
--- a/resources/tools/robot_output_parser.py
+++ b/resources/tools/robot_output_parser.py
@@ -14,11 +14,11 @@
# limitations under the License.
"""Script parses the data taken by robot framework (output.xml) and dumps
-intereted values into JSON output file."""
+intereted values into XML output file."""
-import json
-import re
-import sys, getopt
+import argparse
+import sys
+import xml.etree.ElementTree as ET
from robot.api import ExecutionResult, ResultVisitor
@@ -26,9 +26,9 @@ from robot.api import ExecutionResult, ResultVisitor
class ExecutionTestChecker(ResultVisitor):
"""Iterates through test cases."""
- def __init__(self, vDeviceVersion):
- self.vDeviceVersion = vDeviceVersion
- self.out = []
+ def __init__(self, args):
+ self.root = ET.Element('build',
+ attrib={'vdevice': args.vdevice})
def visit_test(self, test):
"""Overloaded function. Called when test is found to process data.
@@ -37,29 +37,11 @@ class ExecutionTestChecker(ResultVisitor):
:type test: ExecutionTestChecker
"""
- test_id = test.longname
- test_status = 'Failed'
- framesize = ''
- throughput = ''
- throughput_units = ''
- workers_per_nic = ''
- workers = ''
-
- if any("PERFTEST" in tag for tag in test.tags):
+ if any("PERFTEST_LONG" in tag for tag in test.tags):
if test.status == 'PASS':
- test_status = 'Passed'
- if any("PERFTEST_LONG" in tag for tag in test.tags):
- throughput = test.message.split(' ')[1]
- throughput_units = test.message.split(' ')[2]
- elif any("PERFTEST_SHORT" in tag for tag in test.tags):
- for keyword in test.keywords:
- for assign in keyword.assign:
- if assign == '${rate}':
- temp = re.findall(r"(\d*\.\d+|\d+)([A-Za-z]*)",
- keyword.args[0])
- throughput = temp[0][0]
- throughput_units = temp[0][1]
-
+ tags = []
+ for tag in test.tags:
+ tags.append(tag)
for keyword in test.keywords:
for assign in keyword.assign:
if assign == '${framesize}':
@@ -68,43 +50,31 @@ class ExecutionTestChecker(ResultVisitor):
workers = keyword.name.split('\'')[1]
workers_per_nic = keyword.name.split('\'')[3]
- self.out.append({'testCase': {
- 'testId': test_id,
- 'testStatus': test_status,
- 'workerThreads': workers,
- 'workerThreadsPerNic': workers_per_nic,
- 'testTags': [tag for tag in test.tags],
- 'l2FrameSize': {'value': framesize,
- 'units': 'Bytes'},
- 'throughput': {'value': throughput,
- 'units': throughput_units},
- 'vDevice': {'version': self.vDeviceVersion}}})
+ test_elem = ET.SubElement(self.root,
+ test.longname.split('.')[3].replace(" ",""))
+ test_elem.attrib['name'] = test.longname.split('.')[3]
+ test_elem.attrib['workerthreads'] = workers
+ test_elem.attrib['workerspernic'] = workers_per_nic
+ test_elem.attrib['framesize'] = framesize
+ test_elem.attrib['tags'] = ', '.join(tags)
+ test_elem.text = test.message.split(' ')[1]
-def parse_tests(xml_file, vDeviceVersion):
+def parse_tests(args):
"""Parser result of robot output file and return.
- :param xml_file: Output.xml from robot run.
- :param vDeviceVersion: vDevice version.
- :type xml_file: file
- :type vDeviceVersion: str
+ :param args: Parsed arguments.
+ :type args: ArgumentParser
- :return: JSON formatted output.
- :rtype: dict
+ :return: XML formatted output.
+ :rtype: ElementTree
"""
- result = ExecutionResult(xml_file)
- checker = ExecutionTestChecker(vDeviceVersion)
+ result = ExecutionResult(args.input)
+ checker = ExecutionTestChecker(args)
result.visit(checker)
- return checker.out
-
-
-def print_help():
- """Print help on stdout."""
-
- print "args: [-h] -i <input_log_file> -o <output_json_file>" + \
- " -v <vpp_version>"
+ return checker.root
def print_error(msg):
@@ -118,44 +88,34 @@ def print_error(msg):
sys.stderr.write(msg+'\n')
-def main(argv):
+def parse_args():
+ """Parse arguments from cmd line.
+
+ :return: Parsed arguments.
+ :rtype ArgumentParser
+ """
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-i", "--input", required=True,
+ type=argparse.FileType('r'),
+ help="Robot XML log file")
+ parser.add_argument("-o", "--output", required=True,
+ type=argparse.FileType('w'),
+ help="XML output file")
+ parser.add_argument("-v", "--vdevice", required=True,
+ help="VPP version")
+
+ return parser.parse_args()
+
+
+def main():
"""Main function."""
- _log_file = None
- _json_file = None
- _vpp = None
-
- try:
- opts, _ = getopt.getopt(argv, "hi:o:v:", ["help"])
- except getopt.GetoptError:
- print_help()
- sys.exit(1)
-
- for opt, arg in opts:
- if opt in ('-h', "--help"):
- print_help()
- sys.exit()
- elif opt == '-i':
- _log_file = arg
- elif opt == '-o':
- _json_file = arg
- elif opt == '-v':
- _vpp = arg
-
- if _log_file is None or _json_file is None or _vpp is None:
- print_help()
- sys.exit(1)
-
- try:
- with open(_log_file, 'r') as input_file:
- with open(_json_file, 'w') as output_file:
- out = parse_tests(input_file, _vpp)
- json.dump(out, fp=output_file, sort_keys=True,
- indent=4, separators=(',', ': '))
- except IOError as ex_error:
- print_error(str(ex_error))
- sys.exit(1)
+ args = parse_args()
+
+ root = parse_tests(args)
+ ET.ElementTree.write(ET.ElementTree(root), args.output)
if __name__ == "__main__":
- main(sys.argv[1:])
+ sys.exit(main())