* [PATCH 1/4] oeqa/runner: write testresult to json files
@ 2018-10-02 9:22 Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 2/4] selftest/context: " Yeoh Ee Peng
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-02 9:22 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA need to output testresult into json files, where these json
testresult files will be stored in git repository by the future
test-case-management tools.
Both the testresult (eg. PASSED, FAILED, ERROR) and the test log
(eg. message from unit test assertion) will be created for storing.
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.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/lib/oeqa/core/runner.py | 137 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 126 insertions(+), 11 deletions(-)
diff --git a/meta/lib/oeqa/core/runner.py b/meta/lib/oeqa/core/runner.py
index eeb625b..54efdd0 100644
--- a/meta/lib/oeqa/core/runner.py
+++ b/meta/lib/oeqa/core/runner.py
@@ -6,6 +6,8 @@ import time
import unittest
import logging
import re
+import json
+import pathlib
from unittest import TextTestResult as _TestResult
from unittest import TextTestRunner as _TestRunner
@@ -44,6 +46,9 @@ class OETestResult(_TestResult):
self.tc = tc
+ self.result_types = ['failures', 'errors', 'skipped', 'expectedFailures', 'successes']
+ self.result_desc = ['FAILED', 'ERROR', 'SKIPPED', 'EXPECTEDFAIL', 'PASSED']
+
def startTest(self, test):
# May have been set by concurrencytest
if test.id() not in self.starttime:
@@ -80,7 +85,7 @@ class OETestResult(_TestResult):
msg += " (skipped=%d)" % skipped
self.tc.logger.info(msg)
- def _getDetailsNotPassed(self, case, type, desc):
+ def _isTestResultContainTestCaseWithResultTypeProvided(self, case, type):
found = False
for (scase, msg) in getattr(self, type):
@@ -121,16 +126,12 @@ class OETestResult(_TestResult):
for case_name in self.tc._registry['cases']:
case = self.tc._registry['cases'][case_name]
- result_types = ['failures', 'errors', 'skipped', 'expectedFailures', 'successes']
- result_desc = ['FAILED', 'ERROR', 'SKIPPED', 'EXPECTEDFAIL', 'PASSED']
-
- fail = False
+ found = False
desc = None
- for idx, name in enumerate(result_types):
- (fail, msg) = self._getDetailsNotPassed(case, result_types[idx],
- result_desc[idx])
- if fail:
- desc = result_desc[idx]
+ for idx, name in enumerate(self.result_types):
+ (found, msg) = self._isTestResultContainTestCaseWithResultTypeProvided(case, self.result_types[idx])
+ if found:
+ desc = self.result_desc[idx]
break
oeid = -1
@@ -143,13 +144,43 @@ class OETestResult(_TestResult):
if case.id() in self.starttime and case.id() in self.endtime:
t = " (" + "{0:.2f}".format(self.endtime[case.id()] - self.starttime[case.id()]) + "s)"
- if fail:
+ if found:
self.tc.logger.info("RESULTS - %s - Testcase %s: %s%s" % (case.id(),
oeid, desc, t))
else:
self.tc.logger.info("RESULTS - %s - Testcase %s: %s%s" % (case.id(),
oeid, 'UNKNOWN', t))
+ def _get_testcase_result_and_testmessage_dict(self):
+ testcase_result_dict = {}
+ testcase_testmessage_dict = {}
+ for case_name in self.tc._registry['cases']:
+ case = self.tc._registry['cases'][case_name]
+
+ found = False
+ desc = None
+ test_msg = ''
+ for idx, name in enumerate(self.result_types):
+ (found, msg) = self._isTestResultContainTestCaseWithResultTypeProvided(case, self.result_types[idx])
+ if found:
+ desc = self.result_desc[idx]
+ test_msg = msg
+ break
+
+ if found:
+ testcase_result_dict[case.id()] = desc
+ testcase_testmessage_dict[case.id()] = test_msg
+ else:
+ testcase_result_dict[case.id()] = "UNKNOWN"
+ return testcase_result_dict, testcase_testmessage_dict
+
+ def logDetailsInJson(self, file_dir):
+ (testcase_result_dict, testcase_testmessage_dict) = self._get_testcase_result_and_testmessage_dict()
+ if len(testcase_result_dict) > 0 and len(testcase_testmessage_dict) > 0:
+ jsontresulthelper = OEJSONTestResultHelper(testcase_result_dict, testcase_testmessage_dict)
+ jsontresulthelper.write_json_testresult_files(file_dir)
+ jsontresulthelper.write_testcase_log_files(os.path.join(file_dir, 'logs'))
+
class OEListTestsResult(object):
def wasSuccessful(self):
return True
@@ -261,3 +292,87 @@ class OETestRunner(_TestRunner):
self._list_tests_module(suite)
return OEListTestsResult()
+
+class OEJSONTestResultHelper(object):
+ def __init__(self, testcase_result_dict, testcase_log_dict):
+ self.testcase_result_dict = testcase_result_dict
+ self.testcase_log_dict = testcase_log_dict
+
+ def get_testcase_list(self):
+ return self.testcase_result_dict.keys()
+
+ def get_testsuite_from_testcase(self, testcase):
+ testsuite = testcase[0:testcase.rfind(".")]
+ return testsuite
+
+ def get_testmodule_from_testsuite(self, testsuite):
+ testmodule = testsuite[0:testsuite.find(".")]
+ return testmodule
+
+ def get_testsuite_testcase_dictionary(self):
+ testsuite_testcase_dict = {}
+ for testcase in self.get_testcase_list():
+ testsuite = self.get_testsuite_from_testcase(testcase)
+ if testsuite in testsuite_testcase_dict:
+ testsuite_testcase_dict[testsuite].append(testcase)
+ else:
+ testsuite_testcase_dict[testsuite] = [testcase]
+ return testsuite_testcase_dict
+
+ def get_testmodule_testsuite_dictionary(self, testsuite_testcase_dict):
+ testsuite_list = testsuite_testcase_dict.keys()
+ testmodule_testsuite_dict = {}
+ for testsuite in testsuite_list:
+ testmodule = self.get_testmodule_from_testsuite(testsuite)
+ if testmodule in testmodule_testsuite_dict:
+ testmodule_testsuite_dict[testmodule].append(testsuite)
+ else:
+ testmodule_testsuite_dict[testmodule] = [testsuite]
+ return testmodule_testsuite_dict
+
+ def _get_testcase_result(self, testcase, testcase_status_dict):
+ if testcase in testcase_status_dict:
+ return testcase_status_dict[testcase]
+ return ""
+
+ def _create_testcase_testresult_object(self, testcase_list, testcase_result_dict):
+ testcase_dict = {}
+ for testcase in sorted(testcase_list):
+ result = self._get_testcase_result(testcase, testcase_result_dict)
+ testcase_dict[testcase] = {"testresult": result}
+ return testcase_dict
+
+ def _create_json_testsuite_string(self, testsuite_list, testsuite_testcase_dict, testcase_result_dict):
+ testsuite_object = {'testsuite': {}}
+ testsuite_dict = testsuite_object['testsuite']
+ for testsuite in sorted(testsuite_list):
+ testsuite_dict[testsuite] = {'testcase': {}}
+ testsuite_dict[testsuite]['testcase'] = self._create_testcase_testresult_object(
+ testsuite_testcase_dict[testsuite],
+ testcase_result_dict)
+ return json.dumps(testsuite_object, sort_keys=True, indent=4)
+
+ def write_json_testresult_files(self, write_dir):
+ if not os.path.exists(write_dir):
+ pathlib.Path(write_dir).mkdir(parents=True, exist_ok=True)
+ testsuite_testcase_dict = self.get_testsuite_testcase_dictionary()
+ testmodule_testsuite_dict = self.get_testmodule_testsuite_dictionary(testsuite_testcase_dict)
+ for testmodule in testmodule_testsuite_dict.keys():
+ testsuite_list = testmodule_testsuite_dict[testmodule]
+ json_testsuite = self._create_json_testsuite_string(testsuite_list, testsuite_testcase_dict,
+ self.testcase_result_dict)
+ file_name = '%s.json' % testmodule
+ file_path = os.path.join(write_dir, file_name)
+ with open(file_path, 'w') as the_file:
+ the_file.write(json_testsuite)
+
+ def write_testcase_log_files(self, write_dir):
+ if not os.path.exists(write_dir):
+ pathlib.Path(write_dir).mkdir(parents=True, exist_ok=True)
+ for testcase in self.testcase_log_dict.keys():
+ test_log = self.testcase_log_dict[testcase]
+ if test_log is not None:
+ file_name = '%s.log' % testcase
+ file_path = os.path.join(write_dir, file_name)
+ with open(file_path, 'w') as the_file:
+ the_file.write(test_log)
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/4] selftest/context: write testresult to json files
2018-10-02 9:22 [PATCH 1/4] oeqa/runner: write testresult to json files Yeoh Ee Peng
@ 2018-10-02 9:22 ` Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 3/4] testimage.bbclass: " Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
2 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-02 9:22 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA selftest need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
By default, oe-selftest will write json testresult into files.
To disable this, provide '-s' argument to oe-selftest execution.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/lib/oeqa/selftest/context.py | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/meta/lib/oeqa/selftest/context.py b/meta/lib/oeqa/selftest/context.py
index c78947e..61b4afb 100644
--- a/meta/lib/oeqa/selftest/context.py
+++ b/meta/lib/oeqa/selftest/context.py
@@ -73,6 +73,9 @@ class OESelftestTestContextExecutor(OETestContextExecutor):
parser.add_argument('--machine', required=False, choices=['random', 'all'],
help='Run tests on different machines (random/all).')
+
+ parser.add_argument('-s', '--skip-export-json', action='store_true',
+ help='Skip the output test result in json format to files.')
parser.set_defaults(func=self.run)
@@ -99,8 +102,8 @@ class OESelftestTestContextExecutor(OETestContextExecutor):
return cases_paths
def _process_args(self, logger, args):
- args.output_log = '%s-results-%s.log' % (self.name,
- time.strftime("%Y%m%d%H%M%S"))
+ args.test_start_time = time.strftime("%Y%m%d%H%M%S")
+ args.output_log = '%s-results-%s.log' % (self.name, args.test_start_time)
args.test_data_file = None
args.CASES_PATHS = None
@@ -222,6 +225,11 @@ class OESelftestTestContextExecutor(OETestContextExecutor):
rc = self.tc.runTests(**self.tc_kwargs['run'])
rc.logDetails()
rc.logSummary(self.name)
+ if not args.skip_export_json:
+ json_result_dir = os.path.join(os.path.dirname(os.path.abspath(args.output_log)),
+ 'json_testresults-%s' % args.test_start_time,
+ 'oe-selftest')
+ rc.logDetailsInJson(json_result_dir)
return rc
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/4] testimage.bbclass: write testresult to json files
2018-10-02 9:22 [PATCH 1/4] oeqa/runner: write testresult to json files Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 2/4] selftest/context: " Yeoh Ee Peng
@ 2018-10-02 9:22 ` Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
2 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-02 9:22 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA testimage need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
By default, testimage will write json testresult, to disable
this, specify OEQA_SKIP_OUTPUT_JSON="1" as configuration.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/classes/testimage.bbclass | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/meta/classes/testimage.bbclass b/meta/classes/testimage.bbclass
index 39de191..0adaf60 100644
--- a/meta/classes/testimage.bbclass
+++ b/meta/classes/testimage.bbclass
@@ -306,6 +306,18 @@ def testimage_main(d):
bb.fatal('%s - FAILED - tests were interrupted during execution' % pn, forcelog=True)
results.logDetails()
results.logSummary(pn)
+ if (d.getVar('OEQA_SKIP_OUTPUT_JSON')) == '1':
+ bb.debug(2, 'Skip the OEQA output json testresult as OEQA_SKIP_OUTPUT_JSON=1')
+ else:
+ workdir = d.getVar("WORKDIR")
+ image_basename = d.getVar("IMAGE_BASENAME")
+ json_result_dir = os.path.join(workdir,
+ 'temp',
+ 'json_testresults-%s' % os.getpid(),
+ 'runtime',
+ machine,
+ image_basename)
+ results.logDetailsInJson(json_result_dir)
if not results.wasSuccessful():
bb.fatal('%s - FAILED - check the task log and the ssh log' % pn, forcelog=True)
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/4] testsdk.bbclass: write testresult to json files
2018-10-02 9:22 [PATCH 1/4] oeqa/runner: write testresult to json files Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 2/4] selftest/context: " Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 3/4] testimage.bbclass: " Yeoh Ee Peng
@ 2018-10-02 9:22 ` Yeoh Ee Peng
2 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-02 9:22 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA sdk and sdkext need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
By default, sdk and sdkext will write json testresult, to disable
this, specify OEQA_SKIP_OUTPUT_JSON="1" as configuration.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/classes/testsdk.bbclass | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index d3f475d..26c4789 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -83,7 +83,17 @@ def testsdk_main(d):
result.logDetails()
result.logSummary(component, context_msg)
-
+ if (d.getVar('OEQA_SKIP_OUTPUT_JSON')) == '1':
+ bb.debug(2, 'Skip the OEQA output json testresult as OEQA_SKIP_OUTPUT_JSON=1')
+ else:
+ workdir = d.getVar("WORKDIR")
+ image_basename = d.getVar("IMAGE_BASENAME")
+ json_result_dir = os.path.join(workdir,
+ 'temp',
+ 'json_testresults-%s' % os.getpid(),
+ 'sdk',
+ image_basename)
+ result.logDetailsInJson(json_result_dir)
if not result.wasSuccessful():
fail = True
@@ -187,7 +197,17 @@ def testsdkext_main(d):
result.logDetails()
result.logSummary(component, context_msg)
-
+ if (d.getVar('OEQA_SKIP_OUTPUT_JSON')) == '1':
+ bb.debug(2, 'Skip the OEQA output json testresult as OEQA_SKIP_OUTPUT_JSON=1')
+ else:
+ workdir = d.getVar("WORKDIR")
+ image_basename = d.getVar("IMAGE_BASENAME")
+ json_result_dir = os.path.join(workdir,
+ 'temp',
+ 'json_testresults-%s' % os.getpid(),
+ 'sdkext',
+ image_basename)
+ result.logDetailsInJson(json_result_dir)
if not result.wasSuccessful():
fail = True
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/4] oeqa/core/runner: write testresult to json files
@ 2018-10-12 6:33 Yeoh Ee Peng
2018-10-12 6:33 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
0 siblings, 1 reply; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-12 6:33 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA need to output testresult into json files, where these json
testresult files will be stored in git repository by the future
test-case-management tools.
Both the testresult (eg. PASSED, FAILED, ERROR) and the test log
(eg. message from unit test assertion) will be created for storing.
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.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/lib/oeqa/core/runner.py | 132 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 121 insertions(+), 11 deletions(-)
diff --git a/meta/lib/oeqa/core/runner.py b/meta/lib/oeqa/core/runner.py
index eeb625b..cc33d9c 100644
--- a/meta/lib/oeqa/core/runner.py
+++ b/meta/lib/oeqa/core/runner.py
@@ -6,6 +6,8 @@ import time
import unittest
import logging
import re
+import json
+import pathlib
from unittest import TextTestResult as _TestResult
from unittest import TextTestRunner as _TestRunner
@@ -44,6 +46,9 @@ class OETestResult(_TestResult):
self.tc = tc
+ self.result_types = ['failures', 'errors', 'skipped', 'expectedFailures', 'successes']
+ self.result_desc = ['FAILED', 'ERROR', 'SKIPPED', 'EXPECTEDFAIL', 'PASSED']
+
def startTest(self, test):
# May have been set by concurrencytest
if test.id() not in self.starttime:
@@ -80,7 +85,7 @@ class OETestResult(_TestResult):
msg += " (skipped=%d)" % skipped
self.tc.logger.info(msg)
- def _getDetailsNotPassed(self, case, type, desc):
+ def _isTestResultContainTestCaseWithResultTypeProvided(self, case, type):
found = False
for (scase, msg) in getattr(self, type):
@@ -121,16 +126,12 @@ class OETestResult(_TestResult):
for case_name in self.tc._registry['cases']:
case = self.tc._registry['cases'][case_name]
- result_types = ['failures', 'errors', 'skipped', 'expectedFailures', 'successes']
- result_desc = ['FAILED', 'ERROR', 'SKIPPED', 'EXPECTEDFAIL', 'PASSED']
-
- fail = False
+ found = False
desc = None
- for idx, name in enumerate(result_types):
- (fail, msg) = self._getDetailsNotPassed(case, result_types[idx],
- result_desc[idx])
- if fail:
- desc = result_desc[idx]
+ for idx, name in enumerate(self.result_types):
+ (found, msg) = self._isTestResultContainTestCaseWithResultTypeProvided(case, self.result_types[idx])
+ if found:
+ desc = self.result_desc[idx]
break
oeid = -1
@@ -143,13 +144,43 @@ class OETestResult(_TestResult):
if case.id() in self.starttime and case.id() in self.endtime:
t = " (" + "{0:.2f}".format(self.endtime[case.id()] - self.starttime[case.id()]) + "s)"
- if fail:
+ if found:
self.tc.logger.info("RESULTS - %s - Testcase %s: %s%s" % (case.id(),
oeid, desc, t))
else:
self.tc.logger.info("RESULTS - %s - Testcase %s: %s%s" % (case.id(),
oeid, 'UNKNOWN', t))
+ def _get_testcase_result_and_log_dict(self):
+ testcase_result_dict = {}
+ testcase_log_dict = {}
+ for case_name in self.tc._registry['cases']:
+ case = self.tc._registry['cases'][case_name]
+
+ found = False
+ desc = None
+ test_log = ''
+ for idx, name in enumerate(self.result_types):
+ (found, msg) = self._isTestResultContainTestCaseWithResultTypeProvided(case, self.result_types[idx])
+ if found:
+ desc = self.result_desc[idx]
+ test_log = msg
+ break
+
+ if found:
+ testcase_result_dict[case.id()] = desc
+ testcase_log_dict[case.id()] = test_log
+ else:
+ testcase_result_dict[case.id()] = "UNKNOWN"
+ return testcase_result_dict, testcase_log_dict
+
+ def logDetailsInJson(self, file_dir):
+ (testcase_result_dict, testcase_log_dict) = self._get_testcase_result_and_log_dict()
+ if len(testcase_result_dict) > 0 and len(testcase_log_dict) > 0:
+ tresultjsonhelper = OETestResultJSONHelper()
+ tresultjsonhelper.dump_testresult_files(testcase_result_dict, file_dir)
+ tresultjsonhelper.dump_log_files(testcase_log_dict, os.path.join(file_dir, 'logs'))
+
class OEListTestsResult(object):
def wasSuccessful(self):
return True
@@ -261,3 +292,82 @@ class OETestRunner(_TestRunner):
self._list_tests_module(suite)
return OEListTestsResult()
+
+class OETestResultJSONHelper(object):
+
+ def get_testsuite_from_testcase(self, testcase):
+ testsuite = testcase[0:testcase.rfind(".")]
+ return testsuite
+
+ def get_testmodule_from_testsuite(self, testsuite):
+ testmodule = testsuite[0:testsuite.find(".")]
+ return testmodule
+
+ def get_testsuite_testcase_dictionary(self, testcase_result_dict):
+ testcase_list = testcase_result_dict.keys()
+ testsuite_testcase_dict = {}
+ for testcase in testcase_list:
+ testsuite = self.get_testsuite_from_testcase(testcase)
+ if testsuite in testsuite_testcase_dict:
+ testsuite_testcase_dict[testsuite].append(testcase)
+ else:
+ testsuite_testcase_dict[testsuite] = [testcase]
+ return testsuite_testcase_dict
+
+ def get_testmodule_testsuite_dictionary(self, testsuite_testcase_dict):
+ testsuite_list = testsuite_testcase_dict.keys()
+ testmodule_testsuite_dict = {}
+ for testsuite in testsuite_list:
+ testmodule = self.get_testmodule_from_testsuite(testsuite)
+ if testmodule in testmodule_testsuite_dict:
+ testmodule_testsuite_dict[testmodule].append(testsuite)
+ else:
+ testmodule_testsuite_dict[testmodule] = [testsuite]
+ return testmodule_testsuite_dict
+
+ def _get_testcase_result(self, testcase, testcase_status_dict):
+ if testcase in testcase_status_dict:
+ return testcase_status_dict[testcase]
+ return ""
+
+ def _create_testcase_testresult_object(self, testcase_list, testcase_result_dict):
+ testcase_dict = {}
+ for testcase in sorted(testcase_list):
+ result = self._get_testcase_result(testcase, testcase_result_dict)
+ testcase_dict[testcase] = {"testresult": result}
+ return testcase_dict
+
+ def _create_json_testsuite_string(self, testsuite_list, testsuite_testcase_dict, testcase_result_dict):
+ testsuite_object = {'testsuite': {}}
+ testsuite_dict = testsuite_object['testsuite']
+ for testsuite in sorted(testsuite_list):
+ testsuite_dict[testsuite] = {'testcase': {}}
+ testsuite_dict[testsuite]['testcase'] = self._create_testcase_testresult_object(
+ testsuite_testcase_dict[testsuite],
+ testcase_result_dict)
+ return json.dumps(testsuite_object, sort_keys=True, indent=4)
+
+ def dump_testresult_files(self, testcase_result_dict, write_dir):
+ if not os.path.exists(write_dir):
+ pathlib.Path(write_dir).mkdir(parents=True, exist_ok=True)
+ testsuite_testcase_dict = self.get_testsuite_testcase_dictionary(testcase_result_dict)
+ testmodule_testsuite_dict = self.get_testmodule_testsuite_dictionary(testsuite_testcase_dict)
+ for testmodule in testmodule_testsuite_dict.keys():
+ testsuite_list = testmodule_testsuite_dict[testmodule]
+ json_testsuite = self._create_json_testsuite_string(testsuite_list, testsuite_testcase_dict,
+ testcase_result_dict)
+ file_name = '%s.json' % testmodule
+ file_path = os.path.join(write_dir, file_name)
+ with open(file_path, 'w') as the_file:
+ the_file.write(json_testsuite)
+
+ def dump_log_files(self, testcase_log_dict, write_dir):
+ if not os.path.exists(write_dir):
+ pathlib.Path(write_dir).mkdir(parents=True, exist_ok=True)
+ for testcase in testcase_log_dict.keys():
+ test_log = testcase_log_dict[testcase]
+ if test_log is not None:
+ file_name = '%s.log' % testcase
+ file_path = os.path.join(write_dir, file_name)
+ with open(file_path, 'w') as the_file:
+ the_file.write(test_log)
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/4] testsdk.bbclass: write testresult to json files
2018-10-12 6:33 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
@ 2018-10-12 6:33 ` Yeoh Ee Peng
0 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-12 6:33 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA sdk and sdkext need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
By default, sdk and sdkext will write json testresult, to disable
this, specify OEQA_SKIP_OUTPUT_JSON="1" as configuration.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/classes/testsdk.bbclass | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index d3f475d..6f81fe0 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -83,6 +83,17 @@ def testsdk_main(d):
result.logDetails()
result.logSummary(component, context_msg)
+ if (d.getVar('OEQA_SKIP_OUTPUT_JSON')) == '1':
+ bb.debug(2, 'Skip the OEQA output json testresult as OEQA_SKIP_OUTPUT_JSON=1')
+ else:
+ workdir = d.getVar("WORKDIR")
+ image_basename = d.getVar("IMAGE_BASENAME")
+ json_result_dir = os.path.join(workdir,
+ 'temp',
+ 'json_testresults-%s' % os.getpid(),
+ 'sdk',
+ image_basename)
+ result.logDetailsInJson(json_result_dir)
if not result.wasSuccessful():
fail = True
@@ -187,6 +198,17 @@ def testsdkext_main(d):
result.logDetails()
result.logSummary(component, context_msg)
+ if (d.getVar('OEQA_SKIP_OUTPUT_JSON')) == '1':
+ bb.debug(2, 'Skip the OEQA output json testresult as OEQA_SKIP_OUTPUT_JSON=1')
+ else:
+ workdir = d.getVar("WORKDIR")
+ image_basename = d.getVar("IMAGE_BASENAME")
+ json_result_dir = os.path.join(workdir,
+ 'temp',
+ 'json_testresults-%s' % os.getpid(),
+ 'sdkext',
+ image_basename)
+ result.logDetailsInJson(json_result_dir)
if not result.wasSuccessful():
fail = True
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/4] oeqa/core/runner: write testresult to json files
@ 2018-10-22 6:54 Yeoh Ee Peng
2018-10-22 6:54 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
0 siblings, 1 reply; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-22 6:54 UTC (permalink / raw)
To: openembedded-core
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 testresult 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.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/lib/oeqa/core/runner.py | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/meta/lib/oeqa/core/runner.py b/meta/lib/oeqa/core/runner.py
index f1dd080..82463cf 100644
--- a/meta/lib/oeqa/core/runner.py
+++ b/meta/lib/oeqa/core/runner.py
@@ -6,6 +6,7 @@ import time
import unittest
import logging
import re
+import json
from unittest import TextTestResult as _TestResult
from unittest import TextTestRunner as _TestRunner
@@ -119,8 +120,9 @@ class OETestResult(_TestResult):
self.successes.append((test, None))
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:")
+ result = {}
for case_name in self.tc._registry['cases']:
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)"
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(result_id, result, configuration, json_file_dir)
class OEListTestsResult(object):
def wasSuccessful(self):
@@ -249,3 +256,34 @@ class OETestRunner(_TestRunner):
self._list_tests_module(suite)
return OEListTestsResult()
+
+class OETestResultJSONHelper(object):
+
+ testresult_filename = 'testresults.json'
+
+ def _get_testresults(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 _create_json_testresults_string(self, result_id, test_result, configuration, write_dir):
+ testresults = self._get_testresults(write_dir)
+ testresult = {'configuration': configuration,
+ 'result': test_result}
+ testresults[result_id] = testresult
+ return json.dumps(testresults, sort_keys=True, indent=4)
+
+ 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, result_id, test_result, configuration, write_dir):
+ bb.utils.mkdirhier(write_dir)
+ lf = bb.utils.lockfile(os.path.join(write_dir, 'jsontestresult.lock'))
+ json_testresults = self._create_json_testresults_string(result_id, test_result, configuration, write_dir)
+ self._write_file(write_dir, self.testresult_filename, json_testresults)
+ bb.utils.unlockfile(lf)
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/4] testsdk.bbclass: write testresult to json files
2018-10-22 6:54 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
@ 2018-10-22 6:54 ` Yeoh Ee Peng
0 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-22 6:54 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA sdk and sdkext need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
To configure multiple instances of bitbake to write json testresult
to a single testresult file, user will define the variable
"OEQA_JSON_RESULT_COMMON_DIR" with the common directory for writing
json testresult.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/classes/testsdk.bbclass | 40 ++++++++++++++++++++++++++++++++++++----
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index d3f475d..c4a0f37 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -2,6 +2,7 @@
#
# Released under the MIT license (see COPYING.MIT)
+inherit metadata_scm
# testsdk.bbclass enables testing for SDK and Extensible SDK
#
# To run SDK tests, run the commands:
@@ -14,6 +15,33 @@
#
# where "<image-name>" is an image like core-image-sato.
+def _get_configuration(d, test_type, pid):
+ import platform
+ bb_core_dir = d.getVar("BBFILE_PATTERN_core=")
+ return {'TEST_TYPE': test_type,
+ 'BRANCH': base_get_metadata_git_branch(bb_core_dir, None).strip(),
+ 'COMMIT': base_get_metadata_git_revision(bb_core_dir, None),
+ 'PROCESS_ID': pid,
+ 'SDK_MACHINE': d.getVar("SDKMACHINE"),
+ 'IMAGE_BASENAME': d.getVar("IMAGE_BASENAME"),
+ 'IMAGE_PKGTYPE': d.getVar("IMAGE_PKGTYPE"),
+ 'HOST_DISTRO': platform.linux_distribution()}
+
+def _get_json_result_dir(d, configuration):
+ json_result_dir = os.path.join(d.getVar("WORKDIR"),
+ 'temp',
+ 'json_testresults-%s' % configuration['PROCESS_ID'],
+ configuration['TEST_TYPE'],
+ configuration['SDK_MACHINE'],
+ configuration['IMAGE_BASENAME'])
+ oeqa_json_result_common_dir = d.getVar("OEQA_JSON_RESULT_COMMON_DIR")
+ if oeqa_json_result_common_dir:
+ json_result_dir = oeqa_json_result_common_dir
+ return json_result_dir
+
+def _get_result_id(configuration):
+ return '%s-%s-%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDK_MACHINE'])
+
def testsdk_main(d):
import os
import subprocess
@@ -80,8 +108,10 @@ def testsdk_main(d):
component = "%s %s" % (pn, OESDKTestContextExecutor.name)
context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
-
- result.logDetails()
+ configuration = _get_configuration(d, 'sdk', os.getpid())
+ result.logDetails(_get_json_result_dir(d, configuration),
+ configuration,
+ _get_result_id(configuration))
result.logSummary(component, context_msg)
if not result.wasSuccessful():
@@ -184,8 +214,10 @@ def testsdkext_main(d):
component = "%s %s" % (pn, OESDKExtTestContextExecutor.name)
context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
-
- result.logDetails()
+ configuration = _get_configuration(d, 'sdkext', os.getpid())
+ result.logDetails(_get_json_result_dir(d, configuration),
+ configuration,
+ _get_result_id(configuration))
result.logSummary(component, context_msg)
if not result.wasSuccessful():
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/4] oeqa/core/runner: write testresult to json files
@ 2018-10-22 10:34 Yeoh Ee Peng
2018-10-22 10:34 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
0 siblings, 1 reply; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-22 10:34 UTC (permalink / raw)
To: openembedded-core
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.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/lib/oeqa/core/runner.py | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/meta/lib/oeqa/core/runner.py b/meta/lib/oeqa/core/runner.py
index f1dd080..2243a10 100644
--- a/meta/lib/oeqa/core/runner.py
+++ b/meta/lib/oeqa/core/runner.py
@@ -6,6 +6,7 @@ import time
import unittest
import logging
import re
+import json
from unittest import TextTestResult as _TestResult
from unittest import TextTestRunner as _TestRunner
@@ -119,8 +120,9 @@ class OETestResult(_TestResult):
self.successes.append((test, None))
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:")
+ result = {}
for case_name in self.tc._registry['cases']:
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)"
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(result_id, result, configuration, json_file_dir)
class OEListTestsResult(object):
def wasSuccessful(self):
@@ -249,3 +256,33 @@ class OETestRunner(_TestRunner):
self._list_tests_module(suite)
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 _create_json_testresults_string(self, test_results, result_id, test_result, configuration):
+ test_results[result_id] = {'configuration': configuration, 'result': test_result}
+ return json.dumps(test_results, sort_keys=True, indent=4)
+
+ 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, result_id, test_result, configuration, write_dir):
+ 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)
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/4] testsdk.bbclass: write testresult to json files
2018-10-22 10:34 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
@ 2018-10-22 10:34 ` Yeoh Ee Peng
0 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-22 10:34 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA sdk and sdkext need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
To configure multiple instances of bitbake to write json testresult
to a single testresult file at custom direcotry, user will define
the variable "OEQA_JSON_RESULT_DIR" with the custom directory for writing
json testresult.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/classes/testsdk.bbclass | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index d3f475d..2e5f672 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -14,6 +14,30 @@
#
# where "<image-name>" is an image like core-image-sato.
+def _get_sdk_configuration(d, test_type, pid):
+ import platform
+ configuration = {'TEST_TYPE': test_type,
+ 'PROCESS_ID': pid,
+ 'SDK_MACHINE': d.getVar("SDKMACHINE"),
+ 'IMAGE_BASENAME': d.getVar("IMAGE_BASENAME"),
+ 'IMAGE_PKGTYPE': d.getVar("IMAGE_PKGTYPE"),
+ 'HOST_DISTRO': platform.linux_distribution()}
+ layers = (d.getVar("BBLAYERS") or "").split()
+ for l in layers:
+ configuration['%s_BRANCH_REV' % os.path.basename(l)] = '%s:%s' % (base_get_metadata_git_branch(l, None).strip(),
+ base_get_metadata_git_revision(l, None))
+ return configuration
+
+def _get_sdk_json_result_dir(d, configuration):
+ json_result_dir = os.path.join(d.getVar("WORKDIR"), 'oeqa')
+ oeqa_json_result_common_dir = d.getVar("OEQA_JSON_RESULT_DIR")
+ if oeqa_json_result_common_dir:
+ json_result_dir = oeqa_json_result_common_dir
+ return json_result_dir
+
+def _get_sdk_result_id(configuration):
+ return '%s-%s-%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDK_MACHINE'])
+
def testsdk_main(d):
import os
import subprocess
@@ -80,8 +104,10 @@ def testsdk_main(d):
component = "%s %s" % (pn, OESDKTestContextExecutor.name)
context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
-
- result.logDetails()
+ configuration = _get_sdk_configuration(d, 'sdk', os.getpid())
+ result.logDetails(_get_sdk_json_result_dir(d, configuration),
+ configuration,
+ _get_sdk_result_id(configuration))
result.logSummary(component, context_msg)
if not result.wasSuccessful():
@@ -184,8 +210,10 @@ def testsdkext_main(d):
component = "%s %s" % (pn, OESDKExtTestContextExecutor.name)
context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
-
- result.logDetails()
+ configuration = _get_sdk_configuration(d, 'sdkext', os.getpid())
+ result.logDetails(_get_sdk_json_result_dir(d, configuration),
+ configuration,
+ _get_sdk_result_id(configuration))
result.logSummary(component, context_msg)
if not result.wasSuccessful():
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/4] oeqa/core/runner: write testresult to json files
@ 2018-10-23 5:57 Yeoh Ee Peng
2018-10-23 5:57 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
0 siblings, 1 reply; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-23 5:57 UTC (permalink / raw)
To: openembedded-core
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.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/lib/oeqa/core/runner.py | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/meta/lib/oeqa/core/runner.py b/meta/lib/oeqa/core/runner.py
index f1dd080..d6d5afe 100644
--- a/meta/lib/oeqa/core/runner.py
+++ b/meta/lib/oeqa/core/runner.py
@@ -6,6 +6,7 @@ import time
import unittest
import logging
import re
+import json
from unittest import TextTestResult as _TestResult
from unittest import TextTestRunner as _TestRunner
@@ -119,8 +120,9 @@ class OETestResult(_TestResult):
self.successes.append((test, None))
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:")
+ result = {}
for case_name in self.tc._registry['cases']:
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)"
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):
def wasSuccessful(self):
@@ -249,3 +256,29 @@ class OETestRunner(_TestRunner):
self._list_tests_module(suite)
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)
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/4] testsdk.bbclass: write testresult to json files
2018-10-23 5:57 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
@ 2018-10-23 5:57 ` Yeoh Ee Peng
0 siblings, 0 replies; 8+ messages in thread
From: Yeoh Ee Peng @ 2018-10-23 5:57 UTC (permalink / raw)
To: openembedded-core
As part of the solution to replace Testopia to store testresult,
OEQA sdk and sdkext need to output testresult into json files, where
these json testresult files will be stored into git repository
by the future test-case-management tools.
By default, json testresult file will be written to "oeqa"
directory under the "WORKDIR" directory.
To configure multiple instances of bitbake to write json testresult
to a single testresult file at custom directory, user will define
the variable "OEQA_JSON_RESULT_DIR" with the custom directory for
json testresult.
Signed-off-by: Yeoh Ee Peng <ee.peng.yeoh@intel.com>
---
meta/classes/testsdk.bbclass | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index d3f475d..a6c3627 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -14,6 +14,30 @@
#
# where "<image-name>" is an image like core-image-sato.
+def _get_sdk_configuration(d, test_type, pid):
+ import platform
+ configuration = {'TEST_TYPE': test_type,
+ 'PROCESS_ID': pid,
+ 'SDK_MACHINE': d.getVar("SDKMACHINE"),
+ 'IMAGE_BASENAME': d.getVar("IMAGE_BASENAME"),
+ 'IMAGE_PKGTYPE': d.getVar("IMAGE_PKGTYPE"),
+ 'HOST_DISTRO': ('-'.join(platform.linux_distribution())).replace(' ', '-')}
+ layers = (d.getVar("BBLAYERS") or "").split()
+ for l in layers:
+ configuration['%s_BRANCH_REV' % os.path.basename(l)] = '%s:%s' % (base_get_metadata_git_branch(l, None).strip(),
+ base_get_metadata_git_revision(l, None))
+ return configuration
+
+def _get_sdk_json_result_dir(d):
+ json_result_dir = os.path.join(d.getVar("WORKDIR"), 'oeqa')
+ custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR")
+ if custom_json_result_dir:
+ json_result_dir = custom_json_result_dir
+ return json_result_dir
+
+def _get_sdk_result_id(configuration):
+ return '%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDK_MACHINE'])
+
def testsdk_main(d):
import os
import subprocess
@@ -80,8 +104,10 @@ def testsdk_main(d):
component = "%s %s" % (pn, OESDKTestContextExecutor.name)
context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
-
- result.logDetails()
+ configuration = _get_sdk_configuration(d, 'sdk', os.getpid())
+ result.logDetails(_get_sdk_json_result_dir(d),
+ configuration,
+ _get_sdk_result_id(configuration))
result.logSummary(component, context_msg)
if not result.wasSuccessful():
@@ -184,8 +210,10 @@ def testsdkext_main(d):
component = "%s %s" % (pn, OESDKExtTestContextExecutor.name)
context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
-
- result.logDetails()
+ configuration = _get_sdk_configuration(d, 'sdkext', os.getpid())
+ result.logDetails(_get_sdk_json_result_dir(d),
+ configuration,
+ _get_sdk_result_id(configuration))
result.logSummary(component, context_msg)
if not result.wasSuccessful():
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-10-23 6:12 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-02 9:22 [PATCH 1/4] oeqa/runner: write testresult to json files Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 2/4] selftest/context: " Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 3/4] testimage.bbclass: " Yeoh Ee Peng
2018-10-02 9:22 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
-- strict thread matches above, loose matches on Subject: below --
2018-10-12 6:33 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
2018-10-12 6:33 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
2018-10-22 6:54 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
2018-10-22 6:54 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
2018-10-22 10:34 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
2018-10-22 10:34 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
2018-10-23 5:57 [PATCH 1/4] oeqa/core/runner: " Yeoh Ee Peng
2018-10-23 5:57 ` [PATCH 4/4] testsdk.bbclass: " Yeoh Ee Peng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox