Generate sponge xml

Change-Id: I2718e66d427fd35260f8cd505e264db3186da3c6
diff --git a/kokoro/ubuntu/continuous.cfg b/kokoro/ubuntu/continuous.cfg
index 0e0e286..7282715 100644
--- a/kokoro/ubuntu/continuous.cfg
+++ b/kokoro/ubuntu/continuous.cfg
@@ -5,7 +5,10 @@
 
 action {
   define_artifacts {
-    regex: "git/hafnium/out/**/test_log/**/*.log"
+    regex: "git/hafnium/out/**/test_log/**/*sponge_log.log"
+    regex: "git/hafnium/out/**/test_log/**/*sponge_log.xml"
     strip_prefix: "git/hafnium"
   }
 }
+
+timeout_mins: 10
diff --git a/kokoro/ubuntu/presubmit.cfg b/kokoro/ubuntu/presubmit.cfg
index aa7fd6b..71e3719 100644
--- a/kokoro/ubuntu/presubmit.cfg
+++ b/kokoro/ubuntu/presubmit.cfg
@@ -5,7 +5,10 @@
 
 action {
   define_artifacts {
-    regex: "git/hafnium/out/**/test_log/**/*.log"
+    regex: "git/hafnium/out/**/test_log/**/*sponge_log.log"
+    regex: "git/hafnium/out/**/test_log/**/*sponge_log.xml"
     strip_prefix: "git/hafnium"
   }
 }
+
+timeout_mins: 10
diff --git a/test/vm/hftest.py b/test/vm/hftest.py
index 6cf8e97..e21cf35 100755
--- a/test/vm/hftest.py
+++ b/test/vm/hftest.py
@@ -6,6 +6,8 @@
 
 from __future__ import print_function
 
+import xml.etree.ElementTree as ET
+
 import argparse
 import json
 import os
@@ -64,35 +66,61 @@
     log = os.path.join(args.out, "test_log", args.initrd)
     ensure_dir(log)
     print("Logs saved under", log)
-    # Query the tests in the image.
-    out = qemu(hafnium, initrd, "json", os.path.join(log, "json.log"))
-    hftest_json = "\n".join(hftest_lines(out))
-    tests = json.loads(hftest_json)
-    # Run the selected tests.
-    tests_run = 0
-    failures = 0
-    suite_re = re.compile(args.suite or ".*")
-    test_re = re.compile(args.test or ".*")
-    for suite in tests['suites']:
-        if not suite_re.match(suite['name']):
-            continue
-        tests_run_from_suite = 0
-        for test in suite['tests']:
-            if not test_re.match(test):
+    log_file = os.path.join(log, "sponge_log.log")
+    with open(log_file, "w") as sponge_log:
+        # Query the tests in the image.
+        out = qemu(hafnium, initrd, "json", os.path.join(log, "json.log"))
+        sponge_log.write(out)
+        sponge_log.write("\r\n\r\n")
+        hftest_json = "\n".join(hftest_lines(out))
+        tests = json.loads(hftest_json)
+        # Run the selected tests.
+        tests_run = 0
+        failures = 0
+        suite_re = re.compile(args.suite or ".*")
+        test_re = re.compile(args.test or ".*")
+        sponge = ET.Element("testsuites")
+        sponge.set("name", args.initrd)
+        for suite in tests["suites"]:
+            if not suite_re.match(suite["name"]):
                 continue
-            tests_run_from_suite += 1
-            if tests_run_from_suite == 1:
-                print("    SUITE", suite['name'])
-            print("      RUN", test)
-            test_log = os.path.join(log, suite['name'] + "." + test + ".log")
-            out = qemu(hafnium, initrd, "run {} {}".format(suite['name'], test), test_log)
-            hftest_out = hftest_lines(out)
-            if hftest_out[-1] == "PASS":
-                print("        PASS")
-            else:
-                failures += 1
-                print("[x]     FAIL --", test_log)
-        tests_run += tests_run_from_suite
+            tests_run_from_suite = 0
+            failures_from_suite = 0
+            sponge_suite = ET.SubElement(sponge, "testsuite")
+            sponge_suite.set("name", suite["name"])
+            for test in suite["tests"]:
+                if not test_re.match(test):
+                    continue
+                sponge_test = ET.SubElement(sponge_suite, "testcase")
+                sponge_test.set("name", test)
+                sponge_test.set("status", "run")
+                tests_run_from_suite += 1
+                if tests_run_from_suite == 1:
+                    print("    SUITE", suite["name"])
+                print("      RUN", test)
+                test_log = os.path.join(log,
+                                        suite["name"] + "." + test + ".log")
+                out = qemu(hafnium, initrd, "run {} {}".format(
+                    suite["name"], test), test_log)
+                sponge_log.write(out)
+                sponge_log.write("\r\n\r\n")
+                hftest_out = hftest_lines(out)
+                if hftest_out[-1] == "PASS":
+                    print("        PASS")
+                else:
+                    failures_from_suite += 1
+                    sponge_failure = ET.SubElement(sponge_test, "failure")
+                    # TODO: set a meaningful message and put log in CDATA
+                    sponge_failure.set("message", "Test failed")
+                    print("[x]     FAIL --", test_log)
+            tests_run += tests_run_from_suite
+            failures += failures_from_suite
+            sponge_suite.set("tests", str(tests_run_from_suite))
+            sponge_suite.set("failures", str(failures_from_suite))
+    sponge.set("tests", str(tests_run))
+    sponge.set("failures", str(failures))
+    with open(os.path.join(log, "sponge_log.xml"), "w") as f:
+        ET.ElementTree(sponge).write(f, encoding='utf-8', xml_declaration=True)
     # If none were run, this is probably a mistake.
     if tests_run == 0:
         print("Error: no tests match")