fix: testops_multi xdist run_id handoff + mask API token in config debug log#497
Closed
gibiw wants to merge 4 commits into
Closed
fix: testops_multi xdist run_id handoff + mask API token in config debug log#497gibiw wants to merge 4 commits into
gibiw wants to merge 4 commits into
Conversation
In testops_multi mode the controller produces a {project_code: run_id}
dict, but the xdist lock file was written via str(dict) and read back as
a single positional argument. Workers crashed in QaseTestOpsMulti.set_run_id()
with "missing 1 required positional argument: 'run_id'", project_runs stayed
empty, and every result was skipped with "No run_id for project ...".
Serialise the run id via json.dumps in the controller, parse it back in
load_run_from_lock, and add QaseTestOpsMulti.set_run_ids() to seed every
project at once. QaseCoreReporter.set_run_id() now dispatches dict input
to set_run_ids so the single-project path is unchanged.
QaseCoreReporter.__init__ logged the full config via str(self.config), which serialised testops.api.token in clear text. Any debug log shared with support or pasted into an issue leaked the customer's API key. Add qase.commons.util.token_masker with mask_token() and sanitize_config_for_log() mirroring the JS token-masker contract (qase-javascript-commons/src/utils/token-masker.ts). Route the debug config dump through sanitize_config_for_log so testops.api.token is shown as "abc****wxyz" and tokens of 7 chars or fewer are fully hidden.
Contributor
Author
|
Splitting per request into two PRs:
Closing this combined PR — superseded by the two split PRs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bundles two related reliability/security fixes for
testops_multimode. Both ship inqase-python-commons5.1.2.Fix 1 —
testops_multirun_id handoff under pytest-xdistSummary
QaseTestOpsMulti.set_run_id() missing 1 required positional argument: 'run_id'crash and theNo run_id for project ..., skipping sendcascade whentestops_multimode runs under pytest-xdist (-n N).{project_code: run_id}map written by the xdist controller and seed it through a newQaseTestOpsMulti.set_run_ids()bulk setter.QaseTestOpsMulti.set_run_id(project_code, run_id)API is untouched.Root cause
QasePytestPlugin.pytest_sessionstartwrote the run id viastr(self.run_id). In multi modeself.run_idis adict, so the lock file held"{'DW': 1553}"— not round-trippable.QasePytestPlugin.load_run_from_lockthen calledself.reporter.set_run_id(self.run_id)with one argument, butQaseTestOpsMulti.set_run_idrequires(project_code, run_id).QaseCoreReporter.set_run_idswallowed theTypeErrorsilently and routed the worker through the fallback reporter — so results that the user thought were going to TestOps were quietly written to local JSON files instead.Fix
QaseCoreReporter.set_run_id(run_id)accepts both scalar and dict, dispatching dict input toset_run_idswhen the inner reporter exposes it.QaseTestOpsMulti.set_run_ids(run_ids: Dict[str, Union[str, int]])seedsproject_runsfor every known project in one shot, warning on unknown codes.QasePytestPluginserialises the run id viajson.dumpsin the controller and parses it back withjson.loadsin workers; if a legacy non-JSON file is found, it falls back to the previous string handling.Fix 2 — Mask API token in debug config dump
Summary
QaseCoreReporter.__init__logged the full config viastr(self.config), which serialisedtestops.api.tokenin clear text. Any debug log shared with support or pasted into an issue leaked the customer's API key.qase.commons.util.token_maskermodule mirrors the JS contract fromqase-javascript-commons/src/utils/token-masker.ts.Behaviour
abc****wxyz(first 3 + last 4 visible).*.str(config)if the serialised form cannot be parsed as JSON, so a bug in the masker can never silence debug logs.Live verification —
examples/multiproject/pytestwithpytest -n 2Smoke-tested against real Qase TestOps API in projects
DEVXandDEMO. Side-by-side log comparison:main(baseline)fix/testops-multi-xdistset_run_id() missing 1 required positional argumenterrors in worker logFailed to set run idlog lines<64 char plain token>90e****ce5abuild/qase-report/results/build/not createdAdding resultdebug linesTest plan
qase-python-commonsunit suite: 247 passed, including 3 newset_run_idscases, 3 newQaseCoreReporter.set_run_iddispatch cases, and 10 newtoken_maskercases.qase-pytestunit suite: 115 passed, including 5 new lock-file round-trip cases (controller-write / worker-read for both dict and scalar shapes, plus legacy-format tolerance).qase-pytestintegration suite: 10 passed.pytest -n 2inexamples/multiproject/pytest— confirmed all 12 worker results land in TestOps and token is masked in debug log.Release
qase-python-commons5.1.1 → 5.1.2.qase-pytest8.3.0 → 8.3.1.