oeqa/core/runner: write testresult to json files

As part of the solution to replace Testopia to store testresult,
OEQA need to output testresult into single json file, where json
testresult file will be stored in git repository by the future
test-case-management tools.

The json testresult file will store more than one set of results,
where each set of results was uniquely identified by the result_id.
The result_id would be like "runtime-qemux86-core-image-sato", where
it was a runtime test with target machine equal to qemux86 and running
on core-image-sato image. The json testresult file will only store
the latest test content for a given result_id. The json testresult
file contains the configuration (eg. COMMIT, BRANCH, MACHINE, IMAGE),
result (eg. PASSED, FAILED, ERROR), test log, and result_id.

Based on the destination json testresult file directory provided,
it could have multiple instances of bitbake trying to write json
testresult to a single testresult file, using locking a lockfile
alongside the results file directory to prevent races.

Also the library class inside this patch will be reused by the future
test-case-management tools to write json testresult for manual test
case executed.

(From OE-Core rev: 00e03b5004f1eb6d59295544b3a8620504278f51)

Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Yeoh Ee Peng 2018-10-23 13:57:19 +08:00 committed by Richard Purdie
parent 3ca7d58e6f
commit 4ef72d556f

View File

@ -6,6 +6,7 @@ import time
import unittest import unittest
import logging import logging
import re import re
import json
from unittest import TextTestResult as _TestResult from unittest import TextTestResult as _TestResult
from unittest import TextTestRunner as _TestRunner from unittest import TextTestRunner as _TestRunner
@ -119,8 +120,9 @@ class OETestResult(_TestResult):
self.successes.append((test, None)) self.successes.append((test, None))
super(OETestResult, self).addSuccess(test) super(OETestResult, self).addSuccess(test)
def logDetails(self): def logDetails(self, json_file_dir=None, configuration=None, result_id=None):
self.tc.logger.info("RESULTS:") self.tc.logger.info("RESULTS:")
result = {}
for case_name in self.tc._registry['cases']: for case_name in self.tc._registry['cases']:
case = self.tc._registry['cases'][case_name] case = self.tc._registry['cases'][case_name]
@ -137,6 +139,11 @@ class OETestResult(_TestResult):
t = " (" + "{0:.2f}".format(self.endtime[case.id()] - self.starttime[case.id()]) + "s)" t = " (" + "{0:.2f}".format(self.endtime[case.id()] - self.starttime[case.id()]) + "s)"
self.tc.logger.info("RESULTS - %s - Testcase %s: %s%s" % (case.id(), oeid, status, t)) self.tc.logger.info("RESULTS - %s - Testcase %s: %s%s" % (case.id(), oeid, status, t))
result[case.id()] = {'status': status, 'log': log}
if json_file_dir:
tresultjsonhelper = OETestResultJSONHelper()
tresultjsonhelper.dump_testresult_file(json_file_dir, configuration, result_id, result)
class OEListTestsResult(object): class OEListTestsResult(object):
def wasSuccessful(self): def wasSuccessful(self):
@ -249,3 +256,29 @@ class OETestRunner(_TestRunner):
self._list_tests_module(suite) self._list_tests_module(suite)
return OEListTestsResult() return OEListTestsResult()
class OETestResultJSONHelper(object):
testresult_filename = 'testresults.json'
def _get_existing_testresults_if_available(self, write_dir):
testresults = {}
file = os.path.join(write_dir, self.testresult_filename)
if os.path.exists(file):
with open(file, "r") as f:
testresults = json.load(f)
return testresults
def _write_file(self, write_dir, file_name, file_content):
file_path = os.path.join(write_dir, file_name)
with open(file_path, 'w') as the_file:
the_file.write(file_content)
def dump_testresult_file(self, write_dir, configuration, result_id, test_result):
bb.utils.mkdirhier(write_dir)
lf = bb.utils.lockfile(os.path.join(write_dir, 'jsontestresult.lock'))
test_results = self._get_existing_testresults_if_available(write_dir)
test_results[result_id] = {'configuration': configuration, 'result': test_result}
json_testresults = json.dumps(test_results, sort_keys=True, indent=4)
self._write_file(write_dir, self.testresult_filename, json_testresults)
bb.utils.unlockfile(lf)