Repository navigation
coverage: QNX on-target coverage through the score_coverage gcov backend - #626
Conversation
QCC is GCC-based, so QNX coverage uses gcov counters: the tests run in QEMU through score_qnx_unit_tests (run_under_qnx), which brings the .gcda files back; Bazel's own per-test collector turns them into LCOV; score_coverage's gcov reporter (eclipse-score/coverage_tool PR #10) produces the same report as the Linux run. - tools/coverage/BUILD: gcov_reporter_wrapper with backend = "gcov" and the QCC package's gcov. - coverage.bazelrc: coverage:qnx_cov on top of bl-x86_64-qnx (run_under, C++ tests only, Bazel's lcov_merger, the gcov reporter, --instrument_test_targets). - coverage_report_qnx.yml: the QNX build workflow's setup steps (SDP, credential helper, QEMU, KVM) followed by bazel coverage and generate_coverage_html --platform qnx; the artifact is uploaded as baselibs_cpp_coverage_report_qnx. VALIDATION ONLY: MODULE.bazel carries a git_override to the coverage_tool branch; it is replaced by the 0.3.0 registry release once that is published. Rust sources are listed as not-instrumented in the QNX report and measured by the Linux run. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
951166a to
967596c
Compare
|
Documentation preview for this pull request is available at: |
A wildcard build on a Linux host without QNX credentials must not fetch the QNX SDP package the reporter depends on; --coverage_report_generator names the target explicitly. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
|
First real QNX run, job https://github.com/eclipse-score/baselibs/actions/runs/36388596870/job/108819220167 (bl-x86_64-qnx, 278 tests in QEMU): artifact |
The gcov backend for QNX on-target coverage is released. Pin the release commit until the registry entry (bazel_registry PR #519) is merged, then drop the override. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
The release is in the S-CORE Bazel registry; drop the temporary git_override that pinned the release commit. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Bazel derives the default --instrumentation_filter from the packages of the test targets and strips only a trailing /tests to reach the code under test. Our tests live in test/ subpackages, so libraries such as //score/os were outside the guessed filter; the gcov collector then dropped their counters and the QNX report showed them at 0 % (13 % for score/os against 80 % on Linux). Instrument everything under //score. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
…selibs into dcalavrezo_qnx_coverage
0.3.1 requires the explicit --instrumentation_filter this branch already sets, and warns when a report shows the pattern of a library tested from a test/ subpackage without data. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
|
@4og @fbaeuerle could you review this one, please? It moves the coverage pipeline to the qualified |
| # in QEMU through score_qnx_unit_tests, which brings the .gcda counters | ||
| # back. Same-repository branches only: the QNX secrets are not exposed to | ||
| # forks on pull_request events. | ||
| qnx-coverage-report: |
There was a problem hiding this comment.
The generated HTML report completely misses qnx-only targets from this folder https://github.com/eclipse-score/baselibs/tree/main/score/os/qnx
Instead it includes files from score/os/linux which have zero coverage.
I'd expect that both linux and qnx coverage tools produce data only for the code that can be compiled on those platform.
There was a problem hiding this comment.
You are right, and thanks for spotting it: this is a tool limitation, not a baselibs problem. Bazel builds --coverage_report_generator in the exec configuration (BaseRuleClasses.coverageReportGeneratorAttribute with ExecutionTransitionFactory), so the scope aspect resolves every select() for the host platform. On the QNX run that means: the Linux variants are in the allowlist and show 0 % from the host baseline, the QNX variants are not in the allowlist at all. The allowlist is identical for both jobs (978 files). The platform-independent code, the vast majority, is measured correctly from the real QNX run.
Tracked as eclipse-score/coverage_tool#23 with the fix: an explicit target platform on the scope (transition on --platforms), one scope per platform, planned as 0.4.0. Two ways to handle this PR: merge now with the limitation stated in the description and the manual, and the QNX report gets the platform-specific files right with 0.4.0; or hold the PR until 0.4.0. Your call; I lean towards merging, since the Linux report and the whole pipeline are unaffected and the QNX job already gives the shared code.
There was a problem hiding this comment.
Fixed in the tool (eclipse-score/coverage_tool#24, pinned here temporarily) and validated on this branch, run 37473583990:
| QNX before | QNX now | Linux | |
|---|---|---|---|
score/os/qnx/ files in the report |
0 | 56 (7 with data, the rest 0 % or declaration-only) | 0 |
score/os/linux/ files in the report |
16 at 0 % | 0 | 15 |
| allowlist | 978 (identical to Linux) | 976 (QNX-specific) | 978 |
| whole report | 92.2 % lines, 649 files | 89.3 % lines, 684 files | 88.6 %, 655 files |
The scope is now evaluated for the run's platform: coverage_scope_qnx names the QNX platform, and the Linux-only / QNX-only roots sit behind a select(). Rust roots are Linux-only as well (crate_universe marks the crates incompatible with QNX, and gcov cannot measure Rust). Three tool-side fixes came out of the validation: the platform scope must be manual, an incompatible root silently skips every test (now documented with the diagnostic), and the select() in the scope's deps needed the transition on the rule itself. The git override is replaced by the 0.4.0 release before merge.
| # back. Same-repository branches only: the QNX secrets are not exposed to | ||
| # forks on pull_request events. | ||
| qnx-coverage-report: | ||
| name: Coverage bl-x86_64-qnx (gcov, on target) |
There was a problem hiding this comment.
The bl-x86_64-qnx got recently renamed to score-qnx-x86_64
There was a problem hiding this comment.
Done in f9349a0 (branch also merged with main).
| if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - uses: eclipse-score/more-disk-space@3fac5780033e636b114cf69e891dc19d640855c2 # v1.1 |
There was a problem hiding this comment.
The part below looks identical to https://github.com/eclipse-score/cicd-workflows/blob/main/.github/workflows/qnx-build.yml Can it be somehow reused?
Additionally, this job will be failing in forks due to pull_request trigger
There was a problem hiding this comment.
It is the same setup, yes. The reusable qnx-build.yml runs bazel build and optionally bazel test; it has no hook for bazel coverage plus the report step, so I could not call it as is. Two options: extend cicd-workflows with a bazel-command input (build/test/coverage) and a post-step hook, then switch this job over; or keep the inline steps until that exists. I would do the extension as a follow-up rather than block this PR, if that is fine with you.
Forks: the job already carries if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository, so it is skipped for fork PRs instead of failing; same-repository branches get the secrets.
There was a problem hiding this comment.
Changed to the pattern of build_qnx.yml: the QNX coverage job moved to its own workflow, coverage_report_qnx.yml, on pull_request_target with the workflow-approval environment gate for fork PRs (same-repository PRs, pushes to main and the merge queue run directly), and it checks out the PR head explicitly. coverage_report.yml keeps the Linux job only. Reusing qnx-build.yml directly is still not possible because it has no coverage mode; the step list here is the one it uses plus the two coverage steps, and I'd propose a bazel-command input there as a follow-up so both repos can share it.
Note on validation: pull_request_target runs the base branch's workflow definition, so the new file cannot run on this PR before it is merged; the branch carries a TEMPORARY push trigger for its own name to exercise it, which I remove before merge.
| # into LCOV; score_coverage's gcov reporter produces the report. Rust sources | ||
| # are listed as not-instrumented here and measured by the Linux run. | ||
| # --------------------------------------------------------------------------- | ||
| coverage:qnx_cov --config=bl-x86_64-qnx |
There was a problem hiding this comment.
| coverage:qnx_cov --config=bl-x86_64-qnx | |
| coverage:qnx_cov --config=score-qnx-x86_64 |
main renamed bl-x86_64-qnx to score-qnx-x86_64. The QNX job needs the SDP secrets, which forks do not get, so it runs for branches of this repository only. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
…selibs into dcalavrezo_qnx_coverage
Scope per platform: coverage_scope_qnx names the QNX platform and the gcov reporter uses it; the Linux-only and QNX-only roots sit behind a select(). score_coverage pinned to the PR commit until 0.4.0 is released. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
b9268f4 to
c9428d0
Compare
Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
c9428d0 to
a1a29eb
Compare
Wildcard builds on a Linux host analysed coverage_scope_qnx for the QNX platform without the QNX toolchains registered and failed toolchain resolution; the gcov reporter carries the same tag for the same reason. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Bazel's dependency chain for the incompatible QNX scope ended at the cxx.rs crate foldhash, which crate_universe marks incompatible with every platform outside rules_rust's triple list (x86_64-pc-nto-qnx800 is not in it). One incompatible root made the scope, the report generator and therefore every QNX test incompatible: 284 tests skipped, no report. Rust roots and the C++ wrappers linking Rust now live in the Linux-only list; the gcov backend cannot measure Rust anyway. Diagnostic step removed. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Analysed locally with a stand-in cc toolchain for the QNX platform: //score/os/utils:tcp_keep_alive requires the sdp_7.1.0 constraint and made the scope incompatible with the 8.0 platform; five QNX libraries were not visible to //tools/coverage. Diagnostic step removed. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Same pattern as build_qnx.yml: the QNX SDP secrets are needed, so the job moves to its own workflow on pull_request_target. Fork PRs run it after a maintainer approves through the workflow-approval environment; same-repository PRs, pushes to main and the merge queue run directly. The PR head is checked out explicitly. coverage_report.yml keeps the Linux job only. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
…the QNX workflow Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Validated on the branch (run 37595023830): approval skipped for the same-repository branch, 278 tests executed, report produced. Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com> # Conflicts: # tools/coverage/BUILD
Replaces the temporary git_override on the coverage_tool#24 commit with the registry release that contains it (scope evaluated for the run's platform). Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
Uses the
score_coverage0.4.0 registry release (release notes), which adds the gcov backend for QNX on-target coverage (0.3.0), the required instrumentation filter (0.3.1) and the per-platform scope (0.4.0).What
QNX on-target coverage for the C++ tests, through the gcov backend of
score_coverage:score_qnx_unit_tests(run_under_qnx), which brings the.gcdacounters back;score_coverage's gcov reporter applies the coverage scope, adds 0 % baselines from the.gcnonotes, and produces the same report archive as the Linux run (HTML via gcovr, LCOV,unmapped_files.txt, justifications, gate).Changes:
MODULE.bazel:score_coverage0.2.0 → 0.4.0;tools/coverage/BUILD:gcov_reporter_wrapper(backend = "gcov", QCC'sgcov), taggedmanualsobazel build //...on a Linux host does not fetch the QNX SDP;tools/coverage/coverage.bazelrc:coverage:qnx_covconfig (QNX build config,run_under_qnx, Bazel'slcov_merger, gcov reporter,--instrument_test_targets, C++ only);.github/workflows/coverage_report_qnx.yml(new, the pattern ofbuild_qnx.yml):pull_request_targetwith theworkflow-approvalenvironment gate for fork PRs; jobqnx-coverage-report(QNX SDP + QEMU/KVM setup,bazel coverage --config=qnx_cov,generate_coverage_html --platform qnx), artifactbaselibs_cpp_coverage_report_qnx.coverage_report.ymlkeeps the Linux job. Becausepull_request_targetuses the base branch's definition, the new workflow runs on this PR only through a TEMPORARYpushtrigger for the branch, removed before merge.The Linux job is unchanged.
Validation
The QNX job produced a complete report on this branch: 615 files in the index, every link resolves, 81.6 % raw line coverage.
unmapped_files.txtlists 50 Rust sources asnot-instrumented(rustc emits no gcov counters; they are measured by the Linux run), 128 files asno-data(mostly headers vendored from external repositories, which Bazel's collector drops on this backend), 107declaration-onlyheaders and 78compiled-without-codeunits, as on Linux.Per file, the QNX numbers differ from the Linux report of the same tree by design: gcov counts fewer lines (no unused inline functions, no closing braces), so totals differ while no file is missing. The two reports are compared per file, not merged.
Tracking: eclipse-score/tooling#427 (track 1).
Update: bumped to 0.3.1, which requires the explicit
--instrumentation_filter=^//score[/:]this branch sets. Bazel guesses the filter from the packages of the test targets; libraries tested from atestsubpackage were otherwise compiled without counters or, on QNX, lost their counters (score/os showed 13 % instead of 80 % in the first QNX report). See the 0.3.1 release notes.Scope per platform (eclipse-score/coverage_tool#23, fixed in #24).
coverage_scope_qnxnames the QNX platform; Linux-only roots (incl. all Rust) and QNX-only roots sit behind aselect(). Validated on run 37473583990: 56score/os/qnxfiles in the QNX report (0 before), noscore/os/linuxfile (16 at 0 % before), 89.3 % lines over 684 files.MODULE.bazelnow uses the 0.4.0 release, which contains #24 (the temporarygit_overrideis gone).