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 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 39 def __str__(self) -> str: 40 return _to_str(self, 1) 41 42 @property 43 def qemu_cmd_line(self) -> str: 44 qemu = '' 45 if self.qemu == QemuKind.ARM64: 46 qemu = '--arm64-qemu' 47 elif self.qemu == QemuKind.ARM32: 48 qemu = '--arm32-qemu' 49 return qemu 50 51 @cached_property 52 def chunksize(self) -> int: 53 return GeneralOptions.__DEFAULT_CHUNKSIZE 54 55 @cached_property 56 def static_core_root(self) -> str: 57 # This file is expected to be located at path: 58 # $PANDA_SOURCE/tests/tests-u-runner/runner/options/options_general.py 59 path_parts = __file__.split(path.sep)[:-5] 60 return path.sep.join(path_parts) 61 62 @cached_property 63 @value(yaml_path="general.generate-config", cli_name="generate_config", cast_to_type=_to_path) 64 def generate_config(self) -> Optional[str]: 65 return None 66 67 @cached_property 68 @value(yaml_path="general.processes", cli_name="processes", cast_to_type=_to_processes) 69 def processes(self) -> int: 70 return GeneralOptions.__DEFAULT_PROCESSES 71 72 @cached_property 73 @value(yaml_path="general.build", cli_name="build_dir", cast_to_type=_to_path, required=True) 74 def build(self) -> Optional[str]: 75 return None 76 77 @cached_property 78 @value(yaml_path="general.test-root", cli_name="test_root", cast_to_type=_to_path) 79 def test_root(self) -> Optional[str]: 80 return None 81 82 @cached_property 83 @value(yaml_path="general.list-root", cli_name="list_root", cast_to_type=_to_path) 84 def list_root(self) -> Optional[str]: 85 return None 86 87 @cached_property 88 @value(yaml_path="general.work-dir", cli_name="work_dir", cast_to_type=_to_path) 89 def work_dir(self) -> Optional[str]: 90 return None 91 92 @cached_property 93 @value(yaml_path="general.ets-stdlib-root", cli_name="ets_stdlib_root", cast_to_type=_to_path) 94 def ets_stdlib_root(self) -> Optional[str]: 95 return None 96 97 @cached_property 98 @value(yaml_path="general.show-progress", cli_name="progress", cast_to_type=_to_bool) 99 def show_progress(self) -> bool: 100 return False 101 102 @cached_property 103 @value(yaml_path="general.gc_type", cli_name="gc_type") 104 def gc_type(self) -> str: 105 return GeneralOptions.__DEFAULT_GC_TYPE 106 107 @cached_property 108 @value(yaml_path="general.full-gc-bombing-frequency", cli_name="full_gc_bombing_frequency", cast_to_type=_to_int) 109 def full_gc_bombing_frequency(self) -> int: 110 return GeneralOptions.__DEFAULT_GC_BOMBING_FREQUENCY 111 112 @cached_property 113 @value(yaml_path="general.run_gc_in_place", cli_name="run_gc_in_place", cast_to_type=_to_bool) 114 def run_gc_in_place(self) -> bool: 115 return False 116 117 @cached_property 118 @value(yaml_path="general.heap-verifier", cli_name="heap_verifier") 119 def heap_verifier(self) -> str: 120 return GeneralOptions.__DEFAULT_HEAP_VERIFIER 121 122 @cached_property 123 @value( 124 yaml_path="general.verbose", 125 cli_name="verbose", 126 cast_to_type=lambda x: _to_enum(x, VerboseKind) 127 ) 128 def verbose(self) -> VerboseKind: 129 return GeneralOptions.__DEFAULT_VERBOSE 130 131 @cached_property 132 @value( 133 yaml_path="general.verbose-filter", 134 cli_name="verbose_filter", 135 cast_to_type=lambda x: _to_enum(x, VerboseFilter) 136 ) 137 def verbose_filter(self) -> VerboseFilter: 138 return GeneralOptions.__DEFAULT_VERBOSE_FILTER 139 140 @cached_property 141 @value(yaml_path="general.force-download", cli_name="force_download", cast_to_type=_to_bool) 142 def force_download(self) -> bool: 143 return False 144 145 @cached_property 146 @value(yaml_path="general.bco", cli_name="bco", cast_to_type=_to_bool) 147 def bco(self) -> bool: 148 return True 149 150 @cached_property 151 @value(yaml_path="general.with_js", cli_name="with_js", cast_to_type=_to_bool) 152 def with_js(self) -> bool: 153 return True 154 155 @cached_property 156 @value(yaml_path="general.qemu", cli_name=["arm64_qemu", "arm32_qemu"], cast_to_type=_to_qemu) 157 def qemu(self) -> QemuKind: 158 return GeneralOptions.__DEFAULT_QEMU 159 160 @cached_property 161 @value(yaml_path="general.generate-only", cli_name="generate_only", cast_to_type=_to_bool) 162 def generate_only(self) -> bool: 163 return False 164 165 coverage = CoverageOptions() 166 167 def get_command_line(self) -> str: 168 options = [ 169 f'--generate-config="{self.generate_config}"' if self.generate_config else '', 170 f'--processes={self.processes}' if self.processes != GeneralOptions.__DEFAULT_PROCESSES else '', 171 f'--chunksize={self.chunksize}' if self.chunksize != GeneralOptions.__DEFAULT_CHUNKSIZE else '', 172 f'--build-dir="{self.build}"', 173 f'--test-root="{self.test_root}"' if self.test_root else '', 174 f'--list-root="{self.list_root}"' if self.list_root else '', 175 f'--work-dir="{self.work_dir}"' if self.work_dir else '', 176 f'--ets-stdlib-root="{self.ets_stdlib_root}"' if self.ets_stdlib_root else '', 177 '--show-progress' if self.show_progress else '', 178 f'--gc-type="{self.gc_type}"' if self.gc_type != GeneralOptions.__DEFAULT_GC_TYPE else '', 179 f'--full-gc-bombing-frequency={self.full_gc_bombing_frequency}' 180 if self.full_gc_bombing_frequency != GeneralOptions.__DEFAULT_GC_BOMBING_FREQUENCY else '', 181 '--no-run-gc-in-place' if self.run_gc_in_place else '', 182 f'--heap-verifier="{self.heap_verifier}"' 183 if self.heap_verifier != GeneralOptions.__DEFAULT_HEAP_VERIFIER else '', 184 f'--verbose={self.verbose.value}' 185 if self.verbose != GeneralOptions.__DEFAULT_VERBOSE else '', 186 f'--verbose-filter={self.verbose_filter.value}' 187 if self.verbose_filter != GeneralOptions.__DEFAULT_VERBOSE_FILTER else '', 188 self.coverage.get_command_line(), 189 '--force-download' if self.force_download else '', 190 '--no-bco' if not self.bco else '', 191 '--no-js' if not self.with_js else '', 192 '--generate-only' if self.generate_only else '', 193 self.qemu_cmd_line, 194 ] 195 return ' '.join(options) 196 197 def to_dict(self) -> Dict[str, object]: 198 return { 199 "build": self.build, 200 "processes": self.processes, 201 "test-root": self.test_root, 202 "list-root": self.list_root, 203 "work-dir": self.work_dir, 204 "ets-stdlib-root": self.ets_stdlib_root, 205 "show-progress": self.show_progress, 206 "gc_type": self.gc_type, 207 "full-gc-bombing-frequency": self.full_gc_bombing_frequency, 208 "run_gc_in_place": self.run_gc_in_place, 209 "heap-verifier": self.heap_verifier, 210 "verbose": self.verbose.value.upper(), 211 "verbose-filter": self.verbose_filter.value.upper(), 212 "coverage": self.coverage.to_dict(), 213 "force-download": self.force_download, 214 "bco": self.bco, 215 "qemu": self.qemu.value.upper(), 216 "with-js": self.with_js, 217 "generate_only": self.generate_only, 218 } 219