Publish test results to OBS
authorIgor Stoppa <igor.stoppa@intel.com>
Mon, 16 Jun 2014 10:52:28 +0000 (13:52 +0300)
committerLin Yang <lin.a.yang@intel.com>
Mon, 7 Jul 2014 09:35:36 +0000 (17:35 +0800)
Fix parameters passed down from imager job,
through tester and add job for publishing results to OBS.

Change-Id: I96c2d6f1226c3259e1ea1dcbf696e8b20f0f2358

job_imager.py
job_publish_test_results.py [new file with mode: 0755]
job_test_build.py
packaging/jenkins-scripts.spec

index c6aaa8e..9885e0f 100755 (executable)
@@ -145,18 +145,19 @@ def main():
 
     xml_string = get_xml(os.path.join(outdir, build_id), name)
 
-    data = {"image_xml": xml_string,
-            "name": fields['name'],
-            "project": fields.get('project', ''),
-            "status": status,
-            "url": os.path.join(fields.get('url_pub_base', ''),
-                                fields['repo_path'],
-                                fields['images_path'])
-            }
+    url = os.path.join(fields.get('url_pub_base', ''),
+                       fields['repo_path'], fields['images_path'])
 
     # If the project is prerelease project, trigger the post-image-creation
     if is_prerelease_project(fields.get('project', '')):
         # Trigger info for post image creation job
+        data = {"image_xml": xml_string,
+                "name": fields['name'],
+                "project": fields.get('project', ''),
+                "status": status,
+                "url": url
+                }
+
         trigger_next("POST-IMAGE-CREATION", data)
 
     if status == 'success':
@@ -172,8 +173,12 @@ def main():
 
         testable_images = re.compile(os.getenv("TESTABLE_IMAGES"))
         if testable_images.match(fields["name"]):
-            print "The target HW is supported and automated testing will follow."
-            trigger_next("IMAGE-TESTING", data)
+            print ("The target HW is supported "
+                   "and automated testing will follow.")
+            fields["image_xml"] = xml_string
+            fields["status"] = status
+            fields["url"] = url
+            trigger_next("IMAGE-TESTING", fields)
         else:
             print "However the target HW is NOT supported for automated testing."
         return 0
diff --git a/job_publish_test_results.py b/job_publish_test_results.py
new file mode 100755 (executable)
index 0000000..0782a81
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""Publish the test results to OBS"""
+
+import os
+import sys
+from common.buildservice import BuildService
+from common.buildtrigger import trigger_info
+
+
+
+def main():
+    """The main body"""
+
+    try:
+        api_url = os.getenv("OBS_API_URL")
+        api_username = os.getenv("OBS_API_USERNAME")
+        api_password = os.getenv("OBS_API_PASSWD")
+        fields = trigger_info(os.getenv("TRIGGER_INFO"))
+
+        project = fields["project"]
+        result = fields["test_result"]
+        name = fields["name"]
+        test_details = fields["test_details"]
+
+
+        build = BuildService(api_url, api_username, api_password)
+        info = build.get_info(str(project))
+        for i in range(len(info["images"])):
+            if info["images"][i]["name"] == name:
+                info["images"][i]["test_status"] = result
+                info["images"][i]["test_details"] = test_details
+                break
+        build.update_info(info, project)
+    except (TypeError) as error:
+        sys.exit("Error accessing OBS: " + str(error))
+
+
+if __name__ == "__main__":
+    sys.exit(main())
index dd7b41a..05f1d56 100755 (executable)
@@ -7,7 +7,8 @@ import sys
 import glob
 import tarfile
 import subprocess
-from common.buildtrigger import trigger_info
+from lxml import etree
+from common.buildtrigger import trigger_info, trigger_next
 
 
 def dump_result(outcome="TESTER_FAILURE", image="Not found"):
@@ -53,7 +54,6 @@ def test_image(image):
         print output
         result = "PASS"
         print "All the tests succeeded."
-    dump_result(result, image)
     return result
 
 def pack_results(results_folder):
@@ -70,20 +70,52 @@ def pack_results(results_folder):
     else:
         print "done."
 
+def xml_tree_to_dict(tree):
+    """Converts junit xml file to a dictionary"""
+    #pylint: disable=W0141
+    dic = {tree.tag : map(xml_tree_to_dict, tree.iterchildren())}
+    #pylint: enable=W0141
+    dic.update(('@' + k, v) for k, v in tree.attrib.iteritems())
+    dic['text'] = tree.text
+    return dic
+
+
+def get_test_dict(xml_file):
+    """Gets simplified list of test cases and their status"""
+    full_results = xml_tree_to_dict(etree.parse(xml_file).getroot())
+    dic = {}
+    for test in full_results["testsuite"]:
+        dic[test["@name"]] = 1 if test["testcase"] == [] else 0
+    return dic
+
+
 def main():
     """The main body"""
     # Note: the script, by design, will not return errors
     # Rather, it will inject the error status in the environment
 
-    content = trigger_info(os.getenv("TRIGGER_INFO"))
-    url = content.get("url", "")
+    fields = trigger_info(os.getenv("TRIGGER_INFO"))
+    url = fields["url"]
     image = fetch_image(url)
 
     if not image:
         return
 
-    dump_result(test_image(image), image)
-    pack_results(glob.glob("tztestrobot-results.*")[0])
+    result = test_image(image)
+    fields["test_result"] = result
+    dump_result(result, image)
+
+    results_folder = glob.glob("tztestrobot-results.*")
+
+    if results_folder != []:
+        results_folder = results_folder[0]
+        pack_results(results_folder)
+        fields["test_details"] = \
+            get_test_dict(results_folder + "/results.xml")
+    else:
+        fields["test_details"] = {}
+
+    trigger_next("RESULTS-PUBLISHING", fields)
 
 if __name__ == "__main__":
     sys.exit(main())
index 07133a7..64e474a 100644 (file)
@@ -38,6 +38,7 @@ Requires:   python-redis
 Requires:   python-requests >= 2.0.1
 Requires:   python-snapdiff
 Requires:   python-yaml
+Requires:   python-lxml
 Requires:   gbs-api
 
 %description common
@@ -92,6 +93,7 @@ fi
 %{destdir}/job_local_cache_cleanups.py
 %{destdir}/job_policycheck.py
 %{destdir}/job_pre_release_obs.py
+%{destdir}/job_publish_test_results.py
 %{destdir}/job_request.py
 %{destdir}/job_test_build.py
 %{destdir}/requests