• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# coding=utf-8
3
4#
5# Copyright (c) 2022 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import os
20import xml.dom.minidom
21from xdevice import get_cst_time
22from devicetest.core.constants import RunResult
23from devicetest.core.error_message import ErrorMessage
24from devicetest.core.exception import DeviceTestError
25from devicetest.log.logger import DeviceTestLog as log
26
27
28class ReportConstants:
29    _STRIP_FORMAT_TIME = "%Y-%m-%d-%H-%M-%S-%f"
30    _STRF_TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
31    _XML_NAME = "report.xml"
32    _FILE_FARMAT = ".xml"
33
34
35class ReportHandler:
36
37    def __init__(self, report_path):
38        self.report_path = report_path
39        self.test_results = []
40
41    def generate_test_report(self, test_runner, _test_results=None, report_type="normal"):
42        if os.path.exists(self.report_path):
43            dom = xml.dom.minidom.parse(self.report_path)
44            result_node = dom.documentElement
45            return self.report_path, result_node.toxml()
46        try:
47            log.info("start generate test report.")
48            test_results = _test_results or test_runner.test_results
49
50            start_time = test_runner.start_time
51
52            impl = xml.dom.minidom.getDOMImplementation()
53            dom = impl.createDocument(None, 'testsuites', None)
54            result_node = dom.documentElement
55
56            test_name = test_runner.configs.get("test_name")
57            if test_name is not None:
58                result_node.setAttribute("name", test_name)
59            else:
60                result_node.setAttribute("name", ReportConstants._XML_NAME)
61
62            result_node.setAttribute("report_version", "1.0")
63
64            if report_type == "xts":
65                tests_total, tests_error = self.report_xts_type(test_results, dom, result_node)
66            else:
67                tests_total, tests_error = self.report_normal_type(test_results, dom, test_name, result_node)
68
69            result_node.setAttribute("tests", str(tests_total))
70            result_node.setAttribute("failures", str(tests_error))
71            result_node.setAttribute("disabled", '')
72            result_node.setAttribute("errors", "")
73            result_node.setAttribute("starttime",
74                                     self.get_strftime(start_time))
75            result_node.setAttribute("endtime", self.get_now_strftime())
76
77            if not os.path.exists(os.path.dirname(self.report_path)):
78                os.makedirs(os.path.dirname(self.report_path))
79            with open(self.report_path, mode='w',
80                      encoding='utf-8') as fre:
81                dom.writexml(fre, addindent='\t', newl='\n',
82                             encoding="utf-8")
83            return self.report_path, result_node.toxml()
84
85        except Exception as error:
86            log.error(ErrorMessage.Error_01207.Message.en,
87                      error_no=ErrorMessage.Error_01207.Code,
88                      is_traceback=True)
89            raise DeviceTestError(ErrorMessage.Error_01207.Topic) from error
90
91        finally:
92            log.info("exit generate test report.")
93
94    def get_strftime(self, stamp_time):
95        return stamp_time.strftime(ReportConstants._STRF_TIME_FORMAT)
96
97    def get_now_strftime(self):
98        return get_cst_time().strftime(ReportConstants._STRF_TIME_FORMAT)
99
100    def report_normal_type(self, test_results, dom, test_name, result_node):
101        tests_total = 0
102        tests_error = 0
103        for result_info in test_results:
104
105            tests_total += 1
106            case_error = 0
107            case_result = "true"
108            result = result_info.get('result')
109            if result != RunResult.PASSED:
110                tests_error += 1
111                case_error += 1
112                case_result = "false"
113            case_name = result_info.get('case_name')
114            case_start_time = result_info.get('start_time').timestamp()
115            case_end_time = result_info.get('end_time').timestamp()
116            error = result_info.get('error')
117            report = result_info.get("report", "")
118            case_time = case_end_time - case_start_time
119
120            test_case = dom.createElement("testcase")
121            test_case.setAttribute("name", case_name)
122            test_case.setAttribute("status", 'run')
123            test_case.setAttribute("classname", case_name)
124            test_case.setAttribute("level", None)
125            test_case.setAttribute("result", case_result)
126            test_case.setAttribute("result_kind", result)
127            test_case.setAttribute("message", error)
128            test_case.setAttribute("report", report)
129
130            test_suite = dom.createElement("testsuite")
131            test_suite.setAttribute("modulename", test_name)
132            test_suite.setAttribute("name", case_name)
133            test_suite.setAttribute("tests", str(1))
134            test_suite.setAttribute("failures", str(case_error))
135            test_suite.setAttribute("disabled", '0')
136            test_suite.setAttribute("time", "{:.2f}".format(case_time))
137            test_suite.setAttribute("result", case_result)
138            test_suite.setAttribute("result_kind", result)
139            test_suite.setAttribute("report", report)
140            test_suite.appendChild(test_case)
141            result_node.appendChild(test_suite)
142        return tests_total, tests_error
143
144    def report_xts_type(self, test_results, dom, result_node):
145        tests_total = 0
146        tests_error = 0
147        test_suites = {}
148        for result_info in test_results:
149
150            tests_total += 1
151            case_error = 0
152            case_result = "true"
153            result = result_info.get('result')
154            if result != RunResult.PASSED:
155                tests_error += 1
156                case_error += 1
157                case_result = "false"
158            case_info = result_info.get('case_name').split("#")
159            case_name = case_info[1]
160            module_name = case_info[0]
161            case_start_time = result_info.get('start_time').timestamp()
162            case_end_time = result_info.get('end_time').timestamp()
163            error = result_info.get('error')
164            report = result_info.get("report", "")
165            case_time = case_end_time - case_start_time
166
167            test_case = dom.createElement("testcase")
168            test_case.setAttribute("name", case_name)
169            test_case.setAttribute("status", 'run')
170            test_case.setAttribute("classname", module_name)
171            test_case.setAttribute("level", None)
172            test_case.setAttribute("result", case_result)
173            test_case.setAttribute("result_kind", result)
174            test_case.setAttribute("message", error)
175            test_case.setAttribute("report", report)
176
177            test_suite = dom.createElement("testsuite")
178            test_suite.setAttribute("modulename", module_name)
179            test_suite.setAttribute("name", module_name)
180            test_suite.setAttribute("tests", str(1))
181            test_suite.setAttribute("disabled", '0')
182            test_suite.setAttribute("time", "{:.2f}".format(case_time))
183            test_suite.setAttribute("report", report)
184            if module_name not in test_suites:
185                test_suites[module_name] = {"test_suite": test_suite, "tests": 0, "failures": 0}
186                result_node.appendChild(test_suite)
187            test_suites[module_name]["test_suite"].appendChild(test_case)
188            test_suites[module_name]["tests"] += 1
189            tests = test_suites[module_name]["tests"]
190            if case_result == "false":
191                test_suites[module_name]["failures"] += 1
192            failures = test_suites[module_name]["failures"]
193            test_suites[module_name]["test_suite"].setAttribute("tests", str(tests))
194            test_suites[module_name]["test_suite"].setAttribute("failures", str(failures))
195        return tests_total, tests_error
196