scripts: Fix twisterlib for ruff - UP030, UP031, UP032
Fixes ruff linting errors UP030, UP031, UP032, which make you use format specifiers (fstrings) instead of printf formatting or str.format(). Signed-off-by: Lukasz Mrugala <lukaszx.mrugala@intel.com>
This commit is contained in:
parent
7746a97e31
commit
9b4397a764
18 changed files with 215 additions and 226 deletions
|
@ -758,78 +758,54 @@
|
|||
]
|
||||
"./scripts/pylib/twister/twisterlib/cmakecache.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/config_parser.py" = [
|
||||
"UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/coverage.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/environment.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/handlers.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation
|
||||
"UP030", # https://docs.astral.sh/ruff/rules/format-literals
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/hardwaremap.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/harness.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/platform.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/quarantine.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/reports.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/runner.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/size_calc.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/testinstance.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/testplan.py" = [
|
||||
"E402", # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"F401", # https://docs.astral.sh/ruff/rules/unused-import
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/testsuite.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylib/twister/twisterlib/twister_main.py" = [
|
||||
"E501", # https://docs.astral.sh/ruff/rules/line-too-long
|
||||
"UP032", # https://docs.astral.sh/ruff/rules/f-string
|
||||
]
|
||||
"./scripts/pylint/checkers/argparse-checker.py" = [
|
||||
"F821", # https://docs.astral.sh/ruff/rules/undefined-name
|
||||
|
|
|
@ -59,7 +59,7 @@ class CMakeCacheEntry:
|
|||
v = int(val)
|
||||
return v != 0
|
||||
except ValueError as exc:
|
||||
raise ValueError('invalid bool {}'.format(val)) from exc
|
||||
raise ValueError(f'invalid bool {val}') from exc
|
||||
|
||||
@classmethod
|
||||
def from_line(cls, line, line_no):
|
||||
|
@ -81,7 +81,7 @@ class CMakeCacheEntry:
|
|||
try:
|
||||
value = cls._to_bool(value)
|
||||
except ValueError as exc:
|
||||
args = exc.args + ('on line {}: {}'.format(line_no, line),)
|
||||
args = exc.args + (f'on line {line_no}: {line}',)
|
||||
raise ValueError(args) from exc
|
||||
# If the value is a CMake list (i.e. is a string which contains a ';'),
|
||||
# convert to a Python list.
|
||||
|
|
|
@ -164,8 +164,7 @@ class TwisterConfigParser:
|
|||
elif typestr.startswith("map"):
|
||||
return value
|
||||
else:
|
||||
raise ConfigurationError(
|
||||
self.filename, "unknown type '%s'" % value)
|
||||
raise ConfigurationError(self.filename, f"unknown type '{value}'")
|
||||
|
||||
def get_scenario(self, name):
|
||||
"""Get a dictionary representing the keys/values within a scenario
|
||||
|
@ -199,7 +198,7 @@ class TwisterConfigParser:
|
|||
)
|
||||
if k in d:
|
||||
if k == "filter":
|
||||
d[k] = "(%s) and (%s)" % (d[k], v)
|
||||
d[k] = f"({d[k]}) and ({v})"
|
||||
elif k not in ("extra_conf_files", "extra_overlay_confs",
|
||||
"extra_dtc_overlay_files"):
|
||||
if isinstance(d[k], str) and isinstance(v, list):
|
||||
|
@ -258,8 +257,8 @@ class TwisterConfigParser:
|
|||
if required:
|
||||
raise ConfigurationError(
|
||||
self.filename,
|
||||
"missing required value for '%s' in test '%s'" %
|
||||
(k, name))
|
||||
f"missing required value for '{k}' in test '{name}'"
|
||||
)
|
||||
else:
|
||||
if "default" in kinfo:
|
||||
default = kinfo["default"]
|
||||
|
@ -271,8 +270,8 @@ class TwisterConfigParser:
|
|||
d[k] = self._cast_value(d[k], kinfo["type"])
|
||||
except ValueError:
|
||||
raise ConfigurationError(
|
||||
self.filename, "bad %s value '%s' for key '%s' in name '%s'" %
|
||||
(kinfo["type"], d[k], k, name)
|
||||
self.filename,
|
||||
f"bad {kinfo['type']} value '{d[k]}' for key '{k}' in name '{name}'"
|
||||
) from None
|
||||
|
||||
return d
|
||||
|
|
|
@ -39,7 +39,7 @@ class CoverageTool:
|
|||
elif tool == 'gcovr':
|
||||
t = Gcovr()
|
||||
else:
|
||||
logger.error("Unsupported coverage tool specified: {}".format(tool))
|
||||
logger.error(f"Unsupported coverage tool specified: {tool}")
|
||||
return None
|
||||
|
||||
logger.debug(f"Select {tool} as the coverage tool...")
|
||||
|
@ -47,7 +47,7 @@ class CoverageTool:
|
|||
|
||||
@staticmethod
|
||||
def retrieve_gcov_data(input_file):
|
||||
logger.debug("Working on %s" % input_file)
|
||||
logger.debug(f"Working on {input_file}")
|
||||
extracted_coverage_info = {}
|
||||
capture_data = False
|
||||
capture_complete = False
|
||||
|
@ -125,47 +125,61 @@ class CoverageTool:
|
|||
with open(filename, 'wb') as fp:
|
||||
fp.write(hex_bytes)
|
||||
except ValueError:
|
||||
logger.exception("Unable to convert hex data for file: {}".format(filename))
|
||||
logger.exception(f"Unable to convert hex data for file: {filename}")
|
||||
gcda_created = False
|
||||
except FileNotFoundError:
|
||||
logger.exception("Unable to create gcda file: {}".format(filename))
|
||||
logger.exception(f"Unable to create gcda file: {filename}")
|
||||
gcda_created = False
|
||||
return gcda_created
|
||||
|
||||
def generate(self, outdir):
|
||||
coverage_completed = True
|
||||
for filename in glob.glob("%s/**/handler.log" % outdir, recursive=True):
|
||||
for filename in glob.glob(f"{outdir}/**/handler.log", recursive=True):
|
||||
gcov_data = self.__class__.retrieve_gcov_data(filename)
|
||||
capture_complete = gcov_data['complete']
|
||||
extracted_coverage_info = gcov_data['data']
|
||||
if capture_complete:
|
||||
gcda_created = self.create_gcda_files(extracted_coverage_info)
|
||||
if gcda_created:
|
||||
logger.debug("Gcov data captured: {}".format(filename))
|
||||
logger.debug(f"Gcov data captured: {filename}")
|
||||
else:
|
||||
logger.error("Gcov data invalid for: {}".format(filename))
|
||||
logger.error(f"Gcov data invalid for: {filename}")
|
||||
coverage_completed = False
|
||||
else:
|
||||
logger.error("Gcov data capture incomplete: {}".format(filename))
|
||||
logger.error(f"Gcov data capture incomplete: {filename}")
|
||||
coverage_completed = False
|
||||
|
||||
with open(os.path.join(outdir, "coverage.log"), "a") as coveragelog:
|
||||
ret = self._generate(outdir, coveragelog)
|
||||
if ret == 0:
|
||||
report_log = {
|
||||
"html": "HTML report generated: {}".format(os.path.join(outdir, "coverage", "index.html")),
|
||||
"lcov": "LCOV report generated: {}".format(os.path.join(outdir, "coverage.info")),
|
||||
"xml": "XML report generated: {}".format(os.path.join(outdir, "coverage", "coverage.xml")),
|
||||
"csv": "CSV report generated: {}".format(os.path.join(outdir, "coverage", "coverage.csv")),
|
||||
"txt": "TXT report generated: {}".format(os.path.join(outdir, "coverage", "coverage.txt")),
|
||||
"coveralls": "Coveralls report generated: {}".format(os.path.join(outdir, "coverage", "coverage.coveralls.json")),
|
||||
"sonarqube": "Sonarqube report generated: {}".format(os.path.join(outdir, "coverage", "coverage.sonarqube.xml"))
|
||||
"html": "HTML report generated: {}".format(
|
||||
os.path.join(outdir, "coverage", "index.html")
|
||||
),
|
||||
"lcov": "LCOV report generated: {}".format(
|
||||
os.path.join(outdir, "coverage.info")
|
||||
),
|
||||
"xml": "XML report generated: {}".format(
|
||||
os.path.join(outdir, "coverage", "coverage.xml")
|
||||
),
|
||||
"csv": "CSV report generated: {}".format(
|
||||
os.path.join(outdir, "coverage", "coverage.csv")
|
||||
),
|
||||
"txt": "TXT report generated: {}".format(
|
||||
os.path.join(outdir, "coverage", "coverage.txt")
|
||||
),
|
||||
"coveralls": "Coveralls report generated: {}".format(
|
||||
os.path.join(outdir, "coverage", "coverage.coveralls.json")
|
||||
),
|
||||
"sonarqube": "Sonarqube report generated: {}".format(
|
||||
os.path.join(outdir, "coverage", "coverage.sonarqube.xml")
|
||||
)
|
||||
}
|
||||
for r in self.output_formats.split(','):
|
||||
logger.info(report_log[r])
|
||||
else:
|
||||
coverage_completed = False
|
||||
logger.debug("All coverage data processed: {}".format(coverage_completed))
|
||||
logger.debug(f"All coverage data processed: {coverage_completed}")
|
||||
return coverage_completed
|
||||
|
||||
|
||||
|
|
|
@ -286,8 +286,7 @@ Artificially long but functional example:
|
|||
|
||||
# Start of individual args place them in alpha-beta order
|
||||
|
||||
board_root_list = ["%s/boards" % ZEPHYR_BASE,
|
||||
"%s/subsys/testsuite/boards" % ZEPHYR_BASE]
|
||||
board_root_list = [f"{ZEPHYR_BASE}/boards", f"{ZEPHYR_BASE}/subsys/testsuite/boards"]
|
||||
|
||||
modules = zephyr_module.parse_modules(ZEPHYR_BASE)
|
||||
for module in modules:
|
||||
|
@ -934,10 +933,10 @@ def parse_arguments(parser: argparse.ArgumentParser, args, options = None, on_in
|
|||
double_dash = len(options.extra_test_args)
|
||||
unrecognized = " ".join(options.extra_test_args[0:double_dash])
|
||||
|
||||
logger.error("Unrecognized arguments found: '%s'. Use -- to "
|
||||
"delineate extra arguments for test binary or pass "
|
||||
"-h for help.",
|
||||
unrecognized)
|
||||
logger.error(
|
||||
f"Unrecognized arguments found: '{unrecognized}'."
|
||||
" Use -- to delineate extra arguments for test binary or pass -h for help."
|
||||
)
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -1065,7 +1064,7 @@ class TwisterEnv:
|
|||
args = []
|
||||
script = os.fspath(args[0])
|
||||
|
||||
logger.debug("Running cmake script %s", script)
|
||||
logger.debug(f"Running cmake script {script}")
|
||||
|
||||
cmake_args = ["-D{}".format(a.replace('"', '')) for a in args[1:]]
|
||||
cmake_args.extend(['-P', script])
|
||||
|
@ -1093,12 +1092,12 @@ class TwisterEnv:
|
|||
out = strip_ansi_sequences(out.decode())
|
||||
|
||||
if p.returncode == 0:
|
||||
msg = "Finished running %s" % (args[0])
|
||||
msg = f"Finished running {args[0]}"
|
||||
logger.debug(msg)
|
||||
results = {"returncode": p.returncode, "msg": msg, "stdout": out}
|
||||
|
||||
else:
|
||||
logger.error("CMake script failure: %s" % (args[0]))
|
||||
logger.error(f"CMake script failure: {args[0]}")
|
||||
results = {"returncode": p.returncode, "returnmsg": out}
|
||||
|
||||
return results
|
||||
|
|
|
@ -138,9 +138,10 @@ class Handler:
|
|||
for tc in self.instance.testcases:
|
||||
tc.status = TwisterStatus.FAIL
|
||||
self.instance.reason = "Testsuite mismatch"
|
||||
logger.debug("Test suite names were not printed or some of them in " \
|
||||
"output do not correspond with expected: %s",
|
||||
str(expected_suite_names))
|
||||
logger.debug(
|
||||
"Test suite names were not printed or some of them in output"
|
||||
f" do not correspond with expected: {str(expected_suite_names)}",
|
||||
)
|
||||
|
||||
def _final_handle_actions(self, harness, handler_time):
|
||||
|
||||
|
@ -166,7 +167,7 @@ class Handler:
|
|||
# have added any additional images to the run target manually
|
||||
domain_path = os.path.join(self.build_dir, "domains.yaml")
|
||||
domains = Domains.from_file(domain_path)
|
||||
logger.debug("Loaded sysbuild domain data from %s" % domain_path)
|
||||
logger.debug(f"Loaded sysbuild domain data from {domain_path}")
|
||||
build_dir = domains.get_default_domain().build_dir
|
||||
else:
|
||||
build_dir = self.build_dir
|
||||
|
@ -217,7 +218,7 @@ class BinaryHandler(Handler):
|
|||
stripped_line = line_decoded.rstrip()
|
||||
if stripped_line.endswith(suffix):
|
||||
stripped_line = stripped_line[:-len(suffix)].rstrip()
|
||||
logger.debug("OUTPUT: %s", stripped_line)
|
||||
logger.debug(f"OUTPUT: {stripped_line}")
|
||||
log_out_fp.write(strip_ansi_sequences(line_decoded))
|
||||
log_out_fp.flush()
|
||||
harness.handle(stripped_line)
|
||||
|
@ -343,10 +344,10 @@ class BinaryHandler(Handler):
|
|||
harness.run_robot_test(command, self)
|
||||
return
|
||||
|
||||
stderr_log = "{}/handler_stderr.log".format(self.instance.build_dir)
|
||||
stderr_log = f"{self.instance.build_dir}/handler_stderr.log"
|
||||
with open(stderr_log, "w+") as stderr_log_fp, subprocess.Popen(command, stdout=subprocess.PIPE,
|
||||
stderr=stderr_log_fp, cwd=self.build_dir, env=env) as proc:
|
||||
logger.debug("Spawning BinaryHandler Thread for %s" % self.name)
|
||||
logger.debug(f"Spawning BinaryHandler Thread for {self.name}")
|
||||
t = threading.Thread(target=self._output_handler, args=(proc, harness,), daemon=True)
|
||||
t.start()
|
||||
t.join()
|
||||
|
@ -357,7 +358,7 @@ class BinaryHandler(Handler):
|
|||
self.returncode = proc.returncode
|
||||
if proc.returncode != 0:
|
||||
self.instance.status = TwisterStatus.ERROR
|
||||
self.instance.reason = "BinaryHandler returned {}".format(proc.returncode)
|
||||
self.instance.reason = f"BinaryHandler returned {proc.returncode}"
|
||||
self.try_kill_process_by_pid()
|
||||
|
||||
handler_time = time.time() - start_time
|
||||
|
@ -521,7 +522,7 @@ class DeviceHandler(Handler):
|
|||
except subprocess.TimeoutExpired:
|
||||
proc.kill()
|
||||
proc.communicate()
|
||||
logger.error("{} timed out".format(script))
|
||||
logger.error(f"{script} timed out")
|
||||
|
||||
def _create_command(self, runner, hardware):
|
||||
if (self.options.west_flash is not None) or runner:
|
||||
|
@ -550,13 +551,13 @@ class DeviceHandler(Handler):
|
|||
command_extra_args.append(board_id)
|
||||
elif runner == "openocd" and product == "STM32 STLink" or runner == "openocd" and product == "STLINK-V3":
|
||||
command_extra_args.append("--cmd-pre-init")
|
||||
command_extra_args.append("hla_serial %s" % board_id)
|
||||
command_extra_args.append(f"hla_serial {board_id}")
|
||||
elif runner == "openocd" and product == "EDBG CMSIS-DAP":
|
||||
command_extra_args.append("--cmd-pre-init")
|
||||
command_extra_args.append("cmsis_dap_serial %s" % board_id)
|
||||
command_extra_args.append(f"cmsis_dap_serial {board_id}")
|
||||
elif runner == "openocd" and product == "LPC-LINK2 CMSIS-DAP":
|
||||
command_extra_args.append("--cmd-pre-init")
|
||||
command_extra_args.append("adapter serial %s" % board_id)
|
||||
command_extra_args.append(f"adapter serial {board_id}")
|
||||
elif runner == "jlink":
|
||||
command.append("--dev-id")
|
||||
command.append(board_id)
|
||||
|
@ -564,9 +565,9 @@ class DeviceHandler(Handler):
|
|||
# for linkserver
|
||||
# --probe=#<number> select by probe index
|
||||
# --probe=<serial number> select by probe serial number
|
||||
command.append("--probe=%s" % board_id)
|
||||
command.append(f"--probe={board_id}")
|
||||
elif runner == "stm32cubeprogrammer":
|
||||
command.append("--tool-opt=sn=%s" % board_id)
|
||||
command.append(f"--tool-opt=sn={board_id}")
|
||||
|
||||
# Receive parameters from runner_params field.
|
||||
if hardware.runner_params:
|
||||
|
@ -627,7 +628,7 @@ class DeviceHandler(Handler):
|
|||
def _handle_serial_exception(self, exception, dut, serial_pty, ser_pty_process):
|
||||
self.instance.status = TwisterStatus.FAIL
|
||||
self.instance.reason = "Serial Device Error"
|
||||
logger.error("Serial device error: %s" % (str(exception)))
|
||||
logger.error(f"Serial device error: {exception!s}")
|
||||
|
||||
self.instance.add_missing_case_status(TwisterStatus.BLOCK, "Serial Device Error")
|
||||
if serial_pty and ser_pty_process:
|
||||
|
@ -666,10 +667,7 @@ class DeviceHandler(Handler):
|
|||
)
|
||||
except subprocess.CalledProcessError as error:
|
||||
logger.error(
|
||||
"Failed to run subprocess {}, error {}".format(
|
||||
serial_pty,
|
||||
error.output
|
||||
)
|
||||
f"Failed to run subprocess {serial_pty}, error {error.output}"
|
||||
)
|
||||
return
|
||||
|
||||
|
@ -734,8 +732,8 @@ class DeviceHandler(Handler):
|
|||
start_time = time.time()
|
||||
t.start()
|
||||
|
||||
d_log = "{}/device.log".format(self.instance.build_dir)
|
||||
logger.debug('Flash command: %s', command)
|
||||
d_log = f"{self.instance.build_dir}/device.log"
|
||||
logger.debug(f'Flash command: {command}', )
|
||||
flash_error = False
|
||||
try:
|
||||
stdout = stderr = None
|
||||
|
@ -797,7 +795,7 @@ class DeviceHandler(Handler):
|
|||
t.join(0.1)
|
||||
|
||||
if t.is_alive():
|
||||
logger.debug("Timed out while monitoring serial output on {}".format(self.instance.platform.name))
|
||||
logger.debug(f"Timed out while monitoring serial output on {self.instance.platform.name}")
|
||||
|
||||
if ser.isOpen():
|
||||
ser.close()
|
||||
|
@ -1036,7 +1034,7 @@ class QEMUHandler(Handler):
|
|||
self.instance.reason = "Timeout"
|
||||
else:
|
||||
if not self.instance.reason:
|
||||
self.instance.reason = "Exited with {}".format(self.returncode)
|
||||
self.instance.reason = f"Exited with {self.returncode}"
|
||||
self.instance.add_missing_case_status(TwisterStatus.BLOCK)
|
||||
|
||||
def handle(self, harness):
|
||||
|
@ -1055,19 +1053,19 @@ class QEMUHandler(Handler):
|
|||
self.ignore_unexpected_eof))
|
||||
|
||||
self.thread.daemon = True
|
||||
logger.debug("Spawning QEMUHandler Thread for %s" % self.name)
|
||||
logger.debug(f"Spawning QEMUHandler Thread for {self.name}")
|
||||
self.thread.start()
|
||||
thread_max_time = time.time() + self.get_test_timeout()
|
||||
if sys.stdout.isatty():
|
||||
subprocess.call(["stty", "sane"], stdin=sys.stdout)
|
||||
|
||||
logger.debug("Running %s (%s)" % (self.name, self.type_str))
|
||||
logger.debug(f"Running {self.name} ({self.type_str})")
|
||||
|
||||
is_timeout = False
|
||||
qemu_pid = None
|
||||
|
||||
with subprocess.Popen(command, stdout=open(self.stdout_fn, "w"), stderr=open(self.stderr_fn, "w"), cwd=self.build_dir) as proc:
|
||||
logger.debug("Spawning QEMUHandler Thread for %s" % self.name)
|
||||
logger.debug(f"Spawning QEMUHandler Thread for {self.name}")
|
||||
|
||||
try:
|
||||
proc.wait(self.get_test_timeout())
|
||||
|
@ -1205,7 +1203,7 @@ class QEMUWinHandler(Handler):
|
|||
self.instance.reason = "Timeout"
|
||||
else:
|
||||
if not self.instance.reason:
|
||||
self.instance.reason = "Exited with {}".format(self.returncode)
|
||||
self.instance.reason = f"Exited with {self.returncode}"
|
||||
self.instance.add_missing_case_status(TwisterStatus.BLOCK)
|
||||
|
||||
def _enqueue_char(self, queue):
|
||||
|
@ -1333,14 +1331,14 @@ class QEMUWinHandler(Handler):
|
|||
command = self._create_command(domain_build_dir)
|
||||
self._set_qemu_filenames(domain_build_dir)
|
||||
|
||||
logger.debug("Running %s (%s)" % (self.name, self.type_str))
|
||||
logger.debug(f"Running {self.name} ({self.type_str})")
|
||||
is_timeout = False
|
||||
self.stop_thread = False
|
||||
queue = Queue()
|
||||
|
||||
with subprocess.Popen(command, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT,
|
||||
cwd=self.build_dir) as proc:
|
||||
logger.debug("Spawning QEMUHandler Thread for %s" % self.name)
|
||||
logger.debug(f"Spawning QEMUHandler Thread for {self.name}")
|
||||
|
||||
self.thread = threading.Thread(target=self._enqueue_char, args=(queue,))
|
||||
self.thread.daemon = True
|
||||
|
|
|
@ -361,7 +361,7 @@ class HardwareMap:
|
|||
s_dev.lock = None
|
||||
self.detected.append(s_dev)
|
||||
else:
|
||||
logger.warning("Unsupported device (%s): %s" % (d.manufacturer, d))
|
||||
logger.warning(f"Unsupported device ({d.manufacturer}): {d}")
|
||||
|
||||
def save(self, hwm_file):
|
||||
# use existing map
|
||||
|
|
|
@ -222,8 +222,9 @@ class Robot(Harness):
|
|||
# please note that there should be only one testcase in testcases list
|
||||
self.instance.testcases[0].status = TwisterStatus.PASS
|
||||
else:
|
||||
logger.error("Robot test failure: %s for %s" %
|
||||
(handler.sourcedir, self.instance.platform.name))
|
||||
logger.error(
|
||||
f"Robot test failure: {handler.sourcedir} for {self.instance.platform.name}"
|
||||
)
|
||||
self.instance.status = TwisterStatus.FAIL
|
||||
self.instance.testcases[0].status = TwisterStatus.FAIL
|
||||
|
||||
|
@ -530,7 +531,7 @@ class Pytest(Harness):
|
|||
else:
|
||||
cmd_append_python_path = ''
|
||||
cmd_to_print = cmd_append_python_path + shlex.join(cmd)
|
||||
logger.debug('Running pytest command: %s', cmd_to_print)
|
||||
logger.debug(f'Running pytest command: {cmd_to_print}')
|
||||
|
||||
return cmd, env
|
||||
|
||||
|
@ -541,7 +542,7 @@ class Pytest(Harness):
|
|||
if not line:
|
||||
continue
|
||||
self._output.append(line)
|
||||
logger.debug('PYTEST: %s', line)
|
||||
logger.debug(f'PYTEST: {line}')
|
||||
self.parse_record(line)
|
||||
proc.communicate()
|
||||
|
||||
|
@ -639,11 +640,11 @@ class Gtest(Harness):
|
|||
# Assert that we don't already have a running test
|
||||
assert (
|
||||
self.tc is None
|
||||
), "gTest error, {} didn't finish".format(self.tc)
|
||||
), f"gTest error, {self.tc} didn't finish"
|
||||
|
||||
# Check that the instance doesn't exist yet (prevents re-running)
|
||||
tc = self.instance.get_case_by_name(name)
|
||||
assert tc is None, "gTest error, {} running twice".format(tc)
|
||||
assert tc is None, f"gTest error, {tc} running twice"
|
||||
|
||||
# Create the test instance and set the context
|
||||
tc = self.instance.get_case_or_create(name)
|
||||
|
@ -674,7 +675,7 @@ class Gtest(Harness):
|
|||
tc = self.instance.get_case_by_name(name)
|
||||
assert (
|
||||
tc is not None and tc == self.tc
|
||||
), "gTest error, mismatched tests. Expected {} but got {}".format(self.tc, tc)
|
||||
), f"gTest error, mismatched tests. Expected {self.tc} but got {tc}"
|
||||
|
||||
# Test finished, clear the context
|
||||
self.tc = None
|
||||
|
@ -743,13 +744,13 @@ class Test(Harness):
|
|||
for ts_name_ in ts_names:
|
||||
if self.started_suites[ts_name_]['count'] < (0 if phase == 'TS_SUM' else 1):
|
||||
continue
|
||||
tc_fq_id = "{}.{}.{}".format(self.id, ts_name_, tc_name)
|
||||
tc_fq_id = f"{self.id}.{ts_name_}.{tc_name}"
|
||||
if tc := self.instance.get_case_by_name(tc_fq_id):
|
||||
if self.trace:
|
||||
logger.debug(f"On {phase}: Ztest case '{tc_name}' matched to '{tc_fq_id}")
|
||||
return tc
|
||||
logger.debug(f"On {phase}: Ztest case '{tc_name}' is not known in {self.started_suites} running suite(s).")
|
||||
tc_id = "{}.{}".format(self.id, tc_name)
|
||||
tc_id = f"{self.id}.{tc_name}"
|
||||
return self.instance.get_case_or_create(tc_id)
|
||||
|
||||
def start_suite(self, suite_name):
|
||||
|
|
|
@ -152,15 +152,17 @@ class GNUMakeJobClient(JobClient):
|
|||
rc = fcntl.fcntl(pipe[0], fcntl.F_GETFL)
|
||||
if rc & os.O_ACCMODE != os.O_RDONLY:
|
||||
logger.warning(
|
||||
"FD %s is not readable (flags=%x); "
|
||||
"ignoring GNU make jobserver", pipe[0], rc)
|
||||
f"FD {pipe[0]} is not readable (flags={rc:x});"
|
||||
" ignoring GNU make jobserver"
|
||||
)
|
||||
pipe = None
|
||||
if pipe:
|
||||
rc = fcntl.fcntl(pipe[1], fcntl.F_GETFL)
|
||||
if rc & os.O_ACCMODE != os.O_WRONLY:
|
||||
logger.warning(
|
||||
"FD %s is not writable (flags=%x); "
|
||||
"ignoring GNU make jobserver", pipe[1], rc)
|
||||
f"FD {pipe[1]} is not writable (flags={rc:x});"
|
||||
" ignoring GNU make jobserver"
|
||||
)
|
||||
pipe = None
|
||||
if pipe:
|
||||
logger.info("using GNU make jobserver")
|
||||
|
|
|
@ -177,4 +177,4 @@ class Platform:
|
|||
return next(iter(self.simulators), None)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s on %s>" % (self.name, self.arch)
|
||||
return f"<{self.name} on {self.arch}>"
|
||||
|
|
|
@ -38,7 +38,7 @@ class Quarantine:
|
|||
def get_matched_quarantine(self, testname, platform, architecture, simulator):
|
||||
qelem = self.quarantine.get_matched_quarantine(testname, platform, architecture, simulator)
|
||||
if qelem:
|
||||
logger.debug('%s quarantined with reason: %s' % (testname, qelem.comment))
|
||||
logger.debug(f'{testname} quarantined with reason: {qelem.comment}')
|
||||
return qelem.comment
|
||||
return None
|
||||
|
||||
|
|
|
@ -450,7 +450,7 @@ class Reporting:
|
|||
("used_rom", int, True)]
|
||||
|
||||
if not os.path.exists(filename):
|
||||
logger.error("Cannot compare metrics, %s not found" % filename)
|
||||
logger.error(f"Cannot compare metrics, {filename} not found")
|
||||
return []
|
||||
|
||||
results = []
|
||||
|
@ -506,9 +506,7 @@ class Reporting:
|
|||
if show_footprint:
|
||||
logger.log(
|
||||
logging.INFO if all_deltas else logging.WARNING,
|
||||
"{:<25} {:<60} {} {:<+4}, is now {:6} {:+.2%}".format(
|
||||
i.platform.name, i.testsuite.name,
|
||||
metric, delta, value, percentage))
|
||||
f"{i.platform.name:<25} {i.testsuite.name:<60} {metric} {delta:<+4}, is now {value:6} {percentage:+.2%}")
|
||||
|
||||
warnings += 1
|
||||
|
||||
|
@ -574,9 +572,11 @@ class Reporting:
|
|||
if instance.status == TwisterStatus.FAIL:
|
||||
failed += 1
|
||||
elif not ignore_unrecognized_sections and instance.metrics.get("unrecognized"):
|
||||
logger.error("%sFAILED%s: %s has unrecognized binary sections: %s" %
|
||||
(Fore.RED, Fore.RESET, instance.name,
|
||||
str(instance.metrics.get("unrecognized", []))))
|
||||
logger.error(
|
||||
f"{Fore.RED}FAILED{Fore.RESET}:"
|
||||
f" {instance.name} has unrecognized binary sections:"
|
||||
f" {instance.metrics.get('unrecognized', [])!s}"
|
||||
)
|
||||
failed += 1
|
||||
|
||||
# FIXME: need a better way to identify executed tests
|
||||
|
@ -648,7 +648,7 @@ class Reporting:
|
|||
filename = os.path.join(outdir, report_name)
|
||||
|
||||
if suffix:
|
||||
filename = "{}_{}".format(filename, suffix)
|
||||
filename = f"{filename}_{suffix}"
|
||||
|
||||
if not no_update:
|
||||
json_file = filename + ".json"
|
||||
|
@ -669,10 +669,10 @@ class Reporting:
|
|||
platforms = {repr(inst.platform):inst.platform for _, inst in self.instances.items()}
|
||||
for platform in platforms.values():
|
||||
if suffix:
|
||||
filename = os.path.join(outdir,"{}_{}.xml".format(platform.normalized_name, suffix))
|
||||
json_platform_file = os.path.join(outdir,"{}_{}".format(platform.normalized_name, suffix))
|
||||
filename = os.path.join(outdir,f"{platform.normalized_name}_{suffix}.xml")
|
||||
json_platform_file = os.path.join(outdir,f"{platform.normalized_name}_{suffix}")
|
||||
else:
|
||||
filename = os.path.join(outdir,"{}.xml".format(platform.normalized_name))
|
||||
filename = os.path.join(outdir,f"{platform.normalized_name}.xml")
|
||||
json_platform_file = os.path.join(outdir, platform.normalized_name)
|
||||
self.xunit_report(json_file, filename, platform.name, full_report=True)
|
||||
self.json_report(json_platform_file + ".json",
|
||||
|
|
|
@ -181,7 +181,7 @@ class ExecutionCounter:
|
|||
Node(f"Test cases only started: {self.started_cases}", parent=error_cases_node)
|
||||
|
||||
for pre, _, node in RenderTree(root):
|
||||
print("%s%s" % (pre, node.name))
|
||||
print(f"{pre}{node.name}")
|
||||
|
||||
@property
|
||||
def warnings(self):
|
||||
|
@ -521,7 +521,7 @@ class CMake:
|
|||
if args is None:
|
||||
args = []
|
||||
|
||||
logger.debug("Building %s for %s" % (self.source_dir, self.platform.name))
|
||||
logger.debug(f"Building {self.source_dir} for {self.platform.name}")
|
||||
|
||||
cmake_args = []
|
||||
cmake_args.extend(args)
|
||||
|
@ -578,9 +578,9 @@ class CMake:
|
|||
overflow_found = re.findall("region `(FLASH|ROM|RAM|ICCM|DCCM|SRAM|dram\\d_\\d_seg)' overflowed by", log_msg)
|
||||
imgtool_overflow_found = re.findall(r"Error: Image size \(.*\) \+ trailer \(.*\) exceeds requested size", log_msg)
|
||||
if overflow_found and not self.options.overflow_as_errors:
|
||||
logger.debug("Test skipped due to {} Overflow".format(overflow_found[0]))
|
||||
logger.debug(f"Test skipped due to {overflow_found[0]} Overflow")
|
||||
self.instance.status = TwisterStatus.SKIP
|
||||
self.instance.reason = "{} overflow".format(overflow_found[0])
|
||||
self.instance.reason = f"{overflow_found[0]} overflow"
|
||||
change_skip_to_error_if_integration(self.options, self.instance)
|
||||
elif imgtool_overflow_found and not self.options.overflow_as_errors:
|
||||
self.instance.status = TwisterStatus.SKIP
|
||||
|
@ -611,7 +611,7 @@ class CMake:
|
|||
if self.instance.sysbuild:
|
||||
warning_command = 'SB_' + warning_command
|
||||
|
||||
logger.debug("Running cmake on %s for %s" % (self.source_dir, self.platform.name))
|
||||
logger.debug(f"Running cmake on {self.source_dir} for {self.platform.name}")
|
||||
cmake_args = [
|
||||
f'-B{self.build_dir}',
|
||||
f'-DTC_RUNID={self.instance.run_id}',
|
||||
|
@ -633,7 +633,7 @@ class CMake:
|
|||
]
|
||||
|
||||
if self.instance.sysbuild and not filter_stages:
|
||||
logger.debug("Building %s using sysbuild" % (self.source_dir))
|
||||
logger.debug(f"Building {self.source_dir} using sysbuild")
|
||||
source_args = [
|
||||
f'-S{canonical_zephyr_base}/share/sysbuild',
|
||||
f'-DAPP_DIR={self.source_dir}'
|
||||
|
@ -646,7 +646,7 @@ class CMake:
|
|||
|
||||
cmake_args.extend(args)
|
||||
|
||||
cmake_opts = ['-DBOARD={}'.format(self.platform.name)]
|
||||
cmake_opts = [f'-DBOARD={self.platform.name}']
|
||||
cmake_args.extend(cmake_opts)
|
||||
|
||||
if self.instance.testsuite.required_snippets:
|
||||
|
@ -696,7 +696,7 @@ class CMake:
|
|||
for tc in self.instance.testcases:
|
||||
tc.status = self.instance.status
|
||||
|
||||
logger.error("CMake build failure: %s for %s" % (self.source_dir, self.platform.name))
|
||||
logger.error(f"CMake build failure: {self.source_dir} for {self.platform.name}")
|
||||
ret = {"returncode": p.returncode}
|
||||
|
||||
if out:
|
||||
|
@ -726,7 +726,7 @@ class FilterBuilder(CMake):
|
|||
# Load domain yaml to get default domain build directory
|
||||
domain_path = os.path.join(self.build_dir, "domains.yaml")
|
||||
domains = Domains.from_file(domain_path)
|
||||
logger.debug("Loaded sysbuild domain data from %s" % (domain_path))
|
||||
logger.debug(f"Loaded sysbuild domain data from {domain_path}")
|
||||
self.instance.domains = domains
|
||||
domain_build = domains.get_default_domain().build_dir
|
||||
cmake_cache_path = os.path.join(domain_build, "CMakeCache.txt")
|
||||
|
@ -749,7 +749,7 @@ class FilterBuilder(CMake):
|
|||
m = self.config_re.match(line)
|
||||
if not m:
|
||||
if line.strip() and not line.startswith("#"):
|
||||
sys.stderr.write("Unrecognized line %s\n" % line)
|
||||
sys.stderr.write(f"Unrecognized line {line}\n")
|
||||
continue
|
||||
defconfig[m.group(1)] = m.group(2).strip()
|
||||
|
||||
|
@ -796,8 +796,7 @@ class FilterBuilder(CMake):
|
|||
ret = expr_parser.parse(self.testsuite.filter, filter_data, edt)
|
||||
|
||||
except (ValueError, SyntaxError) as se:
|
||||
sys.stderr.write(
|
||||
"Failed processing %s\n" % self.testsuite.yamlfile)
|
||||
sys.stderr.write(f"Failed processing {self.testsuite.yamlfile}\n")
|
||||
raise se
|
||||
|
||||
if not ret:
|
||||
|
@ -828,13 +827,13 @@ class ProjectBuilder(FilterBuilder):
|
|||
def log_info(self, filename, inline_logs, log_testcases=False):
|
||||
filename = os.path.abspath(os.path.realpath(filename))
|
||||
if inline_logs:
|
||||
logger.info("{:-^100}".format(filename))
|
||||
logger.info(f"{filename:-^100}")
|
||||
|
||||
try:
|
||||
with open(filename) as fp:
|
||||
data = fp.read()
|
||||
except Exception as e:
|
||||
data = "Unable to read log data (%s)\n" % (str(e))
|
||||
data = f"Unable to read log data ({e!s})\n"
|
||||
|
||||
# Remove any coverage data from the dumped logs
|
||||
data = re.sub(
|
||||
|
@ -845,7 +844,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
)
|
||||
logger.error(data)
|
||||
|
||||
logger.info("{:-^100}".format(filename))
|
||||
logger.info(f"{filename:-^100}")
|
||||
|
||||
if log_testcases:
|
||||
for tc in self.instance.testcases:
|
||||
|
@ -862,25 +861,25 @@ class ProjectBuilder(FilterBuilder):
|
|||
|
||||
def log_info_file(self, inline_logs):
|
||||
build_dir = self.instance.build_dir
|
||||
h_log = "{}/handler.log".format(build_dir)
|
||||
he_log = "{}/handler_stderr.log".format(build_dir)
|
||||
b_log = "{}/build.log".format(build_dir)
|
||||
v_log = "{}/valgrind.log".format(build_dir)
|
||||
d_log = "{}/device.log".format(build_dir)
|
||||
pytest_log = "{}/twister_harness.log".format(build_dir)
|
||||
h_log = f"{build_dir}/handler.log"
|
||||
he_log = f"{build_dir}/handler_stderr.log"
|
||||
b_log = f"{build_dir}/build.log"
|
||||
v_log = f"{build_dir}/valgrind.log"
|
||||
d_log = f"{build_dir}/device.log"
|
||||
pytest_log = f"{build_dir}/twister_harness.log"
|
||||
|
||||
if os.path.exists(v_log) and "Valgrind" in self.instance.reason:
|
||||
self.log_info("{}".format(v_log), inline_logs)
|
||||
self.log_info(f"{v_log}", inline_logs)
|
||||
elif os.path.exists(pytest_log) and os.path.getsize(pytest_log) > 0:
|
||||
self.log_info("{}".format(pytest_log), inline_logs, log_testcases=True)
|
||||
self.log_info(f"{pytest_log}", inline_logs, log_testcases=True)
|
||||
elif os.path.exists(h_log) and os.path.getsize(h_log) > 0:
|
||||
self.log_info("{}".format(h_log), inline_logs)
|
||||
self.log_info(f"{h_log}", inline_logs)
|
||||
elif os.path.exists(he_log) and os.path.getsize(he_log) > 0:
|
||||
self.log_info("{}".format(he_log), inline_logs)
|
||||
self.log_info(f"{he_log}", inline_logs)
|
||||
elif os.path.exists(d_log) and os.path.getsize(d_log) > 0:
|
||||
self.log_info("{}".format(d_log), inline_logs)
|
||||
self.log_info(f"{d_log}", inline_logs)
|
||||
else:
|
||||
self.log_info("{}".format(b_log), inline_logs)
|
||||
self.log_info(f"{b_log}", inline_logs)
|
||||
|
||||
|
||||
def _add_to_pipeline(self, pipeline, op: str, additionals: dict=None):
|
||||
|
@ -913,7 +912,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
else:
|
||||
# Here we check the dt/kconfig filter results coming from running cmake
|
||||
if self.instance.name in ret['filter'] and ret['filter'][self.instance.name]:
|
||||
logger.debug("filtering %s" % self.instance.name)
|
||||
logger.debug(f"filtering {self.instance.name}")
|
||||
self.instance.status = TwisterStatus.FILTER
|
||||
self.instance.reason = "runtime filter"
|
||||
results.filtered_runtime_increment()
|
||||
|
@ -939,14 +938,14 @@ class ProjectBuilder(FilterBuilder):
|
|||
next_op = 'report'
|
||||
elif self.options.cmake_only:
|
||||
if self.instance.status == TwisterStatus.NONE:
|
||||
logger.debug("CMake only: PASS %s" % self.instance.name)
|
||||
logger.debug(f"CMake only: PASS {self.instance.name}")
|
||||
self.instance.status = TwisterStatus.NOTRUN
|
||||
self.instance.add_missing_case_status(TwisterStatus.NOTRUN, 'CMake only')
|
||||
next_op = 'report'
|
||||
else:
|
||||
# Here we check the runtime filter results coming from running cmake
|
||||
if self.instance.name in ret['filter'] and ret['filter'][self.instance.name]:
|
||||
logger.debug("filtering %s" % self.instance.name)
|
||||
logger.debug(f"filtering {self.instance.name}")
|
||||
self.instance.status = TwisterStatus.FILTER
|
||||
self.instance.reason = "runtime filter"
|
||||
results.filtered_runtime_increment()
|
||||
|
@ -966,7 +965,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
|
||||
elif op == "build":
|
||||
try:
|
||||
logger.debug("build test: %s" % self.instance.name)
|
||||
logger.debug(f"build test: {self.instance.name}")
|
||||
ret = self.build()
|
||||
if not ret:
|
||||
self.instance.status = TwisterStatus.ERROR
|
||||
|
@ -1033,7 +1032,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
# Run the generated binary using one of the supported handlers
|
||||
elif op == "run":
|
||||
try:
|
||||
logger.debug("run test: %s" % self.instance.name)
|
||||
logger.debug(f"run test: {self.instance.name}")
|
||||
self.run()
|
||||
logger.debug(f"run status: {self.instance.name} {self.instance.status}")
|
||||
|
||||
|
@ -1176,7 +1175,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
def cleanup_artifacts(self, additional_keep: list[str] = None):
|
||||
if additional_keep is None:
|
||||
additional_keep = []
|
||||
logger.debug("Cleaning up {}".format(self.instance.build_dir))
|
||||
logger.debug(f"Cleaning up {self.instance.build_dir}")
|
||||
allow = [
|
||||
os.path.join('zephyr', '.config'),
|
||||
'handler.log',
|
||||
|
@ -1214,7 +1213,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
os.rmdir(path)
|
||||
|
||||
def cleanup_device_testing_artifacts(self):
|
||||
logger.debug("Cleaning up for Device Testing {}".format(self.instance.build_dir))
|
||||
logger.debug(f"Cleaning up for Device Testing {self.instance.build_dir}")
|
||||
|
||||
files_to_keep = self._get_binaries()
|
||||
files_to_keep.append(os.path.join('zephyr', 'runners.yaml'))
|
||||
|
@ -1427,11 +1426,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
status += " " + instance.reason
|
||||
else:
|
||||
logger.error(
|
||||
"{:<25} {:<50} {}: {}".format(
|
||||
instance.platform.name,
|
||||
instance.testsuite.name,
|
||||
status,
|
||||
instance.reason))
|
||||
f"{instance.platform.name:<25} {instance.testsuite.name:<50} {status}: {instance.reason}")
|
||||
if not self.options.verbose:
|
||||
self.log_info_file(self.options.inline_logs)
|
||||
elif instance.status == TwisterStatus.SKIP:
|
||||
|
@ -1458,7 +1453,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
if instance.dut:
|
||||
more_info += f": {instance.dut},"
|
||||
if htime:
|
||||
more_info += " {:.3f}s".format(htime)
|
||||
more_info += f" {htime:.3f}s"
|
||||
else:
|
||||
more_info = "build"
|
||||
|
||||
|
@ -1466,9 +1461,11 @@ class ProjectBuilder(FilterBuilder):
|
|||
and hasattr(self.instance.handler, 'seed')
|
||||
and self.instance.handler.seed is not None ):
|
||||
more_info += "/seed: " + str(self.options.seed)
|
||||
logger.info("{:>{}}/{} {:<25} {:<50} {} ({})".format(
|
||||
results.done - results.filtered_static, total_tests_width, total_to_do , instance.platform.name,
|
||||
instance.testsuite.name, status, more_info))
|
||||
logger.info(
|
||||
f"{results.done - results.filtered_static:>{total_tests_width}}/{total_to_do}"
|
||||
f" {instance.platform.name:<25} {instance.testsuite.name:<50}"
|
||||
f" {status} ({more_info})"
|
||||
)
|
||||
|
||||
if self.options.verbose > 1:
|
||||
for tc in self.instance.testcases:
|
||||
|
@ -1484,26 +1481,33 @@ class ProjectBuilder(FilterBuilder):
|
|||
if total_to_do > 0:
|
||||
completed_perc = int((float(results.done - results.filtered_static) / total_to_do) * 100)
|
||||
|
||||
sys.stdout.write("INFO - Total complete: %s%4d/%4d%s %2d%% built (not run): %s%4d%s, filtered: %s%4d%s, failed: %s%4d%s, error: %s%4d%s\r" % (
|
||||
TwisterStatus.get_color(TwisterStatus.PASS),
|
||||
results.done - results.filtered_static,
|
||||
total_to_do,
|
||||
Fore.RESET,
|
||||
completed_perc,
|
||||
TwisterStatus.get_color(TwisterStatus.NOTRUN),
|
||||
results.notrun,
|
||||
Fore.RESET,
|
||||
TwisterStatus.get_color(TwisterStatus.SKIP) if results.filtered_configs > 0 else Fore.RESET,
|
||||
results.filtered_configs,
|
||||
Fore.RESET,
|
||||
TwisterStatus.get_color(TwisterStatus.FAIL) if results.failed > 0 else Fore.RESET,
|
||||
results.failed,
|
||||
Fore.RESET,
|
||||
TwisterStatus.get_color(TwisterStatus.ERROR) if results.error > 0 else Fore.RESET,
|
||||
results.error,
|
||||
Fore.RESET
|
||||
)
|
||||
)
|
||||
unfiltered = results.done - results.filtered_static
|
||||
filtered_section_color = (
|
||||
TwisterStatus.get_color(TwisterStatus.SKIP)
|
||||
if results.filtered_configs > 0
|
||||
else Fore.RESET
|
||||
)
|
||||
failed_section_color = (
|
||||
TwisterStatus.get_color(TwisterStatus.FAIL) if results.failed > 0 else Fore.RESET
|
||||
)
|
||||
error_section_color = (
|
||||
TwisterStatus.get_color(TwisterStatus.ERROR) if results.error > 0 else Fore.RESET
|
||||
)
|
||||
sys.stdout.write(
|
||||
f"INFO - Total complete: "
|
||||
f"{TwisterStatus.get_color(TwisterStatus.PASS)}"
|
||||
f"{unfiltered:>4}/{total_to_do:>4}"
|
||||
f"{Fore.RESET} {completed_perc:>2}%"
|
||||
" built (not run):"
|
||||
f" {TwisterStatus.get_color(TwisterStatus.NOTRUN)}{results.notrun:>4}{Fore.RESET},"
|
||||
" filtered:"
|
||||
f" {filtered_section_color}{results.filtered_configs:>4}{Fore.RESET},"
|
||||
" failed:"
|
||||
f" {failed_section_color}{results.failed:>4}{Fore.RESET},"
|
||||
" error:"
|
||||
f" {error_section_color}{results.error:>4}{Fore.RESET}\r"
|
||||
)
|
||||
|
||||
sys.stdout.flush()
|
||||
|
||||
@staticmethod
|
||||
|
@ -1535,7 +1539,7 @@ class ProjectBuilder(FilterBuilder):
|
|||
overlays.append(additional_overlay_path)
|
||||
|
||||
if overlays:
|
||||
args.append("OVERLAY_CONFIG=\"%s\"" % (" ".join(overlays)))
|
||||
args.append(f"OVERLAY_CONFIG=\"{' '.join(overlays)}\"")
|
||||
|
||||
# Build the final argument list
|
||||
args_expanded.extend(["-D{}".format(a.replace('"', '\"')) for a in cmake_extra_args])
|
||||
|
@ -1703,7 +1707,7 @@ class TwisterRunner:
|
|||
else:
|
||||
self.jobserver = JobClient()
|
||||
|
||||
logger.info("JOBS: %d", self.jobs)
|
||||
logger.info(f"JOBS: {self.jobs}")
|
||||
|
||||
self.update_counting_before_pipeline()
|
||||
|
||||
|
@ -1711,7 +1715,7 @@ class TwisterRunner:
|
|||
self.results.iteration_increment()
|
||||
|
||||
if self.results.iteration > 1:
|
||||
logger.info("%d Iteration:" % (self.results.iteration))
|
||||
logger.info(f"{self.results.iteration} Iteration:")
|
||||
time.sleep(self.options.retry_interval) # waiting for the system to settle down
|
||||
self.results.done = self.results.total - self.results.failed
|
||||
self.results.failed = 0
|
||||
|
@ -1762,12 +1766,12 @@ class TwisterRunner:
|
|||
self.results.error_increment()
|
||||
|
||||
def show_brief(self):
|
||||
logger.info("%d test scenarios (%d configurations) selected, "
|
||||
"%d configurations filtered (%d by static filter, %d at runtime)." %
|
||||
(len(self.suites), len(self.instances),
|
||||
self.results.filtered_configs,
|
||||
self.results.filtered_static,
|
||||
self.results.filtered_configs - self.results.filtered_static))
|
||||
logger.info(
|
||||
f"{len(self.suites)} test scenarios ({len(self.instances)} configurations) selected,"
|
||||
f" {self.results.filtered_configs} configurations filtered"
|
||||
f" ({self.results.filtered_static} by static filter,"
|
||||
f" {self.results.filtered_configs - self.results.filtered_static} at runtime)."
|
||||
)
|
||||
|
||||
def add_tasks_to_queue(self, pipeline, build_only=False, test_only=False, retry_build_errors=False):
|
||||
for instance in self.instances.values():
|
||||
|
|
|
@ -132,12 +132,12 @@ class SizeCalculator:
|
|||
print(self.elf_filename)
|
||||
print("SECTION NAME VMA LMA SIZE HEX SZ TYPE")
|
||||
for v in self.sections:
|
||||
print("%-17s 0x%08x 0x%08x %8d 0x%05x %-7s" %
|
||||
(v["name"], v["virt_addr"], v["load_addr"], v["size"], v["size"],
|
||||
v["type"]))
|
||||
print(
|
||||
f'{v["name"]:<17} {v["virt_addr"]:#010x} {v["load_addr"]:#010x}'
|
||||
f' {v["size"]:>8} {v["size"]:#07x} {v["type"]:<7}'
|
||||
)
|
||||
|
||||
print("Totals: %d bytes (ROM), %d bytes (RAM)" %
|
||||
(self.used_rom, self.used_ram))
|
||||
print(f"Totals: {self.used_rom} bytes (ROM), {self.used_ram} bytes (RAM)")
|
||||
print("")
|
||||
|
||||
def get_used_ram(self):
|
||||
|
@ -196,7 +196,7 @@ class SizeCalculator:
|
|||
|
||||
try:
|
||||
if magic != b'\x7fELF':
|
||||
raise TwisterRuntimeError("%s is not an ELF binary" % self.elf_filename)
|
||||
raise TwisterRuntimeError(f"{self.elf_filename} is not an ELF binary")
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
sys.exit(2)
|
||||
|
@ -212,7 +212,7 @@ class SizeCalculator:
|
|||
"utf-8").strip()
|
||||
try:
|
||||
if is_xip_output.endswith("no symbols"):
|
||||
raise TwisterRuntimeError("%s has no symbol information" % self.elf_filename)
|
||||
raise TwisterRuntimeError(f"{self.elf_filename} has no symbol information")
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
sys.exit(2)
|
||||
|
|
|
@ -397,4 +397,4 @@ class TestInstance:
|
|||
return buildlog_paths[0]
|
||||
|
||||
def __repr__(self):
|
||||
return "<TestSuite %s on %s>" % (self.testsuite.name, self.platform.name)
|
||||
return f"<TestSuite {self.testsuite.name} on {self.platform.name}>"
|
||||
|
|
|
@ -175,7 +175,7 @@ class TestPlan:
|
|||
if self.run_individual_testsuite:
|
||||
logger.info("Running the following tests:")
|
||||
for test in self.run_individual_testsuite:
|
||||
print(" - {}".format(test))
|
||||
print(f" - {test}")
|
||||
else:
|
||||
raise TwisterRuntimeError("Tests not found")
|
||||
|
||||
|
@ -217,7 +217,7 @@ class TestPlan:
|
|||
def load(self):
|
||||
|
||||
if self.options.report_suffix:
|
||||
last_run = os.path.join(self.options.outdir, "twister_{}.json".format(self.options.report_suffix))
|
||||
last_run = os.path.join(self.options.outdir, f"twister_{self.options.report_suffix}.json")
|
||||
else:
|
||||
last_run = os.path.join(self.options.outdir, "twister.json")
|
||||
|
||||
|
@ -262,7 +262,7 @@ class TestPlan:
|
|||
raise TwisterRuntimeError("subset should not exceed the total number of sets")
|
||||
|
||||
if int(subset) > 0 and int(sets) >= int(subset):
|
||||
logger.info("Running only a subset: %s/%s" % (subset, sets))
|
||||
logger.info(f"Running only a subset: {subset}/{sets}")
|
||||
else:
|
||||
raise TwisterRuntimeError(f"You have provided a wrong subset value: {self.options.subset}.")
|
||||
|
||||
|
@ -347,9 +347,9 @@ class TestPlan:
|
|||
if dupes:
|
||||
msg = "Duplicated test scenarios found:\n"
|
||||
for dupe in dupes:
|
||||
msg += ("- {} found in:\n".format(dupe))
|
||||
msg += (f"- {dupe} found in:\n")
|
||||
for dc in self.get_testsuite(dupe):
|
||||
msg += (" - {}\n".format(dc.yamlfile))
|
||||
msg += (f" - {dc.yamlfile}\n")
|
||||
raise TwisterRuntimeError(msg)
|
||||
else:
|
||||
logger.debug("No duplicates found.")
|
||||
|
@ -360,7 +360,7 @@ class TestPlan:
|
|||
tags = tags.union(tc.tags)
|
||||
|
||||
for t in tags:
|
||||
print("- {}".format(t))
|
||||
print(f"- {t}")
|
||||
|
||||
def report_test_tree(self):
|
||||
tests_list = self.get_tests_list()
|
||||
|
@ -399,7 +399,7 @@ class TestPlan:
|
|||
Node(test, parent=subarea)
|
||||
|
||||
for pre, _, node in RenderTree(testsuite):
|
||||
print("%s%s" % (pre, node.name))
|
||||
print(f"{pre}{node.name}")
|
||||
|
||||
def report_test_list(self):
|
||||
tests_list = self.get_tests_list()
|
||||
|
@ -407,8 +407,8 @@ class TestPlan:
|
|||
cnt = 0
|
||||
for test in sorted(tests_list):
|
||||
cnt = cnt + 1
|
||||
print(" - {}".format(test))
|
||||
print("{} total.".format(cnt))
|
||||
print(f" - {test}")
|
||||
print(f"{cnt} total.")
|
||||
|
||||
|
||||
# Debug Functions
|
||||
|
@ -550,7 +550,7 @@ class TestPlan:
|
|||
for root in self.env.test_roots:
|
||||
root = os.path.abspath(root)
|
||||
|
||||
logger.debug("Reading test case configuration files under %s..." % root)
|
||||
logger.debug(f"Reading test case configuration files under {root}...")
|
||||
|
||||
for dirpath, _, filenames in os.walk(root, topdown=True):
|
||||
if self.SAMPLE_FILENAME in filenames:
|
||||
|
@ -570,8 +570,9 @@ class TestPlan:
|
|||
os.path.relpath(suite_path, root),
|
||||
filename)
|
||||
if os.path.exists(alt_config):
|
||||
logger.info("Using alternative configuration from %s" %
|
||||
os.path.normpath(alt_config))
|
||||
logger.info(
|
||||
f"Using alternative configuration from {os.path.normpath(alt_config)}"
|
||||
)
|
||||
suite_yaml_path = alt_config
|
||||
break
|
||||
|
||||
|
@ -981,7 +982,9 @@ class TestPlan:
|
|||
# Search and check that all required snippet files are found
|
||||
for this_snippet in snippet_args['snippets']:
|
||||
if this_snippet not in found_snippets:
|
||||
logger.error("Can't find snippet '%s' for test '%s'", this_snippet, ts.name)
|
||||
logger.error(
|
||||
f"Can't find snippet '{this_snippet}' for test '{ts.name}'"
|
||||
)
|
||||
instance.status = TwisterStatus.ERROR
|
||||
instance.reason = f"Snippet {this_snippet} not found"
|
||||
missing_snippet = True
|
||||
|
|
|
@ -301,9 +301,8 @@ def scan_testsuite_path(testsuite_path):
|
|||
try:
|
||||
result: ScanPathResult = scan_file(filename)
|
||||
if result.warnings:
|
||||
logger.error("%s: %s" % (filename, result.warnings))
|
||||
raise TwisterRuntimeError(
|
||||
"%s: %s" % (filename, result.warnings))
|
||||
logger.error(f"{filename}: {result.warnings}")
|
||||
raise TwisterRuntimeError(f"{filename}: {result.warnings}")
|
||||
if result.matches:
|
||||
subcases += result.matches
|
||||
if result.has_registered_test_suites:
|
||||
|
@ -316,7 +315,7 @@ def scan_testsuite_path(testsuite_path):
|
|||
ztest_suite_names += result.ztest_suite_names
|
||||
|
||||
except ValueError as e:
|
||||
logger.error("%s: error parsing source file: %s" % (filename, e))
|
||||
logger.error(f"{filename}: error parsing source file: {e}")
|
||||
|
||||
src_dir_pathlib_path = Path(src_dir_path)
|
||||
for filename in find_c_files_in(testsuite_path):
|
||||
|
@ -328,13 +327,13 @@ def scan_testsuite_path(testsuite_path):
|
|||
try:
|
||||
result: ScanPathResult = scan_file(filename)
|
||||
if result.warnings:
|
||||
logger.error("%s: %s" % (filename, result.warnings))
|
||||
logger.error(f"{filename}: {result.warnings}")
|
||||
if result.matches:
|
||||
subcases += result.matches
|
||||
if result.ztest_suite_names:
|
||||
ztest_suite_names += result.ztest_suite_names
|
||||
except ValueError as e:
|
||||
logger.error("%s: can't find: %s" % (filename, e))
|
||||
logger.error(f"{filename}: can't find: {e}")
|
||||
|
||||
if (has_registered_test_suites and has_test_main and
|
||||
not has_run_registered_test_suites):
|
||||
|
@ -388,7 +387,7 @@ class TestCase(DisablePyTestCollectionMixin):
|
|||
return self.name < other.name
|
||||
|
||||
def __repr__(self):
|
||||
return "<TestCase %s with %s>" % (self.name, self.status)
|
||||
return f"<TestCase {self.name} with {self.status}>"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -469,7 +468,7 @@ class TestSuite(DisablePyTestCollectionMixin):
|
|||
else:
|
||||
# only add each testcase once
|
||||
for sub in set(parsed_subcases):
|
||||
name = "{}.{}".format(self.id, sub)
|
||||
name = f"{self.id}.{sub}"
|
||||
self.add_testcase(name)
|
||||
|
||||
if suite_names:
|
||||
|
|
|
@ -82,13 +82,13 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace):
|
|||
sys.exit(f"Can't compare metrics with non existing file {ls}")
|
||||
elif os.path.exists(options.outdir):
|
||||
if options.clobber_output:
|
||||
print("Deleting output directory {}".format(options.outdir))
|
||||
print(f"Deleting output directory {options.outdir}")
|
||||
shutil.rmtree(options.outdir)
|
||||
else:
|
||||
for i in range(1, 100):
|
||||
new_out = options.outdir + ".{}".format(i)
|
||||
new_out = options.outdir + f".{i}"
|
||||
if not os.path.exists(new_out):
|
||||
print("Renaming output directory to {}".format(new_out))
|
||||
print(f"Renaming output directory to {new_out}")
|
||||
shutil.move(options.outdir, new_out)
|
||||
break
|
||||
else:
|
||||
|
@ -141,13 +141,7 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace):
|
|||
if options.platform and not tplan.check_platform(i.platform, options.platform):
|
||||
continue
|
||||
logger.debug(
|
||||
"{:<25} {:<50} {}SKIPPED{}: {}".format(
|
||||
i.platform.name,
|
||||
i.testsuite.name,
|
||||
Fore.YELLOW,
|
||||
Fore.RESET,
|
||||
i.reason,
|
||||
)
|
||||
f"{i.platform.name:<25} {i.testsuite.name:<50} {Fore.YELLOW}SKIPPED{Fore.RESET}: {i.reason}"
|
||||
)
|
||||
|
||||
report = Reporting(tplan, env)
|
||||
|
@ -173,7 +167,7 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace):
|
|||
|
||||
if options.dry_run:
|
||||
duration = time.time() - start_time
|
||||
logger.info("Completed in %d seconds" % (duration))
|
||||
logger.info(f"Completed in {duration} seconds")
|
||||
return 0
|
||||
|
||||
if options.short_build_path:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue