Push ODL results to DB
authorMorgan Richomme <morgan.richomme@orange.com>
Thu, 21 Jan 2016 16:29:09 +0000 (17:29 +0100)
committerMorgan Richomme <morgan.richomme@orange.com>
Fri, 22 Jan 2016 08:05:15 +0000 (09:05 +0100)
JIRA: FUNCTEST-57

Change-Id: I8e998382aff0cc60e82338c27d234abe6be5c505
Signed-off-by: Morgan Richomme <morgan.richomme@orange.com>
docker/requirements.pip
docker/run_tests.sh
testcases/Controllers/ODL/CI/odlreport2db.py [new file with mode: 0644]

index 40e56b9..2389d60 100644 (file)
@@ -23,3 +23,5 @@ robotframework-requests==0.3.8
 robotframework-sshlibrary==2.1.1
 configObj==5.0.6
 Flask==0.10.1
+xmltodict==0.9.2
+
index 6ae12b9..7cb06ab 100755 (executable)
@@ -86,10 +86,12 @@ function run_test(){
             ODL_PORT=$odl_port ODL_IP=$odl_ip NEUTRON_IP=$neutron_ip USR_NAME=$usr_name PASS=$password \
                 ${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI/start_tests.sh
 
-            # save ODL results
-            odl_logs="${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI/logs"
-            if [ -d ${odl_logs} ]; then
-                cp -Rf  ${odl_logs} ${FUNCTEST_CONF_DIR}/ODL/
+            # push results to the DB in case of CI
+            if [[ -n "$DEPLOY_SCENARIO" && "$DEPLOY_SCENARIO" != "none" ]]; then
+                odl_logs="/home/opnfv/functest/results/odl/logs/2"
+                odl_path="${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI"
+                node_name=$(env | grep NODE_NAME | cut -f2 -d'=')
+                python ${odl_path}/odlreport2db.py -x ${odl_logs}/output.xml -i ${INSTALLER_TYPE} -p ${node_name} -s ${DEPLOY_SCENARIO}
             fi
         ;;
         "tempest")
diff --git a/testcases/Controllers/ODL/CI/odlreport2db.py b/testcases/Controllers/ODL/CI/odlreport2db.py
new file mode 100644 (file)
index 0000000..1538f79
--- /dev/null
@@ -0,0 +1,143 @@
+#!/usr/bin/python
+#
+# Authors:
+# - peter.bandzi@cisco.com
+# - morgan.richomme@orange.com
+#
+# src: Peter Bandzi
+# https://github.com/pbandzi/parse-robot/blob/master/convert_robot_to_json.py
+#
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# 0.1: This script boots the VM1 and allocates IP address from Nova
+# Later, the VM2 boots then execute cloud-init to ping VM1.
+# After successful ping, both the VMs are deleted.
+# 0.2: measure test duration and publish results under json format
+#
+#
+import xmltodict
+import json
+import sys
+import getopt
+import yaml
+
+
+sys.path.append("/home/opnfv/repos/functest/testcases")
+import functest_utils
+
+
+def usage():
+    print """Usage:
+    get-json-from-robot.py --xml=<output.xml> --pod=<pod_name>
+                           --installer=<installer> --database=<Database URL>
+                           --scenaro=SCENARIO
+    -x, --xml   xml file generated by robot test
+    -p, --pod   POD name where the test come from
+    -i, --installer
+    -s, --scenario
+    -h, --help  this message
+    """
+    sys.exit(2)
+
+
+def populate_detail(test):
+    detail = {}
+    detail['test_name'] = test['@name']
+    detail['test_status'] = test['status']
+    detail['test_doc'] = test['doc']
+    return detail
+
+
+def parse_test(tests, details):
+    try:
+        for test in tests:
+            details.append(populate_detail(test))
+    except TypeError:
+        # tests is not iterable
+        details.append(populate_detail(tests))
+    return details
+
+
+def parse_suites(suites):
+    data = {}
+    details = []
+    try:
+        for suite in suites:
+            data['details'] = parse_test(suite['test'], details)
+    except TypeError:
+        # suites is not iterable
+        data['details'] = parse_test(suites['test'], details)
+    return data
+
+
+def main(argv):
+    try:
+        opts, args = getopt.getopt(argv,
+                                   'x:p:i:s:h',
+                                   ['xml=', 'pod=',
+                                    'installer=',
+                                    'scenario=',
+                                    'help'])
+    except getopt.GetoptError:
+        usage()
+
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage()
+        elif opt in ('-x', '--xml'):
+            xml_file = arg
+        elif opt in ('-p', '--pod'):
+            pod = arg
+        elif opt in ('-i', '--installer'):
+            installer = arg
+        elif opt in ('-s', '--scenario'):
+            scenario = arg
+        else:
+            usage()
+
+    with open(xml_file, "r") as myfile:
+        xml_input = myfile.read().replace('\n', '')
+
+    # dictionary populated with data from xml file
+    all_data = xmltodict.parse(xml_input)['robot']
+
+    data = parse_suites(all_data['suite']['suite'])
+    data['description'] = all_data['suite']['@name']
+    data['version'] = all_data['@generator']
+    data['test_project'] = "functest"
+    data['case_name'] = "ODL"
+    data['pod_name'] = pod
+    data['installer'] = installer
+
+    json.dumps(data, indent=4, separators=(',', ': '))
+
+    # Only used from container, we can set up absolute path
+    with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
+        functest_yaml = yaml.safe_load(f)
+        f.close()
+
+    database = functest_yaml.get("results").get("test_db_url")
+
+    try:
+        # example:
+        # python odlreport2db.py -x ~/Pictures/Perso/odl/output3.xml
+        #                        -i fuel
+        #                        -p opnfv-jump-2
+        #                        -s os-odl_l2-ha
+        functest_utils.push_results_to_db(database,
+                                          data['case_name'],
+                                          None,
+                                          data['pod_name'],
+                                          scenario,
+                                          data)
+    except:
+        print("Error pushing results into Database '%s'" % sys.exc_info()[0])
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])