1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from functools import cached_property 18from os import path 19from typing import Dict, Optional, Union, Any 20 21from runner.enum_types.qemu import QemuKind 22from runner.enum_types.verbose_format import VerboseKind, VerboseFilter 23from runner.options.decorator_value import value, _to_qemu, _to_bool, _to_enum, _to_str, _to_path, _to_int, \ 24 _to_processes 25from runner.options.options_coverage import CoverageOptions 26 27 28# pylint: disable=too-many-public-methods 29class GeneralOptions: 30 __DEFAULT_PROCESSES = 1 31 __DEFAULT_CHUNKSIZE = 32 32 __DEFAULT_GC_TYPE = "g1-gc" 33 __DEFAULT_GC_BOMBING_FREQUENCY = 0 34 __DEFAULT_HEAP_VERIFIER = "fail_on_verification" 35 __DEFAULT_VERBOSE = VerboseKind.NONE 36 __DEFAULT_VERBOSE_FILTER = VerboseFilter.NEW_FAILURES 37 __DEFAULT_QEMU = QemuKind.NONE 38 __DEFAULT_GDB_TIMEOUT = 10 39 __DEFAULT_HANDLE_TIMEOUT = False 40 41 def __str__(self) -> str: 42 return _to_str(self, 1) 43 44 @property 45 def qemu_cmd_line(self) -> str: 46 qemu = '' 47 if self.qemu == QemuKind.ARM64: 48 qemu = '--arm64-qemu' 49 elif self.qemu == QemuKind.ARM32: 50 qemu = '--arm32-qemu' 51 return qemu 52 53 @staticmethod 54 def __to_cli_with_default( 55 option_name: str, 56 option_value: Optional[Any], 57 default_value: Optional[Any] = None) -> str: 58 return f"{option_name}={option_value}" if option_value != default_value else "" 59 60 @staticmethod 61 def __to_cli( 62 option_name: str, 63 option_value: Optional[Union[str, bool]]) -> str: 64 return f"{option_name}={option_value}" if option_value else "" 65 66 @cached_property 67 def chunksize(self) -> int: 68 return GeneralOptions.__DEFAULT_CHUNKSIZE 69 70 @cached_property 71 def static_core_root(self) -> str: 72 # This file is expected to be located at path: 73 # $PANDA_SOURCE/tests/tests-u-runner/runner/options/options_general.py 74 path_parts = __file__.split(path.sep)[:-5] 75 return path.sep.join(path_parts) 76 77 @cached_property 78 @value(yaml_path="general.generate-config", cli_name="generate_config", cast_to_type=_to_path) 79 def generate_config(self) -> Optional[str]: 80 return None 81 82 @cached_property 83 @value(yaml_path="general.processes", cli_name="processes", cast_to_type=_to_processes) 84 def processes(self) -> int: 85 return GeneralOptions.__DEFAULT_PROCESSES 86 87 @cached_property 88 @value(yaml_path="general.build", cli_name="build_dir", cast_to_type=_to_path, required=True) 89 def build(self) -> Optional[str]: 90 return None 91 92 @cached_property 93 @value(yaml_path="general.test-root", cli_name="test_root", cast_to_type=_to_path) 94 def test_root(self) -> Optional[str]: 95 return None 96 97 @cached_property 98 @value(yaml_path="general.list-root", cli_name="list_root", cast_to_type=_to_path) 99 def list_root(self) -> Optional[str]: 100 return None 101 102 @cached_property 103 @value(yaml_path="general.work-dir", cli_name="work_dir", cast_to_type=_to_path) 104 def work_dir(self) -> Optional[str]: 105 return None 106 107 @cached_property 108 @value(yaml_path="general.ets-stdlib-root", cli_name="ets_stdlib_root", cast_to_type=_to_path) 109 def ets_stdlib_root(self) -> Optional[str]: 110 return None 111 112 @cached_property 113 @value(yaml_path="general.show-progress", cli_name="progress", cast_to_type=_to_bool) 114 def show_progress(self) -> bool: 115 return False 116 117 @cached_property 118 @value(yaml_path="general.gc_type", cli_name="gc_type") 119 def gc_type(self) -> str: 120 return GeneralOptions.__DEFAULT_GC_TYPE 121 122 @cached_property 123 @value(yaml_path="general.full-gc-bombing-frequency", cli_name="full_gc_bombing_frequency", cast_to_type=_to_int) 124 def full_gc_bombing_frequency(self) -> int: 125 return GeneralOptions.__DEFAULT_GC_BOMBING_FREQUENCY 126 127 @cached_property 128 @value(yaml_path="general.run_gc_in_place", cli_name="run_gc_in_place", cast_to_type=_to_bool) 129 def run_gc_in_place(self) -> bool: 130 return False 131 132 @cached_property 133 @value(yaml_path="general.heap-verifier", cli_name="heap_verifier") 134 def heap_verifier(self) -> str: 135 return GeneralOptions.__DEFAULT_HEAP_VERIFIER 136 137 @cached_property 138 @value( 139 yaml_path="general.verbose", 140 cli_name="verbose", 141 cast_to_type=lambda x: _to_enum(x, VerboseKind) 142 ) 143 def verbose(self) -> VerboseKind: 144 return GeneralOptions.__DEFAULT_VERBOSE 145 146 @cached_property 147 @value( 148 yaml_path="general.verbose-filter", 149 cli_name="verbose_filter", 150 cast_to_type=lambda x: _to_enum(x, VerboseFilter) 151 ) 152 def verbose_filter(self) -> VerboseFilter: 153 return GeneralOptions.__DEFAULT_VERBOSE_FILTER 154 155 @cached_property 156 @value(yaml_path="general.force-download", cli_name="force_download", cast_to_type=_to_bool) 157 def force_download(self) -> bool: 158 return False 159 160 @cached_property 161 @value(yaml_path="general.bco", cli_name="bco", cast_to_type=_to_bool) 162 def bco(self) -> bool: 163 return True 164 165 @cached_property 166 @value(yaml_path="general.with_js", cli_name="with_js", cast_to_type=_to_bool) 167 def with_js(self) -> bool: 168 return True 169 170 @cached_property 171 @value(yaml_path="general.qemu", cli_name=["arm64_qemu", "arm32_qemu"], cast_to_type=_to_qemu) 172 def qemu(self) -> QemuKind: 173 return GeneralOptions.__DEFAULT_QEMU 174 175 @cached_property 176 @value(yaml_path="general.generate-only", cli_name="generate_only", cast_to_type=_to_bool) 177 def generate_only(self) -> bool: 178 return False 179 180 @cached_property 181 @value(yaml_path="general.gdb-timeout", cli_name="gdb_timeout", cast_to_type=_to_int) 182 def gdb_timeout(self) -> int: 183 return self.__DEFAULT_GDB_TIMEOUT 184 185 @cached_property 186 @value(yaml_path="general.handle-timeout", cli_name="handle_timeout", cast_to_type=_to_bool) 187 def handle_timeout(self) -> bool: 188 return self.__DEFAULT_HANDLE_TIMEOUT 189 190 coverage = CoverageOptions() 191 192 def get_command_line(self) -> str: 193 options = [ 194 f'--build-dir="{self.build}"', 195 self.__to_cli('--generate-config', self.generate_config), 196 self.__to_cli_with_default('--processes', self.processes, GeneralOptions.__DEFAULT_PROCESSES), 197 self.__to_cli_with_default('--chunksize', self.chunksize, GeneralOptions.__DEFAULT_CHUNKSIZE), 198 self.__to_cli('--test-root', self.test_root), 199 self.__to_cli('--list-root', self.list_root), 200 self.__to_cli('--work-dir', self.work_dir), 201 self.__to_cli('--ets-stdlib-root', self.ets_stdlib_root), 202 self.__to_cli('--show-progress', self.show_progress), 203 self.__to_cli_with_default('--gc-type', self.gc_type, GeneralOptions.__DEFAULT_GC_TYPE), 204 self.__to_cli_with_default('--full-gc-bombing-frequency', self.full_gc_bombing_frequency, 205 GeneralOptions.__DEFAULT_GC_BOMBING_FREQUENCY), 206 self.__to_cli('--no-run-gc-in-place', self.run_gc_in_place), 207 self.__to_cli_with_default('--heap-verifier', self.heap_verifier, 208 GeneralOptions.__DEFAULT_HEAP_VERIFIER), 209 self.__to_cli_with_default('--verbose', self.verbose, GeneralOptions.__DEFAULT_VERBOSE), 210 self.__to_cli_with_default('--verbose-filter', self.verbose_filter, 211 GeneralOptions.__DEFAULT_VERBOSE_FILTER), 212 self.__to_cli('--force-download', self.force_download), 213 self.__to_cli('--no-bco', not self.bco), 214 self.__to_cli('--no-js', not self.with_js), 215 self.__to_cli('--generate-only', self.generate_only), 216 self.qemu_cmd_line, 217 self.__to_cli_with_default('--gdb-timeout', self.gdb_timeout, 218 GeneralOptions.__DEFAULT_GDB_TIMEOUT), 219 self.__to_cli_with_default('--handle-timeout', self.handle_timeout, 220 GeneralOptions.__DEFAULT_HANDLE_TIMEOUT), 221 self.coverage.get_command_line(), 222 ] 223 return ' '.join(options) 224 225 def to_dict(self) -> Dict[str, object]: 226 return { 227 "build": self.build, 228 "processes": self.processes, 229 "test-root": self.test_root, 230 "list-root": self.list_root, 231 "work-dir": self.work_dir, 232 "ets-stdlib-root": self.ets_stdlib_root, 233 "show-progress": self.show_progress, 234 "gc_type": self.gc_type, 235 "full-gc-bombing-frequency": self.full_gc_bombing_frequency, 236 "run_gc_in_place": self.run_gc_in_place, 237 "heap-verifier": self.heap_verifier, 238 "verbose": self.verbose.value.upper(), 239 "verbose-filter": self.verbose_filter.value.upper(), 240 "coverage": self.coverage.to_dict(), 241 "force-download": self.force_download, 242 "bco": self.bco, 243 "qemu": self.qemu.value.upper(), 244 "with-js": self.with_js, 245 "generate_only": self.generate_only, 246 "gdb-timeout": self.gdb_timeout, 247 "handle-timeout": self.handle_timeout 248 } 249