1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021 Huawei Device Co., Ltd. 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 16import sys 17import os 18import argparse 19import shutil 20import xml.etree.ElementTree as ET 21sys.path.append( 22 os.path.dirname(os.path.dirname(os.path.dirname( 23 os.path.abspath(__file__))))) 24from scripts.util.file_utils import write_json_file # noqa: E402 25from scripts.util import build_utils # noqa: E402 26 27 28def copy_dir(src: str, dest: str): 29 if not os.path.exists(src): 30 raise Exception("src dir '{}' doesn't exist.".format(src)) 31 if not os.path.exists(dest): 32 os.makedirs(dest, exist_ok=True) 33 src_files = [] 34 for root, _, files in os.walk(src): 35 for _file in files: 36 file_path = os.path.join(root, _file) 37 src_files.append(file_path) 38 for src_path in src_files: 39 if os.path.islink(src_path): 40 continue 41 file_relpath = os.path.relpath(src_path, src) 42 dest_path = os.path.join(dest, file_relpath) 43 dest_dir = os.path.dirname(dest_path) 44 if not os.path.exists(dest_dir): 45 os.makedirs(dest_dir, exist_ok=True) 46 shutil.copy2(src_path, dest_path) 47 return 0 48 49 50def _resources_with_xml_v1(root, testcase_target_name: str, test_resource_path: str, 51 part_build_out_path: str, resource_output_path: str): 52 _out_resources_list = [] 53 for target in root: 54 if target.attrib.get('name') != testcase_target_name: 55 continue 56 for _depend in target: 57 _findpath = _depend.attrib.get('findpath') 58 _resource_file = _depend.attrib.get('resource') 59 if _findpath == 'res': 60 _resource_src = os.path.join(test_resource_path, 61 _resource_file) 62 _res_dest = os.path.join(resource_output_path, _resource_file) 63 elif _findpath == 'out': 64 if not os.path.exists(_resource_file): 65 __dir_name = _resource_file.split('/')[0] 66 _resource_file_new = os.path.join(__dir_name, 67 _resource_file) 68 _resource_src_new = os.path.join(part_build_out_path, 69 _resource_file_new) 70 if os.path.exists(_resource_src_new): 71 _resource_src = _resource_src_new 72 _res_dest = os.path.join(resource_output_path, 73 _resource_file) 74 else: 75 _resource_src = '' 76 _res_dest = '' 77 else: 78 _resource_src = os.path.join(part_build_out_path, 79 _resource_file) 80 _res_dest = os.path.join(resource_output_path, 81 _resource_file) 82 else: 83 raise Exception( 84 "resource findpath type '{}' not support.".format( 85 _findpath)) 86 if _resource_src: 87 _out_resources_list.append({ 88 "src": 89 os.path.relpath(_resource_src), 90 "dest": 91 os.path.relpath(_res_dest) 92 }) 93 return _out_resources_list 94 95 96def _parse_res_value(value: str): 97 res_file = value.split('->')[0].strip() 98 return res_file 99 100 101def _resources_with_xml_v2(root, testcase_target_name: str, test_resource_path: str, 102 part_build_out_path: str, resource_output_path: str): 103 _out_resources_list = [] 104 for target in root: 105 if target.attrib.get('name') != testcase_target_name: 106 continue 107 for child in target: 108 if child.tag != 'preparer': 109 continue 110 for _option in child: 111 if _option.attrib.get('name') != 'push': 112 continue 113 _src_type = _option.attrib.get('src') 114 _resource_file_val = _option.attrib.get('value') 115 _resource_file = _parse_res_value(_resource_file_val) 116 if _src_type == 'res': 117 _resource_src = os.path.join(test_resource_path, 118 _resource_file) 119 _res_dest = os.path.join(resource_output_path, 120 _resource_file) 121 elif _src_type == 'out': 122 _resource_src = os.path.join(part_build_out_path, 123 _resource_file) 124 _res_dest = os.path.join(resource_output_path, 125 _resource_file) 126 else: 127 raise Exception( 128 "resource src type '{}' not support.".format( 129 _src_type)) 130 if _resource_src: 131 _out_resources_list.append({ 132 "src": 133 os.path.relpath(_resource_src), 134 "dest": 135 os.path.relpath(_res_dest) 136 }) 137 return _out_resources_list 138 139 140def find_testcase_resources(resource_config_file: str, testcase_target_name: str, 141 test_resource_path: str, part_build_out_path: str, 142 resource_output_path: str): 143 if not os.path.exists(resource_config_file): 144 return [] 145 tree = ET.parse(resource_config_file) 146 root = tree.getroot() 147 if root.attrib.get('ver') == '2.0': 148 _resources_list = _resources_with_xml_v2(root, testcase_target_name, 149 test_resource_path, 150 part_build_out_path, 151 resource_output_path) 152 else: 153 _resources_list = _resources_with_xml_v1(root, testcase_target_name, 154 test_resource_path, 155 part_build_out_path, 156 resource_output_path) 157 # copy ohos_test.xml 158 _resources_list.append({ 159 "src": 160 resource_config_file, 161 "dest": 162 os.path.join(resource_output_path, 163 os.path.basename(resource_config_file)) 164 }) 165 return _resources_list 166 167 168def copy_testcase_resources(resource_infos: dict): 169 for resource_info in resource_infos: 170 src_file = resource_info.get('src') 171 if not os.path.exists(src_file): 172 print("warning: testcase resource {} doesn't exist.".format( 173 src_file)) 174 return 0 175 dest_file = resource_info.get('dest') 176 dest_dir = os.path.dirname(dest_file) 177 if os.path.isdir(src_file): 178 copy_dir(src_file, dest_file) 179 else: 180 if not os.path.exists(dest_dir): 181 os.makedirs(dest_dir, exist_ok=True) 182 shutil.copy2(src_file, dest_file) 183 return 0 184 185 186def main(): 187 parser = argparse.ArgumentParser() 188 parser.add_argument('--resource-config-file', required=False) 189 parser.add_argument('--testcase-target-name', required=True) 190 parser.add_argument('--part-build-out-path', required=True) 191 parser.add_argument('--resource-output-path', required=True) 192 parser.add_argument('--output-file', required=True) 193 args = parser.parse_args() 194 if not args.resource_config_file: 195 return 0 196 else: 197 resource_config_file = args.resource_config_file 198 if not os.path.exists(resource_config_file): 199 raise Exception( 200 "testcase '{}' resource_config_file config incorrect.".format( 201 args.testcase_target_name)) 202 203 test_resource_path = os.path.dirname(resource_config_file) 204 resources_list = find_testcase_resources(resource_config_file, 205 args.testcase_target_name, 206 test_resource_path, 207 args.part_build_out_path, 208 args.resource_output_path) 209 write_json_file(args.output_file, resources_list) 210 copy_testcase_resources(resources_list) 211 return 0 212 213 214if __name__ == '__main__': 215 sys.exit(main()) 216