1#!/usr/bin/env python3 2# coding: utf-8 3 4""" 5Copyright (c) 2023 Huawei Device Co., Ltd. 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17 18Description: utils for test suite 19""" 20 21import json 22import logging 23import os 24import shutil 25import time 26import subprocess 27import sys 28 29import gzip 30from PIL import Image 31 32 33def get_log_level(arg_log_level): 34 log_level_dict = { 35 'debug': logging.DEBUG, 36 'info': logging.INFO, 37 'warn': logging.WARN, 38 'error': logging.ERROR 39 } 40 if arg_log_level not in log_level_dict.keys(): 41 return logging.ERROR # use error as default log level 42 else: 43 return log_level_dict[arg_log_level] 44 45 46def init_logger(log_level, log_file): 47 logging.basicConfig(filename=log_file, 48 level=get_log_level(log_level), 49 encoding=get_encoding(), 50 format='[%(asctime)s %(filename)s:%(lineno)d]: [%(levelname)s] %(message)s') 51 logging.info("Test command:") 52 logging.info(" ".join(sys.argv)) 53 54 55def get_encoding(): 56 if is_windows(): 57 return 'utf-8' 58 else: 59 return sys.getfilesystemencoding() 60 61 62def is_windows(): 63 return sys.platform == 'win32' or sys.platform == 'cygwin' 64 65 66def is_mac(): 67 return sys.platform == 'darwin' 68 69 70def is_linux(): 71 return sys.platform == 'linux' 72 73 74def get_time_string(): 75 return time.strftime('%Y%m%d-%H%M%S') 76 77 78def is_esmodule(hap_type): 79 # if hap_type is stage, it's esmodule. 80 # if hap_type is js, fa, compatible 8, it's js_bundle 81 return 'stage' in hap_type 82 83 84def is_file_timestamps_same(file_a, file_b): 85 file_a_mtime = os.stat(file_a).st_mtime 86 file_b_mtime = os.stat(file_b).st_mtime 87 return file_a_mtime == file_b_mtime 88 89 90def add_executable_permission(file_path): 91 current_mode = os.stat(file_path).st_mode 92 new_mode = current_mode | 0o111 93 os.chmod(file_path, new_mode) 94 95 96def run_cmd(cmd): 97 subprocess.run(cmd, shell=False) 98 99 100def get_running_screenshot(task, image_name): 101 run_cmd(['hdc', 'shell', 'power-shell', 'wakeup;power-shell', 'setmode 602']) 102 run_cmd(['hdc', 'shell', 'uinput', '-T', '-m', '420', '1000', '420', 103 '400;uinput', '-T', '-m', '420', '400', '420', '1000']) 104 105 build_path = os.path.join(task.path, *task.build_path) 106 out_path = os.path.join(build_path, *task.output_hap_path_signed) 107 108 run_cmd(['hdc', 'install', f'{out_path}']) 109 run_cmd(['hdc', 'shell', 'aa', 'start', '-a', f'{task.ability_name}', '-b', f'{task.bundle_name}']) 110 time.sleep(3) 111 112 screen_path = f'/data/local/tmp/{image_name}.jpeg' 113 run_cmd(['hdc', 'shell', 'snapshot_display', '-f', f'{screen_path}']) 114 time.sleep(3) 115 116 run_cmd(['hdc', 'file', 'recv', f'{screen_path}', f'{image_name}.jpeg']) 117 run_cmd(['hdc', 'shell', 'aa', 'force-stop', f'{task.bundle_name}']) 118 run_cmd(['hdc', 'shell', 'bm', 'uninstall', '-n', f'{task.bundle_name}']) 119 120 pic_save_dic = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pictures') 121 if not os.path.exists(pic_save_dic): 122 os.mkdir(pic_save_dic) 123 124 pic_save_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), f'pictures\{task.name}') 125 if not os.path.exists(pic_save_path): 126 os.mkdir(pic_save_path) 127 128 shutil.move(f'{image_name}.jpeg', pic_save_path) 129 130 131def compare_screenshot(runtime_picture_path, picture_reference_path, threshold=0.95): 132 try: 133 runtime_picture = Image.open(runtime_picture_path).convert('RGB') 134 picture_reference_path = Image.open(picture_reference_path).convert('RGB') 135 except Exception: 136 logging.error(f'open image {runtime_picture_path} failed') 137 return False 138 runtime_picture.thumbnail((256, 256)) 139 picture_reference_path.thumbnail((256, 256)) 140 141 runtime_pixel = runtime_picture.load() 142 reference_pixel = picture_reference_path.load() 143 width, height = runtime_picture.size 144 145 similar_pixels = 0 146 total_pixels = width * height 147 148 for x in range(width): 149 for y in range(height): 150 if runtime_pixel[x, y] == reference_pixel[x, y]: 151 similar_pixels += 1 152 153 similarity = similar_pixels / total_pixels 154 155 if similarity >= threshold: 156 return True 157 else: 158 return False 159 160 161def verify_runtime(task, picture_name): 162 pic_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 163 f'pictures/{task.name}/{picture_name}.jpeg') 164 pic_path_reference = os.path.join(os.path.dirname(os.path.abspath(__file__)), 165 f'pictures_reference/{task.name}/{picture_name}.jpeg') 166 passed = compare_screenshot(pic_path, pic_path_reference, threshold=0.95) 167 if not passed: 168 logging.error(f'{task.name} get error when running') 169 return False 170 return True