With --retry-failed, add_tasks_to_queue() resets the status of a failed
instance before queueing it again, but leaves the per-testcase statuses
from the failed attempt in place.
When the first attempt fails before any output is seen (for example
"Timeout during flashing" on a hardware target), every testcase is
marked blocked. On the retry, only cases that print a result are
updated. Cases that never report, such as ztest cases compiled out of
the image for the current configuration, keep the stale blocked status
and reason, so twister.json shows blocked testcases inside a suite whose
final status is passed. A clean run without a retry reports no status
for those same cases.
Clear the status, reason, duration and output of every testcase after
removing the previous attempt from the status counts, so a retried run
reports the same testcase results as a run that passed first time.
Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
The QEMU adapter closes the console FIFO while its reader thread can
still be blocked in read(). On macOS this hangs pytest teardown, even
after the test itself has passed.
Stop QEMU first so that its end of the FIFO closes and the reader
returns. Only then release the handles.
Fixes: 1b7810f0cb ("scripts: twister: Support multiple ports in
pytest-twister-harness")
Signed-off-by: Chao Liu <chao.liu@processmission.com>
A test case can be declared static ZTEST(), which makes its statistics
object static too; many Bluetooth tests do so. The source scan matches
only lines that start with ZTEST, so it misses those cases: --list-tests
leaves them out, --sub-test cannot select them, and they are known only
from the runtime output. On main this concerns 369 test cases in 22 test
directories.
Accept an optional static before the macro in both test case patterns.
Tested with the twister unit tests and with --list-tests over
tests/bluetooth.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Bluetooth Classic tests on native_sim need linked virtual controllers
and one Zephyr instance per device. Without host-side support every
test carries shell scripts that allocate TCP ports, start and stop the
controllers and launch the peers, and that depend on the layout of the
twister output directory.
The "bumble" sidecar provisions this from sidecar_config, so a test
keeps its normal harness and ships no scripts. The controllers bind
kernel-chosen ports and report them to the sidecar, since a port
picked up front can be taken by a parallel worker before it is bound.
The handler watches the guest only, so the sidecar reads the Ztest
results the peers printed and reports the cases they ran, and the
peers share the scenario's timeout with the guest. On a host without
Bumble the test is built but not run.
Based on Anas Nashif's proof of concept for the pre-merge sidecar
framework (nashif/zephyr commit 099427868f7).
Tested on native_sim with Bumble 0.0.220: the acl_conn test passes
with both of its cases reported, also as three instances run in
parallel, and is only built when Bumble is missing.
Assisted-by: Claude:claude-fable-5.1
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
ESP32-P4, C5, C6, C61 and H2 name their RAM region sram0_0_seg, which
the overflow pattern did not match, so a too large image was reported
as a build error instead of an overflow skip like on the other ESP32
SoCs.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
Ninja 1.13 became a GNU make job server client, but on POSIX it accepts
the job server only as a named pipe. Twister hands out a pair of file
descriptors, so Ninja warns "Ignoring jobserver: Pipe-based protocol is
not supported!" and every build twister runs in parallel starts its own
full set of jobs: a load average of 150 and 11 GB of anonymous memory
for tests/bluetooth on native_sim on a 24-thread machine.
Create the job server as a named pipe when the build tool takes that
form (Ninja from 1.13, GNU make from 4.4) and no make on PATH is older
than GNU make 4.4: such a make stops with an error on a named pipe, and
native builds run make below Ninja. Otherwise, and when extra CMake
arguments select the tools, the file descriptors are passed as before.
Tested with Ninja 1.13.2 and GNU make 4.4.1: without ccache the run
above takes 425 to 438 s instead of 477 s and peaks at 4.4 GB.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
The twister Test harness attributes every Ztest suite/case marker it
parses to the current run. When a device restarts mid-run -- because it
reboots on its own, or because console output was captured from a
previously-programmed image while the board was still being flashed (the
default flash_before=False opens the serial port before flashing) -- the
markers seen before the restart are left pending. They never reach a
terminal status, so they surface as phantom 'started' cases and produce
spurious 'already STARTED' warnings once the real run re-emits the same
markers.
Discard that stale state when a restart is detected, keyed on two signals
that Ztest emits itself rather than on any application artifact:
- A start marker for a suite or case that is already running. Ztest emits
these itself, so whenever there is stale state to discard the evidence
of the restart is already present, with no dependency on any Kconfig.
This replaces the 'already STARTED' warnings the harness logged for
these restarts (729 across an 1841-log device-run replay corpus) with a
correct recovery.
- The "RunID started:" marker that TC_PRINT_RUNID_START prints at the
start of every run. A second one seen while markers are still pending
proves the image restarted, so it catches a restart that never re-emits
a marker that is still pending. It is emitted on every boot when a run
id is set, and nothing is printed otherwise.
A suite that ends before starting again is a legitimate repeat and is
left alone, as is any suite declaring expect_reboot.
An earlier revision used the Zephyr boot banner for the second signal.
The banner is an application artifact and is optional; the RunID marker
is part of the test output and does not depend on CONFIG_BOOT_BANNER.
Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
The CPE was only emitted when an exact vX.Y.Z tag pointed at the built
revision, leaving zephyr-sources and zephyr-deps with no version and no
CPE on every other build, release candidates included. Fall back to the
VERSION file and map EXTRAVERSION onto the CPE update field, so an rc is
recorded as cpe:2.3⭕zephyrproject:zephyr:4.4.0:rc3:*:*:*:*:*:*.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The Script/Pytest/Bsim/Ctest harnesses read the spawned process output
in _output_reader() and decode it as strict UTF-8. A single invalid
byte, which is common on a hardware serial console, raises
UnicodeDecodeError. That kills the reader thread and stops capturing
the rest of the process output for the run.
Decode with errors="replace" so a stray byte no longer aborts output
capture.
Signed-off-by: Kevin Chan <kevin.chan3@infineon.com>
When a testsuite uses required_devices/required_applications, twister
locates the companion application's build directory with a regular
expression built from forward slashes ("{platform}/.*/{application}").
On Windows the build_dir is produced with os.path.join(), so it uses
backslashes and the pattern never matches. twister then reports
"Could not find a build dir for required application" even though the
directory exists. The glob that locates a pre-built required
application makes the same forward-slash assumption.
Normalize os.sep to "/" before matching so the lookup works on both
POSIX and Windows.
Signed-off-by: Kevin Chan <kevin.chan3@infineon.com>
Project.from_directory() globs the whole component tree for REUSE.toml
and drops ignored paths only afterwards. The zephyr-sources component
is rooted at the west topdir, which is not a git repository, so every
run walked all modules, virtualenvs and build directories in the
workspace: 86 s for hello_world in a workspace with many worktrees.
A REUSE.toml only covers its own directory tree, so only check the
ancestor directories of the files being scanned and build the Project
from those. The generated documents are unchanged; the same run takes
2.4 s.
The slowdown came with commit bc14cfbb1b ("scripts: zspdx: scanner:
load REUSE.toml, surface its licenses").
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
Match the complete name GoogleTest prints and derive the internal test
name from it by replacing "/" with ".", so no index or generator name
can be lost. This supports TEST, TEST_F, TYPED_TEST, TYPED_TEST_P and
TEST_P, each with a default or custom name and, for TEST_P, with or
without an instantiation prefix.
Fixes: ba480d810b ("twister: add support for gtest parametrized tests")
Signed-off-by: Mario Jaun <mario.jaun@zuehlke.com>
SPDX 3 element IDs were shortened to "zephyr:..." through namespaceMap,
which JSON-LD consumers do not expand, and License List licenses were
defined at their https://spdx.org/licenses/ IRIs. Both are the same IRIs
in every build, so the documents of separate builds, such as sysbuild
images, merged into conflicting elements when combined.
Write full IRIs under the namespace prefix, and define License List
licenses as license expressions in that namespace like custom ones.
Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
When running native_sim tests with --coverage, harness.capture_coverage
is False (it is only True when dumping coverage over serial console with
CONFIG_COVERAGE_DUMP). Once a test prints its final pass status,
BinaryHandler._output_handler resets timeout_time to time.time() + 2
and waits for stdout EOF before calling proc.wait(0.1) and terminate().
Under heavy parallel I/O, __gcov_exit() can take longer than 2.6s to
write all .gcda files before exiting and closing stdout, causing Twister
to SIGKILL zephyr.exe mid-__gcov_exit() and leave truncated 0-byte or
missing .gcda files. Extend timeout_time by COVERAGE_TIMEOUT_EXTENSION
(30s) when self.options.enable_coverage is set.
Signed-off-by: Jeremy Bettis <jbettis@google.com>
ScannerConfig.do_md5 was off by default and nothing enables it, so
every file was hashed with MD5 only for the result to be discarded.
Drop the MD5 hash, its option and its serializer branches, and remove
MD5 from the hashes the documentation lists.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
Compute a SHA512 hash for every file alongside SHA1 and SHA256, and
emit it as a FileChecksum in SPDX 2.x and as a verifiedUsing hash in
SPDX 3.x. Like SHA256, it is enabled by default through
ScannerConfig.do_sha512.
Extend the SBOM integration test to check the SHA512 of main.c.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
When the command line argument for twister is used to treat
warnings as errors, will also set the same option for treating
deprecated Kconfigs as errors, this allows CI compliance to ensure
that the API lifecycle process is followed
Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
The handlers fill in a reason of their own, such as the exit code,
only when the instance has none. The JSON report, however, writes a
placeholder reason, "Unknown Instance status", for every suite that
has not run, which is every suite in a test plan saved before
running, and loading that plan with --load-tests restores the
placeholder along with the unset status. A run that then fails
keeps the placeholder over the exit code, which is how CI reports
a QEMU that could not start.
Write no reason for a suite that has not run, do not restore one
for such a suite from a loaded plan, and clear the reason together
with the status before every run so that neither a loaded plan nor
an earlier retry iteration can leak one into the new result.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The QEMU monitor thread opens the console fifos as QEMU's
counterpart, and each of those opens blocks until QEMU opens the
other end. When the run command fails to start QEMU at all, the
thread sits in open() with nothing to wait for while the handler
joins it for the whole test timeout: a QEMU binary that cannot be
executed costs the full timeout per test, several minutes in CI,
before being reported as a timeout.
Once the run command has exited, give the thread a moment to drain
what QEMU left in the pipe. If it is still around after that it is
blocked on the fifos, so connect to them in QEMU's place and
disconnect again: the opens return, the thread reads EOF and
finishes at once. If QEMU never wrote its pid file, drop the EOF
reason the thread recorded so the exit code names the failure.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The QEMU handler captures the run command's stderr to qemu.stderr, a
file nothing reads: neither the inline log printed for a failure nor
the JSON report look at it. When QEMU cannot start at all, because
the binary is not found, refuses an option or fails to load a
library, the console log stays empty and twister prints build.log,
a log of a build that succeeded, and records nothing about why the
test did not run.
Capture that stderr as handler_stderr.log instead, the file the
binary handler already uses and that both the inline log and the
JSON report read. The run command's stdout stays in qemu.stdout.
The inline log printed for a failure also appends handler_stderr.log
to a non-empty console log, as the JSON report already does, so a
console log that stops short comes with the stderr that explains it.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Commit 11c210cec9 ("twister: match platform extra args against
aliases") replaced the substring match of platform:<selector>:<arg>
against the platform name with an exact match against its aliases.
Selectors that name only part of a board target, such as
platform:nrf54l:shell_remote_SNIPPET=nordic-flpr, no longer apply. For
example, shell.shell_remote.no_multithreading on
nrf54l15dk/nrf54l15/cpuapp builds the remote image for the application
core and fails with "No IPC node found".
Match the selector as a substring of the platform name as before, and
additionally as an exact alias so a default board target still selects
its default revision. Add a test case for a partial selector.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Match platform extra_args selectors against the aliases associated with
a platform. This lets a default board target select its default revision.
Signed-off-by: Hake Huang <hake.huang@nxp.com>
Add the ability to configure additional runner parameters.
For instance the Raspberry Pi boards require a specific openocd version
with rp2xxx driver support.
Signed-off-by: Joel Guittet <joelguittet@gmail.com>
This reverts commit 9fa96059da.
Treating deprecated Kconfig symbols as errors breaks main CI on several
boards, drivers and module tests that still enable them. Revert until
those are migrated.
Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
When the command line argument for twister is used to treat
warnings as errors, will also set the same option for treating
deprecated Kconfigs as errors, this allows CI compliance to ensure
that the API lifecycle process is followed
Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
Before commit bedba6412a ("twister: Add YAML config file support in
pytest-harness"), twister passed --device-id=<probe_id or id> to the
pytest harness. Since then, twister writes the DUT to
twister_pytest_config.yaml and the harness takes the device ID from its
id key only, so the hardware adapter ignores probe_id even when the
hardware map loader provides it.
Use probe_id when it is set. A --device-id given on the pytest command
line still takes precedence.
Checked the flash command generated by a pytest test for a
native_sim/native/64 build with --device-testing and a pyocd hardware
map entry that sets both keys: it now uses probe_id. Not run on
hardware.
Fixes#112600
Signed-off-by: YunHung Hua <oliverhua.us@gmail.com>
A hardware map entry can set probe_id to override the id passed to the
flash runner, for example when the board is flashed through an external
J-Link probe. The schema accepts the key and the device handler uses
hardware.probe_id when it is set, but HardwareMap.load() does not read
the key, so probe_id is always None and the flash runner gets the id.
The key has not been read since the hardware map entries were turned
into objects in commit 531fe89e80 ("sanitycheck: use multiprcoessing
instead of threads").
Read probe_id when loading the hardware map.
Checked the flash command twister generates for a native_sim/native/64
build with --device-testing and a pyocd hardware map entry that sets
both keys: it now uses probe_id. Not run on hardware.
Signed-off-by: YunHung Hua <oliverhua.us@gmail.com>
Allow a hardware-map entry to set run_with_fixture_only.
Such DUTs are excluded from tests that do not request
fixtures, while fixture tests remain eligible when their
requested fixtures match the DUT.
Add schema validation and unit coverage for map loading
and DUT selection.
Signed-off-by: Hake Huang <hake.huang@nxp.com>
Make whisper depend on cmake WHISPER_BIN, so we do not get twister
trying to execute tests with unavailable simulators.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The generated cmake snippet logic in `snippets_generated.cmake` requires
a full board name match, enforced by the anchoring characters `^...$`,
to apply the relevent overlays.
The python `testplan.py` `required_snippets` filtering currently
enforces a looser filtering of `re.search`. This allows boards to pass
the twister filtering that don't actually support the required snippet.
For example a snippet with board regex of `/nrf54l15dk/nrf54l15/cpuapp/`
when compiled for `nrf54l15dk/nrf54l15/cpuapp/ns` would pass the
twister filtering step, but not apply any snippet in cmake.
Switch `re.search` to `re.fullmatch` to duplicate the CMake logic.
Signed-off-by: Jordan Yates <jordan@embeint.com>
A component carrying a CPE was written out under the CPE product name
while its SPDXID and relationships kept using the component name, and the
SPDX 3.0 serializer never did this. Keep the component name and let the
CPE fill in only the supplier and version.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
commit d2b568433a ("twister: coverage: keep the report when one object
is unreadable") added the flag to the first gcovr call only, so the
ztest filter stage still exits 64 and drops both reports.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
It was left behind by the Document to SBOMGraph migration and only ever
raises NotImplementedError, so it cannot provide the compatibility it
claims. Nothing calls it.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The vendored list was a copy of SPDX license list 3.12 from 2021, so the
288 identifiers added since were demoted to custom LicenseRef- entries.
Read the list from license-expression, already pulled in by reuse, which
tracks the published one.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The twister source scanner extracts ZTEST() testcase names with the
regex [a-zA-Z0-9_]+. For cases whose name is built with the ##
token-paste operator, e.g.
ZTEST(dma_m2m_loop, test_dma##idx##_m2m_loop)
the regex stops at the first # and captures "test_dma", which after the
"test_" prefix is stripped registers a phantom subcase "<suite>.dma".
That case never runs (the real, fully expanded cases such as
test_dma0_m2m_loop are only produced at build time), so every run of
tests/drivers/dma/loop_transfer and other macro-generated ztest suites
reports it as "None status".
Add a negative lookahead so a testcase name immediately followed by a
word character or # is not matched. Token-pasted names are therefore
ignored by the static scan and no longer create phantom subcases; the
real cases continue to be discovered from the harness output at runtime.
Add a scan_file unit test covering a suite that mixes a literal ZTEST
case with token-pasted, macro-generated cases, and extend the
get_all_testsuites expectation with the new fixture's literal case.
Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
When using LCOV v2 with --coverage, geninfo can encounter empty or
invalid .gcda files (such as 0-byte nsi_tasks.gcda generated under the
native simulator). In LCOV v2, gcov errors and parallel child worker
failures are treated as fatal unless explicitly ignored.
Add "gcov,gcov" and "child,child" to the --ignore-errors list in
twister's Lcov tool when LCOV v2 is detected so that coverage capture
does not fail on non-fatal gcov and child errors.
Assisted-by: Antigravity:gemini-1.5-pro
Signed-off-by: Jeremy Bettis <jbettis@google.com>
A run picks a single gcov, but a suite may ask to be built with another
toolchain through integration_toolchains, and a target that faults
mid-dump leaves a truncated .gcda behind. Either one makes gcovr exit
without writing coverage.json, so a whole platform contributes nothing
even though every other object was fine.
Ask gcovr to report what the rest of the run covered instead. Objects
it cannot read are dropped without a message, which is the price of not
losing every other object with them.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
get_version() returns a string, so "10.0" >= "7.0" is false and a gcovr
10 release would silently lose --gcov-object-directory and the
suspicious_hits tolerance. Parse it instead.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Tests that trigger faults on purpose set ignore_faults, which disables
the generic ">>> ZEPHYR FATAL ERROR" crash detection entirely. When
such a test then crashes for real (e.g. testing.ztest.error_hook), the
crash went unrecognized and the run was reported with a twister-side
artifact such as "unexpected eof" or a timeout.
Ztest's fatal-error and assert hooks already make the distinction the
harness needs: they print "Fatal error was unexpected, aborting..." or
"Assert failed was unexpected, aborting..." right before halting when
the fault was not declared as expected by the test. Several tests with
custom hooks print the same message, some in lower case.
Match these markers case-insensitively in Harness.process_test() and
set harness.fault even when fail_on_fault is off, so the handlers
report such runs as "Fault detected while running test" like any
other crash. The hooks' expected-fault messages ("Fatal error
expected as part of test case.") do not contain the markers and are
unaffected.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
When a test crashes with an unexpected fatal error the target halts
and never prints a verdict, so the QEMU monitor kept reading until
the full per-test timeout expired and the run was reported as
"Timeout". The timeout was a twister artifact, not the failure: the
console already contained the ">>> ZEPHYR FATAL ERROR" banner. Other
simulators exit on such a crash and got reported differently again
(e.g. "failed (rc=2)" on mps4 FVP), so the same crash produced
inconsistent results across platforms.
The harness already tracks unexpected fatal errors in harness.fault
(tests that fault on purpose opt out with ignore_faults), and any run
with a recorded fault is already doomed to fail once a verdict
arrives. Use that flag in the handlers:
- The QEMU monitor loops (POSIX and Windows) record the failure as
"Fault detected while running test" as soon as the fault banner is
seen and switch to the short post-status grace period, capturing
the rest of the crash dump instead of waiting out the timeout. A
subsequent EOF no longer overwrites the recorded fault reason with
"unexpected eof".
- BinaryHandler's output loop stops after the same grace period once
a fault is seen, covering simulators such as Arm FVP.
- Handler._update_instance_info() prefers the fault over the derived
"Timeout" or "Exited with <rc>" reasons, so every handler
(including device testing) reports such a crash the same way.
The reason string is shared as FAULT_REASON in constants.py so the
harness and the handlers cannot drift apart.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
_parse_build_failure decides why a link failed from the line before the
one carrying "error: ld returned":
elif "error: ld returned" in line:
if last_warning:
return last_warning
elif "overflowed by" in lines[i - 1]:
return "ld.bfd: region overflowed"
elif "ld.bfd: warning: " in lines[i - 1]:
return "ld.bfd:" + lines[i - 1].split("ld.bfd:", 1)[-1]
At i == 0 that is lines[-1], the last line of the log. So a log whose
first line is the linker error is described by its last line -- and that
line need not even come from the same file, since JsonReport.create()
appends the handler's stderr to the build log before parsing it.
The same failure then gets reported two ways, depending only on whether
anything was printed before the linker error:
[ld error, "ninja: build stopped.", "...overflowed by 4096 bytes"]
-> "ld.bfd: region overflowed"
["[1/2] Building ...", ld error, "ninja: build stopped.",
"...overflowed by 4096 bytes"]
-> "/usr/bin/ld.bfd: error: ld returned 1 exit status"
Nothing precedes the first line, so the answer is the line itself, which
is already what the function returns when the previous line says nothing
in particular.
scripts/ci/twister_report_analyzer.py reads lines[i - 1] the same way,
parsing the same linker output for the CI job summary. It is a separate
tool with no tests of its own, in a directory this change does not
otherwise touch, so it is left for a change of its own.
Signed-off-by: Egemen Tuncarslan <egementuncarslan@hotmail.com>
Assisted-by: Claude:claude-opus-5
For some reasons, there are always lingering QEMU processes
after twister has finished on my computer. So need to try
harder to make sure the QEMU process tree is terminated.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Space-separated lists stopped being split in 714e193340, so "a b" is now
taken verbatim and silently matches nothing. Fail loudly for keys whose
members name a tag, platform, feature or toolchain. extra_args and
extra_configs are exempt: their Kconfig values may contain spaces.
Signed-off-by: Flavio Ceolin <flavio@hubble.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CCACHE_BASEDIR makes ccache rewrite absolute paths below the output
directory into relative ones in the command line it actually runs, so
the include path for the generated headers loses the build directory
and they are recorded relative to it in the .gcno. gcovr resolves them
from neither the object directory nor the source root, and the run
fails with "GCOVR failed with 64".
Skipping the optimization for coverage builds costs nothing: ccache
hashes the absolute object and .gcda paths whenever it generates
coverage data, so objects were never shared between build directories
there anyway. sloppiness=gcno_cwd does not change that; it only drops
the separate hashing of the working directory.
Fixes#117813
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
A sidecar could only discover a missing host tool in setup(), just
before executing the test image. The virtiofs sidecar then skipped
the instance at run time and logged a warning on every host without
a virtiofsd binary, which is noise on CI runners where the daemon is
simply not installed.
Introduce Sidecar.host_ready(), consulted from check_runnable() on a
configured sidecar at test-plan time. When the host lacks what the
sidecar needs, the instance is demoted to build-only, exactly like a
platform whose simulator executable is not installed, instead of the
gap surfacing as a late skip plus a warning. The virtiofs sidecar
implements the hook by checking that a virtiofsd binary was resolved;
the setup() guard remains as a safety net for forced runs.
Document the new lifecycle step and add unit tests for host_ready()
and for its wiring in check_runnable().
Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Zephyr modules declare their binary blobs in module.yml, including the
blob's download URL, version, description and expected sha256. Surface
that provenance in the SBOM for blob files picked up during the walk:
as a FileComment in SPDX 2.3 output and as comment/description on the
software_File in SPDX 3.0 output.
Also cross-check the computed sha256 against the declared one while
scanning, warning when a linked blob does not match what its module
declares.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Vendor blobs (e.g. the STM32WBA BLE controller libraries or the ESP32
Wi-Fi/BT libraries) never appeared in the generated SBOM: the CMake
codemodel only expresses libraries built by other targets, and prebuilt
libraries only show up on the final link command line.
Resolve each linked target's link command fragments instead: path
fragments are used directly (libraries linked as imported targets, as
hal_stm32 does) and -lNAME flags are resolved against the -L search
directories (as hal_espressif does). Resolved libraries outside the
build directory are attributed to their owning component and get a
STATIC_LINK relationship from the target's build product.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>