From 54ad124c1885fce8fb54e13e2ff9097508ab83fb Mon Sep 17 00:00:00 2001 From: "A.Shakhmatov" Date: Sun, 9 Aug 2026 13:13:38 +0300 Subject: [PATCH] tests/spec: a CSOT-rewritten maxTimeMS cannot be asserted Every client entity is built with CSOT `timeoutMS` (OP_TIMEOUT_MS, 10 s), and CSOT overwrites `maxTimeMS` on each command with what is left of that budget. An expectation of `maxTimeMS: 6000` therefore meets the harness's 10000, and no amount of engine correctness would change it. Reported unsupported rather than failed: a FAIL is a claim about the engine, and this is a claim about the runner. Refused unconditionally when an expected command mentions `maxTimeMS`, not only when the two values differ, so it can never become a pass by coincidence. Exactly one case in the corpus asserts it -- estimatedDocumentCount.json, "estimatedDocumentCount with maxTimeMS" -- so the whole cost of the hatch is one case, which is why it is worth taking instead of dropping `timeoutMS`. That option is not open anyway: `timeoutMS` is what replaced the outer race that once turned ~190 good cases into phantom timeout FAILs. This is the only escape hatch in the runner. Everything else is either an honest FAIL or an enumerated unsupported feature. 159/133/195 becomes 159/132/196: one case, fail to skip, and nothing else moves. --- tests/spec/run.js | 15 +++++++++++++++ tests/spec/scorecard.txt | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/spec/run.js b/tests/spec/run.js index b4f96f4..021b193 100644 --- a/tests/spec/run.js +++ b/tests/spec/run.js @@ -646,6 +646,21 @@ function matchEvent(expected, actual, entities, pathStr) { for (const [k, v] of Object.entries(body || {})) { switch (k) { case 'command': + // The one assertion this runner cannot make, and the only + // escape hatch in it. Every client entity carries CSOT + // `timeoutMS` (see OP_TIMEOUT_MS), and CSOT overwrites + // `maxTimeMS` on every command with what is left of that + // budget -- so the value on the wire is the harness's, not the + // test's. Dropping `timeoutMS` is not the alternative: it is + // what replaced the outer race that produced ~190 phantom + // timeout FAILs, and it would cost far more than one case. + // Refused unconditionally rather than only when the values + // differ, so this can never turn into a pass by coincidence. + if (isPlainDoc(v) && Object.prototype.hasOwnProperty.call(v, 'maxTimeMS')) { + throw new Unsupported('maxTimeMS in an expected command (CSOT rewrites it)'); + } + match(v, actual.ev[k], entities, `${pathStr}.${k}`, true); + break; case 'reply': match(v, actual.ev[k], entities, `${pathStr}.${k}`, true); break; diff --git a/tests/spec/scorecard.txt b/tests/spec/scorecard.txt index 4ef782b..28b048a 100644 --- a/tests/spec/scorecard.txt +++ b/tests/spec/scorecard.txt @@ -13,7 +13,7 @@ # semantics; ignoring them makes some cases pass that a full runner would # fail, so treat `pass` as an upper bound until M1 wires events up. -total 159 pass 133 fail 195 skip 175 files 0 errored +total 159 pass 132 fail 196 skip 175 files 0 errored # per-file: name pass fail skip aggregate-allowdiskuse.json 3 0 0 @@ -109,7 +109,7 @@ distinct-rawdata.json 0 1 1 distinct.json 0 2 0 estimatedDocumentCount-comment.json 1 1 1 estimatedDocumentCount-rawdata.json 1 0 1 -estimatedDocumentCount.json 2 2 2 +estimatedDocumentCount.json 2 1 3 find-allowdiskuse-serverError.json 0 0 2 find-allowdiskuse.json 3 0 0 find-collation.json 0 1 0 @@ -348,7 +348,7 @@ distinct.json FAIL Distinct with a filter MongoServerError: no such command: 'di estimatedDocumentCount-comment.json SKIP estimatedDocumentCount with document comment needs server >= 4.4.14 estimatedDocumentCount-comment.json FAIL estimatedDocumentCount with document comment - pre 4.4.14, server error estimatedDocumentCount: expected an error, the operation succeeded estimatedDocumentCount-rawdata.json SKIP Estimated document count with rawData option needs server >= 8.2.0 -estimatedDocumentCount.json FAIL estimatedDocumentCount with maxTimeMS events client0[0].command.maxTimeMS: expected 6000, got 10000 +estimatedDocumentCount.json SKIP estimatedDocumentCount with maxTimeMS runner: maxTimeMS in an expected command (CSOT rewrites it) estimatedDocumentCount.json SKIP estimatedDocumentCount errors correctly--command error runner: failPoint estimatedDocumentCount.json SKIP estimatedDocumentCount errors correctly--socket error runner: failPoint estimatedDocumentCount.json FAIL estimatedDocumentCount works correctly on views estimatedDocumentCount: expected 2, got 0