1# 2# Copyright (C) 2018 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17import logging 18import os 19 20from xml.etree import ElementTree 21 22from host_controller import common 23 24 25def ExtractResultZip(zip_file, output_dir, xml_only=True): 26 """Extracts XML result from a zip file. 27 28 Args: 29 zip_file: An object of zipfile.ZipFile. 30 output_dir: The directory where the zip is extracted. 31 xml_only: Whether to extract log-result.xml or test_result.xml only. 32 33 Returns: 34 The path to the XML in the output directory. 35 None if the zip does not contain the XML result. 36 """ 37 try: 38 xml_name = next(x for x in zip_file.namelist() if 39 x.endswith(common._TEST_RESULT_XML) or 40 x.endswith(common._LOG_RESULT_XML)) 41 except StopIteration: 42 return None 43 44 if not os.path.exists(output_dir): 45 os.makedirs(output_dir) 46 if xml_only: 47 return zip_file.extract(xml_name, path=output_dir) 48 else: 49 zip_file.extractall(path=output_dir) 50 return os.path.join(output_dir, xml_name) 51 52 53def LoadTestSummary(result_xml): 54 """Gets attributes of <Result>, <Build>, and <Summary>. 55 56 Args: 57 result_xml: A file object of the TradeFed report in XML format. 58 59 Returns: 60 3 dictionaries, the attributes of <Result>, <Build>, and <Summary>. 61 """ 62 result_attrib = {} 63 build_attrib = {} 64 summary_attrib = {} 65 for event, elem in ElementTree.iterparse(result_xml, events=("start", )): 66 if all((result_attrib, build_attrib, summary_attrib)): 67 break 68 if elem.tag == common._RESULT_TAG: 69 result_attrib = dict(elem.attrib) 70 elif elem.tag == common._BUILD_TAG: 71 build_attrib = dict(elem.attrib) 72 elif elem.tag == common._SUMMARY_TAG: 73 summary_attrib = dict(elem.attrib) 74 return result_attrib, build_attrib, summary_attrib 75 76 77def IterateTestResults(result_xml): 78 """Yields test records in test_result.xml. 79 80 Args: 81 result_xml: A file object of the TradeFed report in XML format. 82 83 Yields: 84 A tuple of ElementTree.Element, (Module, TestCase, Test) for each 85 </Test>. 86 """ 87 module_elem = None 88 testcase_elem = None 89 for event, elem in ElementTree.iterparse( 90 result_xml, events=("start", "end")): 91 if event == "start": 92 if elem.tag == common._MODULE_TAG: 93 module_elem = elem 94 elif elem.tag == common._TESTCASE_TAG: 95 testcase_elem = elem 96 97 if event == "end" and elem.tag == common._TEST_TAG: 98 yield module_elem, testcase_elem, elem 99 100 101def GetAbiBitness(abi): 102 """Gets bitness of an ABI. 103 104 Args: 105 abi: A string, the ABI name. 106 107 Returns: 108 32 or 64, the ABI bitness. 109 """ 110 return 64 if "arm64" in abi or "x86_64" in abi else 32 111 112 113def GetTestName(module, testcase, test): 114 """Gets the bitness and the full test name. 115 116 Args: 117 module: The Element for <Module>. 118 testcase: The Element for <TestCase>. 119 test: The Element for <Test>. 120 121 Returns: 122 A tuple of (bitness, module_name, testcase_name, test_name). 123 """ 124 abi = module.attrib.get(common._ABI_ATTR_KEY, "") 125 bitness = str(GetAbiBitness(abi)) 126 module_name = module.attrib.get(common._NAME_ATTR_KEY, "") 127 testcase_name = testcase.attrib.get(common._NAME_ATTR_KEY, "") 128 test_name = test.attrib.get(common._NAME_ATTR_KEY, "") 129 return bitness, module_name, testcase_name, test_name 130