<div dir="ltr">This was initially for our needs.<div>For general usage it need to be changed so full result will be reported.</div><div>I will fix that.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 6 September 2017 at 04:25, Jianbo Liu <span dir="ltr"><<a href="mailto:jianbo.liu@linaro.org" target="_blank">jianbo.liu@linaro.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 5 September 2017 at 23:26, Radoslaw Biernacki<br>
<div><div class="h5"><<a href="mailto:radoslaw.biernacki@linaro.org">radoslaw.biernacki@linaro.org</a><wbr>> wrote:<br>
> This patch adds the JSON reporter class which puts the results<br>
> into output/test_results.json file<br>
> Having JSON file format for results is usefull for CI integration.<br>
><br>
> Signed-off-by: Radoslaw Biernacki <<a href="mailto:radoslaw.biernacki@linaro.org">radoslaw.biernacki@linaro.org</a><wbr>><br>
> ---<br>
>  framework/dts.py           |  5 ++++<br>
>  framework/json_reporter.py | 75 ++++++++++++++++++++++++++++++<wbr>++++++++++++++++<br>
>  2 files changed, 80 insertions(+)<br>
>  create mode 100644 framework/json_reporter.py<br>
><br>
> diff --git a/framework/dts.py b/framework/dts.py<br>
> index 931bf38..b38deb7 100644<br>
> --- a/framework/dts.py<br>
> +++ b/framework/dts.py<br>
> @@ -51,6 +51,7 @@ from test_case import TestCase<br>
>  from test_result import Result<br>
>  from stats_reporter import StatsReporter<br>
>  from excel_reporter import ExcelReporter<br>
> +from json_reporter import JSONReporter<br>
>  from exception import TimeoutException, ConfigParseException, VerifyFailure<br>
>  from logger import getLogger<br>
>  import logger<br>
> @@ -66,6 +67,7 @@ sys.setdefaultencoding('UTF8')<br>
>  requested_tests = None<br>
>  result = None<br>
>  excel_report = None<br>
> +json_report = None<br>
>  stats_report = None<br>
>  log_handler = None<br>
><br>
> @@ -443,6 +445,7 @@ def run_all(config_file, pkgName, git, patch, skip_setup,<br>
>      global requested_tests<br>
>      global result<br>
>      global excel_report<br>
> +    global json_report<br>
>      global stats_report<br>
>      global log_handler<br>
>      global check_case_inst<br>
> @@ -506,6 +509,7 @@ def run_all(config_file, pkgName, git, patch, skip_setup,<br>
><br>
>      # report objects<br>
>      excel_report = ExcelReporter(output_dir + '/test_results.xls')<br>
> +    json_report = JSONReporter(output_dir + '/test_results.json')<br>
>      stats_report = StatsReporter(output_dir + '/statistics.txt')<br>
>      result = Result()<br>
><br>
> @@ -574,6 +578,7 @@ def save_all_results():<br>
>      Save all result to files.<br>
>      """<br>
>      excel_report.save(result)<br>
> +    json_report.save(result)<br>
>      stats_report.save(result)<br>
><br>
><br>
> diff --git a/framework/json_reporter.py b/framework/json_reporter.py<br>
> new file mode 100644<br>
> index 0000000..47e6869<br>
> --- /dev/null<br>
> +++ b/framework/json_reporter.py<br>
> @@ -0,0 +1,75 @@<br>
> +# BSD LICENSE<br>
> +#<br>
> +# Copyright(c) 2017 Linaro. All rights reserved.<br>
> +# All rights reserved.<br>
> +#<br>
> +# Redistribution and use in source and binary forms, with or without<br>
> +# modification, are permitted provided that the following conditions<br>
> +# are met:<br>
> +#<br>
> +#   * Redistributions of source code must retain the above copyright<br>
> +#     notice, this list of conditions and the following disclaimer.<br>
> +#   * Redistributions in binary form must reproduce the above copyright<br>
> +#     notice, this list of conditions and the following disclaimer in<br>
> +#     the documentation and/or other materials provided with the<br>
> +#     distribution.<br>
> +#   * Neither the name of Intel Corporation nor the names of its<br>
> +#     contributors may be used to endorse or promote products derived<br>
> +#     from this software without specific prior written permission.<br>
> +#<br>
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS<br>
> +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT<br>
> +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR<br>
> +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT<br>
> +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,<br>
> +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT<br>
> +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,<br>
> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY<br>
> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br>
> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE<br>
> +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br>
> +<br>
> +import json<br>
> +import os<br>
> +<br>
> +class JSONReporter(object):<br>
> +<br>
> +    def __init__(self, filename):<br>
> +        self.filename = filename<br>
> +<br>
> +    def __scan_cases(self, result, dut, target, suite):<br>
> +        case_results = {}<br>
> +        for case in result.all_test_cases(dut, target, suite):<br>
> +             test_result = result.result_for(dut, target, suite, case)<br>
> +             case_name = '{}/{}'.format(suite,case)<br>
> +             if 'PASSED' in test_result:<br>
> +                 case_results[case_name] = 'pass'<br>
> +             else:<br>
> +                 case_results[case_name] = 'fail'<br>
<br>
</div></div>Is it reasonable to consider "N/A" or "SKIP" as fail?<br>
<div class="HOEnZb"><div class="h5"><br>
> +        return case_results<br>
> +<br>
> +    def __scan_target(self, result, dut, target):<br>
> +        if result.is_target_failed(dut, target):<br>
> +            return {'Target failed', 'fail'}<br>
> +        case_results = {}<br>
> +        for suite in result.all_test_suites(dut, target):<br>
> +            case_results.update(self.__<wbr>scan_cases(result, dut, target, suite))<br>
> +        abspath = os.path.abspath(self.filename)<br>
> +        filename = os.path.basename(abspath)<br>
> +        dirname = os.path.dirname(abspath)<br>
> +        splitname = os.path.splitext(filename)<br>
> +        extfilename = '{}/{}_{}_{}{}'.format(<wbr>dirname, splitname[0], dut, target, splitname[1])<br>
> +        with open(extfilename, 'w') as outfile:<br>
> +            json.dump(case_results, outfile, indent=4, separators=(',', ': '), encoding="utf-8", sort_keys=True)<br>
> +<br>
> +    def __scan_dut(self, result, dut):<br>
> +        if result.is_dut_failed(dut):<br>
> +            return {'DUT failed', 'fail'}<br>
> +        case_results = {}<br>
> +        for target in result.all_targets(dut):<br>
> +            self.__scan_target(result, dut, target)<br>
> +<br>
> +    def save(self, result):<br>
> +        case_results = {}<br>
> +        for dut in result.all_duts():<br>
> +            self.__scan_dut(result, dut)<br>
> --<br>
> 1.9.1<br>
><br>
</div></div></blockquote></div><br></div>