#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Copyright (c) 2021 Huawei Device Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Description: Use ark to execute ts/js files """ import os import sys import re import glob import argparse import subprocess import signal import time import json DEFAULT_TIMEOUT = 300 DEFAULT_PGO_THRESHOLD = 10 TARGET_PLATFORM = ['x64', 'arm64'] PRODUCT_LIST = ['hispark_taurus', 'rk3568', 'baltimore'] TARGET_PRODUCT_MAP = {'x64': 0, 'arm64': 1} def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('name', metavar='file|path', type=str, help='test case name: file or path') parser.add_argument('-a', '--all', action='store_true', help='run all test cases on path') parser.add_argument('-p', '--product', metavar='name', help='product name, default is hispark_taurus on x64, rk3568 on arm64, baltimore on arm64') parser.add_argument('-t', '--tool', metavar='opt', help='run tool supported opt: aot, int(c interpreter tool), asmint(asm interpreter tool), node(v8), qjs, hermes') parser.add_argument('-f', '--frontend', metavar='opt', help='run frontend supported opt: ts2abc (slow), es2abc (quick not released)') parser.add_argument('-s', '--step', metavar='opt', help='run step supported opt: abc, pack, aot, aotd, run, rund, asmint, asmintd, int, intd') parser.add_argument('-d', '--debug', action='store_true', help='run on debug mode') parser.add_argument('--arm64', action='store_true', help='run on arm64 platform') parser.add_argument('--device', action='store_true', help='run on device') parser.add_argument('--copy-path', metavar='path', help='copy bins to device') parser.add_argument('-m', '--module', action='store_true', help='frontend compile with module') parser.add_argument('--frontend-args', metavar='args', help='pass to frontend args') parser.add_argument('--aot-args', metavar='args', help='pass to aot compiler args') parser.add_argument('--jsvm-args', metavar='args', help='pass to jsvm args') parser.add_argument('-i', '--info', action='store_true', help='add log level of info to args') parser.add_argument('-c', '--clean', action='store_true', help='clean output files') parser.add_argument('--npm', action='store_true', help='npm install') parser.add_argument('--bt', dest='builtin', action='store_true', help='aot compile with lib_ark_builtins.d.ts') parser.add_argument('--pgo', action='store_true', help=f'aot compile with pgo, default threshold is {DEFAULT_PGO_THRESHOLD}') parser.add_argument('--pgo-th', metavar='n', default=DEFAULT_PGO_THRESHOLD, type=int, help=f'pgo hotness threshold, default is {DEFAULT_PGO_THRESHOLD}') parser.add_argument('--sign', metavar='name', help='sign level, default is system_core, other is normal, system_basic') parser.add_argument('--timeout', metavar='n', default=DEFAULT_TIMEOUT, type=int, help=f'specify seconds of test timeout, default is {DEFAULT_TIMEOUT}') parser.add_argument('-e', '--env', action='store_true', help='print LD_LIBRARY_PATH') arguments = parser.parse_args() return arguments def run_and_print(cmd): print(cmd) os.system(cmd) def run_command(cmd, timeout=DEFAULT_TIMEOUT): proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) code_format = 'UTF-8' try: (msg, errs) = proc.communicate(timeout=timeout) ret_code = proc.poll() if errs: ret_code = 2 except subprocess.TimeoutExpired: proc.kill() proc.terminate() os.kill(proc.pid, signal.SIGTERM) return (1, '', f'exec command timeout {timeout}s') return (ret_code, msg.decode(code_format), errs.decode(code_format)) def match_list_name(list, name): for str in list: found = str.find(name) if (found == 0): return str return '' def get_module_name(hap_dir): with open(f'{hap_dir}/module.json') as f: data = json.load(f) if len(data): return data['module']['name'] else: return 'entry' def get_bundle_name(hap_dir): with open(f'{hap_dir}/module.json') as f: data = json.load(f) if len(data): return data['app']['bundleName'] else: return 'entry' class ArkTest(): def __init__(self, args): self.args = args self.self_dir = os.path.abspath(sys.argv[0]) self.hap_abc = 'ets/modules.abc' self.place_dir = 'arkcompiler/ets_runtime/test' if not args.device and self.self_dir.find(self.place_dir) < 0: print(f'pls place this script at: {self.place_dir}') sys.exit(1) self.ohdir = os.path.abspath(f'{self.self_dir}/../../../..') self.product = PRODUCT_LIST[TARGET_PRODUCT_MAP['x64']] self.builtin = '' if args.builtin: self.builtin = f'{self.ohdir}/arkcompiler/ets_runtime/ecmascript/ts_types/lib_ark_builtins.d' self.arm64 = False if args.step == 'hap': self.arm64 = True if args.arm64: self.product = PRODUCT_LIST[TARGET_PRODUCT_MAP['arm64']] self.arm64 = True if args.product: self.product = match_list_name(PRODUCT_LIST, args.product) self.step = 'all' if args.step: self.step = args.step if args.clean: self.step = 'clean' self.expect = 'expect_output.txt' search_type_list = ['.ts', '.js', '.abc'] self.types = {'all': ['.ts', '.js'], 'abc': ['.ts', '.js'], 'pack': ['.an'], 'aot': search_type_list, 'aotd': search_type_list, 'run': search_type_list, 'rund': search_type_list, 'asmint': search_type_list, 'asmintd': search_type_list, 'int': search_type_list, 'intd': search_type_list, 'clean': search_type_list} product_dir = f'{self.ohdir}/out/{self.product}' libs_dir_x64_release = (f'{self.ohdir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib:' f'{product_dir}/clang_x64/arkcompiler/ets_runtime:' f'{product_dir}/clang_x64/thirdparty/icu:' f'{product_dir}/clang_x64/thirdparty/zlib') libs_dir_x64_debug = (f'{self.ohdir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib:' f'{product_dir}/clang_x64/exe.unstripped/clang_x64/arkcompiler/ets_runtime:' f'{product_dir}/clang_x64/lib.unstripped/clang_x64/arkcompiler/ets_runtime:' f'{product_dir}/clang_x64/lib.unstripped/clang_x64/test/test:' f'{product_dir}/clang_x64/lib.unstripped/clang_x64/thirdparty/icu:' f'{product_dir}/clang_x64/lib.unstripped/clang_x64/thirdparty/zlib') libs_dir_arm64_release = (f'{self.ohdir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/aarch64-linux-ohos/c++/:' f'{product_dir}/arkcompiler/ets_runtime/:' f'{product_dir}/utils/utils_base/:' f'{product_dir}/thirdparty/icu:' f'{product_dir}/thirdparty/zlib:' f'{product_dir}/common/dsoftbus/:' f'{product_dir}/commonlibrary/c_utils:' f'{product_dir}/systemabilitymgr/samgr:' f'{product_dir}/hiviewdfx/hisysevent_native:' f'{product_dir}/common/common:' f'{product_dir}/securec/thirdparty_bounds_checking_function:' f'{product_dir}/hiviewdfx/faultloggerd:' f'{product_dir}/thirdparty/bounds_checking_function:' f'{product_dir}/hiviewdfx/hilog_native:' f'{product_dir}/startup/init:' f'{product_dir}/thirdparty/cjson:' f'{product_dir}/lib.unstripped/common/dsoftbus:' f'{product_dir}/security/selinux:' f'{product_dir}/hiviewdfx/hitrace_native/:' f'{product_dir}/communication/ipc/:' f'{product_dir}/distributedschedule/samgr_standard:' f'{product_dir}/security/access_token:' f'{product_dir}/communication/dsoftbus:' f'{product_dir}/startup/startup_l2/:' f'{product_dir}/security/huks/:' f'{product_dir}/clang_x64/thirdparty/icu:' f'{product_dir}/clang_x64/thirdparty/zlib:' f'{product_dir}/clang_x64/arkcompiler/ets_runtime') libs_dir_arm64_debug = (f'{self.ohdir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/aarch64-linux-ohos/c++/:' f'{product_dir}/lib.unstripped/arkcompiler/ets_runtime/:' f'{product_dir}/utils/utils_base/:' f'{product_dir}/thirdparty/icu:' f'{product_dir}/thirdparty/zlib:' f'{product_dir}/common/dsoftbus/:' f'{product_dir}/commonlibrary/c_utils:' f'{product_dir}/systemabilitymgr/samgr:' f'{product_dir}/hiviewdfx/hisysevent_native:' f'{product_dir}/common/common:' f'{product_dir}/securec/thirdparty_bounds_checking_function:' f'{product_dir}/hiviewdfx/faultloggerd:' f'{product_dir}/thirdparty/bounds_checking_function:' f'{product_dir}/hiviewdfx/hilog_native:' f'{product_dir}/startup/init:' f'{product_dir}/thirdparty/cjson:' f'{product_dir}/security/selinux:' f'{product_dir}/hiviewdfx/hitrace_native/:' f'{product_dir}/communication/ipc/:' f'{product_dir}/distributedschedule/samgr_standard:' f'{product_dir}/security/access_token:' f'{product_dir}/communication/dsoftbus:' f'{product_dir}/startup/startup_l2/:' f'{product_dir}/security/huks/:' f'{product_dir}/clang_x64/thirdparty/icu/:' f'{product_dir}/clang_x64/thirdparty/zlib/:' f'{product_dir}/clang_x64/arkcompiler/ets_runtime') libs_dir = [[libs_dir_x64_release, libs_dir_x64_debug], [libs_dir_arm64_release, libs_dir_arm64_debug]] bins_dir = [['clang_x64/arkcompiler', 'clang_x64/exe.unstripped/clang_x64/arkcompiler'], ['arkcompiler', 'exe.unstripped/arkcompiler']] icu_arg = f'--icu-data-path={self.ohdir}/third_party/icu/ohos_icu4j/data' self.libs_dir = libs_dir[self.arm64][args.debug] self.compiler = f'{product_dir}/{bins_dir[0][args.debug]}/ets_runtime/ark_aot_compiler' self.jsvm = f'{product_dir}/{bins_dir[self.arm64][args.debug]}/ets_runtime/ark_js_vm' self.ts2abc = f'node --expose-gc {product_dir}/clang_x64/arkcompiler/ets_frontend/build/src/index.js' self.es2abc = f'{product_dir}/clang_x64/arkcompiler/ets_frontend/es2abc' self.frontend = self.ts2abc if not args.frontend: args.frontend = 'ts2abc' if args.frontend not in ['ts2abc', 'es2abc']: print(f'not supported frontend: {args.frontend}') sys.exit(1) if args.frontend == 'es2abc': self.frontend = self.es2abc abcmode = {'ts2abc': ['--merge-abc', '--merge-abc -m'], 'es2abc': ['--merge-abc', '--merge-abc --module']} self.abcmode = abcmode[args.frontend][args.module] self.frontend_args = '' self.aot_args = '' self.jsvm_args = icu_arg if args.device: self.jsvm_args = '' if self.builtin: self.aot_args = f'{self.aot_args} --builtins-dts={self.builtin}.abc' self.pgo = False if args.pgo: self.pgo = True self.aot_args = (f'{self.aot_args} --enable-pgo-profiler=true --compiler-pgo-hotness-threshold={args.pgo_th}' f' --compiler-pgo-profiler-path=pgo_file_name.ap') if args.frontend_args: self.frontend_args = f'{self.frontend_args} {args.frontend_args}' if args.aot_args: self.aot_args = f'{self.aot_args} {args.aot_args}' if args.jsvm_args: self.jsvm_args = f'{self.jsvm_args} {args.jsvm_args}' if args.info: self.aot_args = f'{self.aot_args} --log-level=info' self.jsvm_args = f'{self.jsvm_args} --log-level=info' self.runner = '' self.runnerd = 'gdb --args' if self.arm64 or args.device: if self.step[:3] != 'aot': self.runner = 'qemu-aarch64' self.runnerd = 'qemu-aarch64 -cpu max,sve=off -g 123456' self.aot_args = f'{self.aot_args} --compiler-target-triple=aarch64-unknown-linux-gnu' self.test_count = 0 self.fail_cases = [] os.environ['LD_LIBRARY_PATH'] = self.libs_dir if args.env: print(f'export LD_LIBRARY_PATH={self.libs_dir}') sys.exit(0) if args.copy_path: run_and_print(f'hdc shell mount -o remount,rw /') run_and_print(f'hdc file send {args.copy_path}\\ark_aot_compiler /system/bin/') run_and_print(f'hdc shell chmod a+x /system/bin/ark_aot_compiler') run_and_print(f'hdc file send {args.copy_path}\\ark_js_vm /system/bin/') run_and_print(f'hdc shell chmod a+x /system/bin/ark_js_vm') sys.exit(0) if args.npm: index_dir = f'{product_dir}/clang_x64/arkcompiler/ets_frontend/build/src' os.system(f'cd {index_dir}/.. && npm install') sys.exit(0) if args.sign: self.sign_hap(self.args.name) sys.exit(0) def run_cmd(self, cmd): print(cmd) ret = run_command(cmd, self.args.timeout) if ret[0]: print(ret[2]) return ret def run_test(self, file): self.test_count += 1 basename = os.path.basename(f'{file}') type = os.path.splitext(basename)[-1] name = os.path.splitext(basename)[0] dir = os.path.dirname(file) out_case_dir = f'{dir}' hap_dir = 'null' hap_name = 'null' module_name = 'null' if self.step == 'hap' or self.step == 'pack': hap_dir = os.path.abspath(f'{out_case_dir}/..') hap_name = os.path.basename(hap_dir) module_name = get_module_name(hap_dir) abc_file = f'{os.path.splitext(file)[0]}.abc' if self.pgo: pgo_file = f'{hap_dir}/ap/{module_name}' self.aot_args = self.aot_args.replace('pgo_file_name', pgo_file) cmd_map = { 'node': f'node {self.frontend_args} {file}', 'qjs': f'qjs {self.frontend_args} {file}', 'hermes': f'hermes {self.frontend_args} {file}', 'abc': f'{self.frontend} {self.frontend_args} {self.abcmode} --output {abc_file} {file}', 'pack': [f'mkdir -p {out_case_dir}/../an/arm64-v8a', f'mv {out_case_dir}/{name}.an {hap_dir}/an/arm64-v8a/{module_name}.an', f'mv {out_case_dir}/{name}.ai {hap_dir}/an/arm64-v8a/{module_name}.ai', f'cd {out_case_dir}/.. && rm -f ../{hap_name}.hap && zip -r -q ../{hap_name}.hap *', f'mv {hap_dir}/an/arm64-v8a/{module_name}.an {out_case_dir}/{name}.an', f'mv {hap_dir}/an/arm64-v8a/{module_name}.ai {out_case_dir}/{name}.ai', f'rm -rf {hap_dir}/an'], 'aot': f'{self.compiler} {self.aot_args} --aot-file={out_case_dir}/{name} {abc_file}', 'aotd': f'{self.runnerd} {self.compiler} {self.aot_args} --aot-file={out_case_dir}/{name} {abc_file}', 'run': f'{self.runner} {self.jsvm} {self.jsvm_args} --aot-file={out_case_dir}/{name} --entry-point={name} {abc_file}', 'rund': f'{self.runnerd} {self.jsvm} {self.jsvm_args} --aot-file={out_case_dir}/{name} --entry-point={name} {abc_file}', 'asmint': f'{self.runner} {self.jsvm} {self.jsvm_args} --entry-point={name} {abc_file}', 'asmintd': f'{self.runnerd} {self.jsvm} {self.jsvm_args} --entry-point={name} {abc_file}', 'int': f'{self.runner} {self.jsvm} {self.jsvm_args} --asm-interpreter=0 --entry-point={name} {abc_file}', 'intd': f'{self.runnerd} {self.jsvm} {self.jsvm_args} --asm-interpreter=0 --entry-point={name} {abc_file}', 'clean': f'rm -f {out_case_dir}/{name}.abc {out_case_dir}/{name}.an {out_case_dir}/{name}.ai', 'cleanhap': f'rm -rf {hap_dir}/an {out_case_dir}/{name}.an {out_case_dir}/{name}.ai'} if self.builtin: if self.frontend == self.ts2abc: cmd = f'{self.ts2abc} {self.builtin}.ts -m --merge-abc -q -b' elif self.frontend == self.es2abc: cmd = (f'{self.es2abc} --module --merge-abc --extension=ts --type-extractor --type-dts-builtin ' f'--output={self.builtin}.abc {self.builtin}.ts') print(cmd) os.system(cmd) if self.step == 'hap': self.step = 'aot' perf_start = time.perf_counter() cmd = cmd_map[self.step] print(cmd) os.system(cmd) perf_end = time.perf_counter() abc_size = os.path.getsize(file) / 1024 / 1024 an_size = os.path.getsize(f'{out_case_dir}/{name}.an') / 1024 / 1024 print(f'test: {file} abc_size: {abc_size: .1f}MB an_size: {an_size:.1f}MB ' f'expand: {an_size / abc_size: .1f} time: {perf_end - perf_start: .1f}s') self.step = 'pack' if self.step == 'pack': for cmd in cmd_map[self.step]: print(cmd) os.system(cmd) print(f'packed hap: {hap_name}.hap') print(f'sign --------------------------------------------') self.sign_hap(f'{hap_name}.hap') return if self.step == 'clean': if os.path.isfile(f'{hap_dir}/{self.hap_abc}'): self.step = 'cleanhap' if self.args.tool == 'node': ret = self.run_cmd(cmd_map['node']) self.judge_test(file, ret) return if self.args.tool == 'qjs': ret = self.run_cmd(cmd_map['qjs']) self.judge_test(file, ret) return if self.args.tool == 'hermes': ret = self.run_cmd(cmd_map['hermes']) self.judge_test(file, ret) return if not self.args.tool: self.args.tool = 'aot' if self.args.tool not in ['aot', 'asmint', 'int']: print(f'not supported tool: {self.args.tool}') sys.exit(1) if self.args.device: ret = self.run_test_on_device(file) return if self.step != 'all': # gdb should use the os.system cmd = cmd_map[self.step] print(cmd) if self.arm64 and self.step[-1:] == 'd' and self.step[:3] != 'aot': print(f'gdb-client start: gdb-multiarch {self.jsvm}') print(f'gdb-server connect: target remote:123456') os.system(cmd) return ret = self.run_cmd(cmd_map['abc']) if ret[0]: self.judge_test(file, ret) return if self.args.tool == 'aot': ret = self.run_cmd(cmd_map['aot']) if ret[0] and ret[2].find('aot compile success') < 0: self.judge_test(file, ret) return ret = self.run_cmd(cmd_map['run']) else: ret = self.run_cmd(cmd_map[self.args.tool]) self.judge_test(file, ret) def run_test_on_device(self, file): basename = os.path.basename(f'{file}') name = os.path.splitext(basename)[0] out_case_dir = '/data/test' send_abc_file = f'{os.path.splitext(file)[0]}.abc'.replace('/', '\\') abc_file = f'{out_case_dir}/{name}.abc' cmd_map = {'abc': f'hdc file send {send_abc_file} {out_case_dir}/', 'aot': f'hdc shell ark_aot_compiler {self.aot_args} --aot-file={out_case_dir}/{name} {abc_file}', 'run': f'hdc shell ark_js_vm {self.jsvm_args} --aot-file={out_case_dir}/{name} --entry-point={name} {abc_file}', 'asmint': f'hdc shell ark_js_vm {self.jsvm_args} --entry-point={name} {abc_file}', 'int': f'hdc shell ark_js_vm {self.jsvm_args} --asm-interpreter=0 --entry-point={name} {abc_file}'} if self.step != 'all': run_and_print(cmd_map[self.step]) return run_and_print(cmd_map['abc']) if self.args.tool == 'aot': ret = self.run_cmd(cmd_map['aot']) if ret[0] and ret[2].find('aot compile success') < 0: self.judge_test(file, ret) return ret = self.run_cmd(cmd_map['run']) else: ret = self.run_cmd(cmd_map[self.args.tool]) self.judge_test(file, ret) def judge_test(self, file, out): if out[0]: self.fail_cases.append(file) print_fail(f'FAIL: {file}') return expect_file = f'{os.path.dirname(file)}/{self.expect}' if os.path.exists(expect_file): with open(expect_file, mode='r') as infile: expect = ''.join(infile.readlines()[13:]) if out[1].replace('\r', '') != expect.replace('\r', ''): self.fail_cases.append(file) print(f'expect: [{expect}]\nbut got: [{out[1]}]') print_fail(f'FAIL: {file}') else: print_pass(f'PASS: {file}') else: print_pass(f'PASS: {file}') print(out[1]) def report_test(self): fail_count = len(self.fail_cases) print(f'Ran tests: {self.test_count}') print(f'Ran failed: {fail_count}') if fail_count == 0: print_pass('================================== All tests Run PASSED!') return print_fail('==================================') for case in self.fail_cases: print(case) print_fail('==================================') def find_file(self, dir, postfix_list): result = [] for root, lists, files in os.walk(dir): for file in files: for postfix in postfix_list: path = os.path.join(root, file) found = path.find(postfix) if found == len(path) - len(postfix): result.append(path) if os.path.isfile(dir): for postfix in postfix_list: found = dir.find(postfix) if found == len(dir) - len(postfix): result.append(dir) break return result def test_hap(self): if self.step != 'all': return 1 files = self.find_file(self.args.name, [self.hap_abc, '.hap']) if len(files): self.step = 'hap' file = files[0] type = os.path.splitext(file)[-1] if type == '.hap': hap_dir = f'{os.path.splitext(file)[0]}.aot' os.system(f'mkdir -p {hap_dir} && unzip -o -q {file} -d {hap_dir}') file = f'{hap_dir}/{self.hap_abc}' self.run_test(file) return 0 return 1 def sign_hap(self, hap_name): name = os.path.splitext(hap_name)[0] sign_dir = f'{name}.sign' sign_tool_dir = f'{self.ohdir}/developtools/hapsigner/dist' name = os.path.splitext(sign_dir)[0] self_dir = os.path.abspath(sys.argv[0]) os.system(f'mkdir -p {sign_dir} && unzip -o -q {hap_name} module.json -d {sign_dir}') bundle_name = get_bundle_name(sign_dir) if not self.args.sign or self.args.sign == 'system_core': bundle_apl = 'system_core' bundle_feature = 'hos_system_app' elif self.args.sign == 'system_basic': bundle_apl = self.args.sign bundle_feature = 'hos_system_app' elif self.args.sign == 'normal': bundle_apl = self.args.sign bundle_feature = 'hos_normal_app' else: print(f'sign not supported input: {self.args.sign}') return 1 # modify sign config data_load = [] data_save = [] sign_config = 'UnsgnedReleasedProfileTemplate.json' with open(f'{sign_tool_dir}/{sign_config}') as f: data_load = json.load(f) data_load['bundle-info']['bundle-name'] = bundle_name data_load['bundle-info']['apl'] = bundle_apl data_load['bundle-info']['app-feature'] = bundle_feature data_save = json.dumps(data_load) with open(f'{sign_dir}/{sign_config}', 'w+') as f: f.write(data_save) # generate cert and sign gen_cert = f'java -jar {sign_tool_dir}/hap-sign-tool.jar sign-profile -keyAlias "openharmony application profile release" -signAlg "SHA256withECDSA" -mode "localSign" -profileCertFile "{sign_tool_dir}/OpenHarmonyProfileRelease.pem" -inFile "{sign_dir}/{sign_config}" -keystoreFile "{sign_tool_dir}/OpenHarmony.p12" -outFile "{sign_dir}/openharmony.p7b" -keyPwd "123456" -keystorePwd "123456"' sign_hap = f'java -jar {sign_tool_dir}/hap-sign-tool.jar sign-app -keyAlias "openharmony application release" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "{sign_tool_dir}/OpenHarmonyApplication.pem" -profileFile "{sign_dir}/openharmony.p7b" -inFile "{hap_name}" -keystoreFile "{sign_tool_dir}/OpenHarmony.p12" -outFile "{name}.sign.hap" -keyPwd "123456" -keystorePwd "123456"' print(gen_cert) print(sign_hap) os.system(gen_cert) os.system(sign_hap) print(f'signed of {bundle_apl} for hap: {name}.sign.hap') def test(self): # run single test by name files = [] if self.step not in self.types: print(f'not supported step: {self.step}') return 1 if not self.args.all: files = self.find_file(self.args.name, self.types[self.step]) if len(files): self.run_test(files[0]) elif self.test_hap(): print(f'only support file type: {self.types[self.step]}') print(f'input path no test case: {self.args.name}') return 1 return 0 # run all test in path if not os.path.isdir(self.args.name): print(f'input path not exists or is file: {self.args.name}') return 1 files = self.find_file(self.args.name, self.types[self.step]) for test in files: self.run_test(test) if len(files) == 0: self.test_hap() if self.step == 'clean': print('clean output files finished') return 0 if self.test_count == 0: print(f'input path no test case: {self.args.name}') return 1 # output report self.report_test() return 0 def print_pass(str): print(f'\033[32;2m{str}\033[0m') sys.stdout.flush() def print_fail(str): print(f'\033[31;2m{str}\033[0m') sys.stdout.flush() def main(): args = parse_args() arktest = ArkTest(args) return arktest.test() if __name__ == '__main__': sys.exit(main())