Skip to content

fix(xtest): use head-built otdfctl for admin key ops so PQ/T tests run on branch refs#534

Merged
dmihalcik-virtru merged 5 commits into
mainfrom
debug-pqc-mechanism-detection
Jun 23, 2026
Merged

fix(xtest): use head-built otdfctl for admin key ops so PQ/T tests run on branch refs#534
dmihalcik-virtru merged 5 commits into
mainfrom
debug-pqc-mechanism-detection

Conversation

@dmihalcik-virtru

@dmihalcik-virtru dmihalcik-virtru commented Jun 23, 2026

Copy link
Copy Markdown
Member

Problem

PQ/T tests (test_pqc.py: X-Wing, secp+ML-KEM hybrids) silently skipped on every branch/PR run, only ever exercised on main/nightly. They skipped with:

Algorithm hpqt:xwing not supported by platform

even when the platform fully supported it (km1's keyring loads hpqt:*, and the policy-service key_algorithm_defined CEL allows the enum values).

Root cause

The PQ tests register their keys via the admin otdfctl fixture (conftest.load_otdfctl()), which picks the CLI in this order:

  1. OTDFCTL_HEADS[0]sdk/go/dist/{tag}/otdfctl.sh (the head build)
  2. sdk/go/dist/main/otdfctl.sh
  3. fallback → go run github.com/opentdf/otdfctl@latest

OTDFCTL_HEADS was never set by the workflow. For any platform/go ref that is a branch (not main), dist/main/otdfctl.sh doesn't exist either, so the admin CLI fell through to the released otdfctl@latest — which predates the hpqt:* algorithm mapping. It rejected --algorithm=hpqt:xwing client-side, before the request reached the (fully capable) platform. (Older algorithms like rsa-4096 / ec-384-521 still passed because @latest knows them — which is why only hpqt skipped.)

Fix

Set OTDFCTL_HEADS: ${{ steps.configure-go.outputs.heads }} on each pytest step so the admin otdfctl uses the head build (sdk/go/dist/{tag}/otdfctl) that matches what's under test. heads is [.tag], which matches the dist/{tag} build-dir naming.

Supporting changes

  • fixtures/keys.py — include the underlying otdfctl/platform error in the PQ key-create skip reason. The previous opaque "not supported" message is what hid this for so long; the enriched message is what surfaced the go run …@latest smoking gun. Worth keeping permanently.
  • conftest.pypytest_report_header echoes the detected platform version + feature set into the always-visible session header (feature detection gates skips, and pytest hides captured output for skipped tests).
  • tdfs.py — lightweight logger.debug breadcrumbs on the PQ-detection failure paths (km1 log missing/unreadable, KAS algorithm probe failure).

Validation

Dispatched xtest.yml against platform branch revert-3625-DSPX-3396-disable-hybrid (platform + go both): the mechanism-xwing / mechanism-secpmlkem tests went from SKIPPED → PASSED.

Summary by CodeRabbit

Release Notes

  • Tests
    • Test reports now display detected platform version and feature set in session headers.
    • Enhanced skip messages with detailed feature requirements and error context.
    • Improved debug logging for test diagnostics and troubleshooting.

Instrument PlatformFeatureSet PQ/T mechanism detection (mechanism-xwing,
mechanism-secpmlkem, mechanism-mlkem) to diagnose why these features go
undetected even when km1's 'kas trust mechanisms initialized' log line
lists hpqt:xwing and hpqt:secp256r1-mlkem768.

Logs: resolved KAS_KM1_LOG_FILE path + existence, whether the mechanisms
line matched (and what it contained), HTTP-probe fallback results, the
semver gate decision, and which features were ultimately added.
PQ/T mechanism tests skip (not fail) when a mechanism is undetected, and
pytest hides captured output for skipped tests, so the pqc-detect DEBUG
lines would not appear in CI. A pytest_report_header hook forces detection
and echoes the captured xtest logs into the always-visible session header.
When kas-registry key create rejects an hpqt algorithm, include the
underlying otdfctl/platform error in the skip reason. This distinguishes a
client-side otdfctl mapping rejection ('invalid algorithm' from
sdkHelpers) from a server-side protovalidate rejection
('key_algorithm_defined' CEL), which the generic message hid.
The admin otdfctl fixture (used to register kas-registry keys for ABAC/PQC
tests) is loaded by conftest.load_otdfctl(), which picks the head build via
the OTDFCTL_HEADS env var, else dist/main/otdfctl.sh, else falls back to
'go run github.com/opentdf/otdfctl@latest'.

OTDFCTL_HEADS was never set by the workflow, so for any platform/go ref that
is a branch (not 'main') the admin CLI silently fell back to the released
otdfctl@latest. That released CLI predates the hpqt:* algorithm mapping, so
'kas-registry key create --algorithm=hpqt:xwing' was rejected client-side and
every PQ/T test skipped as 'Algorithm ... not supported by platform' -- even
though the platform (KAS keyring + policy CEL) fully supported it.

Set OTDFCTL_HEADS from configure-go.outputs.heads on each pytest step so the
admin otdfctl uses the head build (sdk/go/dist/{tag}/otdfctl) that matches
what's under test.
Replace the verbose per-call pqc-detect DEBUG logging with a concise
always-visible session-header summary of the detected platform version and
feature set (feature detection gates skips, and pytest hides captured output
for skipped tests). Keep lightweight logger.debug detail on the failure
paths in tdfs.py (km1 log missing/unreadable, KAS algorithm probe failure)
so there's still a breadcrumb when PQ/T detection comes up empty.
@dmihalcik-virtru dmihalcik-virtru requested review from a team as code owners June 23, 2026 17:29
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 367d7dbd-fd78-4452-8e9f-2adfd1eae1a9

📥 Commits

Reviewing files that changed from the base of the PR and between 61c70ca and 33f7239.

📒 Files selected for processing (4)
  • .github/workflows/xtest.yml
  • xtest/conftest.py
  • xtest/fixtures/keys.py
  • xtest/tdfs.py

📝 Walkthrough

Walkthrough

Improves xtest observability by adding debug logging to platform feature detection helpers in tdfs.py, enriching InvalidAlgorithm skip messages in fixtures/keys.py, adding a pytest_report_header hook in conftest.py that displays detected platform version and features, and propagating OTDFCTL_HEADS to all five pytest steps in the CI workflow.

Changes

Xtest diagnostics and CI wiring

Layer / File(s) Summary
Platform feature detection observability
xtest/tdfs.py, xtest/fixtures/keys.py, xtest/conftest.py
Debug logs added to _algs_from_km1_log (missing file, parse error) and _kas_supports_algorithm (HTTP probe failure). InvalidAlgorithm skip message in _get_or_create_key now includes algorithm, required features, and exception text. A new pytest_report_header() hook reports detected platform version and feature set in the pytest session header.
OTDFCTL_HEADS env var in CI pytest steps
.github/workflows/xtest.yml
OTDFCTL_HEADS sourced from steps.configure-go.outputs.heads is added to the env: blocks of all five uv run pytest steps in the xct matrix job.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related PRs

  • opentdf/tests#426: Refactors the same _get_or_create_key helper and touches xtest/tdfs.py platform-feature plumbing, directly overlapping with this PR's changes to both files.
  • opentdf/tests#443: Modifies the same InvalidAlgorithm handling path in xtest/fixtures/keys.py to conditionally call pytest.skip when required_features is non-empty.
  • opentdf/tests#484: Modifies xtest/tdfs.py's _algs_from_km1_log path, directly overlapping with this PR's debug-logging additions to the same function.

Suggested reviewers

  • pflynn-virtru
  • jakedoublev

Poem

🐇 Hopping through the CI vines,
I planted logs in hidden lines.
Skip messages now show the cause,
No more silent, puzzling flaws.
The header gleams with feature names —
🌟 A bunny wins debugging games!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main fix: using head-built otdfctl for admin key operations to enable PQ/T tests on branch refs, which aligns with the core objective documented in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch debug-pqc-mechanism-detection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances test reporting and diagnostic logging in the test suite. Specifically, it adds a 'pytest_report_header' to display detected platform features and versions in the pytest session header, improves the skip message in '_get_or_create_key' to include the underlying exception and required features when an algorithm is unsupported, and introduces debug logging in 'xtest/tdfs.py' for missing or unreadable logs and failed KAS algorithm probes. There are no review comments, and we have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@dmihalcik-virtru dmihalcik-virtru merged commit dfc132e into main Jun 23, 2026
18 checks passed
@dmihalcik-virtru dmihalcik-virtru deleted the debug-pqc-mechanism-detection branch June 23, 2026 17:36
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants