@blamejs/blamejs-shop 0.4.101 → 0.4.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +55 -51
- package/lib/vendor/blamejs/.gitignore +5 -0
- package/lib/vendor/blamejs/CHANGELOG.md +4 -0
- package/lib/vendor/blamejs/api-snapshot.json +2 -2
- package/lib/vendor/blamejs/lib/sandbox.js +23 -5
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.15.25.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.15.26.json +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-adverse-decision.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-open-nofollow.test.js +7 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-bucket-ops.test.js +30 -10
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/bearer-auth.test.js +22 -17
- package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-chunked-malformed.test.js +23 -18
- package/lib/vendor/blamejs/test/layer-0-primitives/breach-deadline.test.js +8 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +13 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/cra-report.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/daily-byte-quota.test.js +20 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +8 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +34 -15
- package/lib/vendor/blamejs/test/layer-0-primitives/gcs-bucket-ops.test.js +30 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +15 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +41 -18
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +33 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-throttle-transform.test.js +21 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/incident-report.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp.test.js +29 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +42 -23
- package/lib/vendor/blamejs/test/layer-0-primitives/network-byte-quota.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +20 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts-handshake-byte-cap.test.js +20 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/nis2-report.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +22 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +8 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parser-verify-hardening.test.js +21 -16
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-sqs.test.js +31 -11
- package/lib/vendor/blamejs/test/layer-0-primitives/request-id-async-context.test.js +21 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +35 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update-poll-asset-digest.test.js +21 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +29 -10
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +51 -33
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-multipart-sse.test.js +31 -13
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +41 -21
- package/lib/vendor/blamejs/test/layer-0-primitives/testing-request.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-exporter.test.js +30 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +10 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +91 -20
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../scripts/release-notes-schema.json",
|
|
3
|
+
"version": "0.15.26",
|
|
4
|
+
"date": "2026-06-25",
|
|
5
|
+
"headline": "Internal test-harness correctness only — the published library is byte-for-byte identical to 0.15.25",
|
|
6
|
+
"summary": "The smoke runner requires each test module and awaits its exported run(). Several tests were instead written as a top-level (async function () {...})() IIFE that runs detached at require-time, so the runner measured and reported the test's result before the IIFE's post-await assertions executed — those checks silently never ran (one parser test exercised 4 of its 26 assertions, and a failure after the first await would have gone unseen as a false pass). Those tests are converted to the exported-run form so the runner awaits their full assertion set, and a codebase-patterns detector now refuses a top-level async IIFE in a test file so the pattern cannot return. No shipped framework code changed; this release is byte-for-byte identical to 0.15.25 for operators.",
|
|
7
|
+
"sections": [
|
|
8
|
+
{
|
|
9
|
+
"heading": "Fixed",
|
|
10
|
+
"items": [
|
|
11
|
+
{
|
|
12
|
+
"title": "Detached-IIFE tests now run their full assertion set under the smoke runner",
|
|
13
|
+
"body": "A test written as a top-level (async function () {...})() IIFE runs detached when the runner requires it: the runner only awaits an exported run(), so it reported the file's result before the IIFE's awaited assertions executed, and every check after the first await silently did not count (one parsers test ran 4 of 26). Such tests are rewritten to define async function run(), export it, and invoke it under if (require.main === module), so the runner awaits the complete set; a detector refuses a re-introduced top-level async IIFE in a test file. This is test-harness correctness only — no shipped framework behavior changed."
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -3,7 +3,7 @@ var helpers = require("../helpers");
|
|
|
3
3
|
var b = helpers.b;
|
|
4
4
|
var check = helpers.check;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
async function run() {
|
|
7
7
|
var captured = null;
|
|
8
8
|
var hire = b.ai.adverseDecision.wrap({
|
|
9
9
|
audit: false,
|
|
@@ -41,4 +41,7 @@ var check = helpers.check;
|
|
|
41
41
|
check("ai.adverseDecision refuses missing legalBasis", threwBadLegal);
|
|
42
42
|
|
|
43
43
|
console.log("OK — ai.adverseDecision tests");
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = { run: run };
|
|
47
|
+
if (require.main === module) run().catch(function (e) { console.error(e); process.exit(1); });
|
|
@@ -12,7 +12,7 @@ var helpers = require("../helpers");
|
|
|
12
12
|
var b = helpers.b;
|
|
13
13
|
var check = helpers.check;
|
|
14
14
|
|
|
15
|
-
function run() {
|
|
15
|
+
async function run() {
|
|
16
16
|
check("b.atomicFile.openNoFollowSync is a function",
|
|
17
17
|
typeof b.atomicFile.openNoFollowSync === "function");
|
|
18
18
|
|
|
@@ -58,12 +58,17 @@ function run() {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
// Await the stream's end BEFORE the finally cleanup. Without the await,
|
|
62
|
+
// the try block returns its promise and the finally runs synchronously —
|
|
63
|
+
// removing the dir and leaving the stream's in-flight read (FSReqCallback)
|
|
64
|
+
// alive past run(). Awaiting drains the read before cleanup.
|
|
65
|
+
await new Promise(function (resolve, reject) {
|
|
62
66
|
rs.on("end", function () {
|
|
63
67
|
check("an fd from openNoFollowSync is consumable by createReadStream",
|
|
64
68
|
streamed === "payload-bytes");
|
|
65
69
|
resolve();
|
|
66
70
|
});
|
|
71
|
+
rs.on("error", reject);
|
|
67
72
|
});
|
|
68
73
|
} finally {
|
|
69
74
|
try { fs.rmSync(dir, { recursive: true, force: true }); } catch (_e) { /* best-effort */ }
|
|
@@ -235,17 +235,37 @@ async function testSetLifecycleNotSupported() {
|
|
|
235
235
|
} finally { await l.close(); }
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
// bucketOps.create issues its requests through the shared b.httpClient
|
|
239
|
+
// keep-alive agent, whose cached client sockets (and the mock servers they
|
|
240
|
+
// keep open) would otherwise outlive run() and hold the forked worker's
|
|
241
|
+
// event loop open. Tear the pool down and poll until the TCP handles have
|
|
242
|
+
// actually closed — agent.destroy() schedules the teardown asynchronously,
|
|
243
|
+
// so polling drives the event-loop turns needed to complete it inside run().
|
|
244
|
+
async function _drainTcpHandles() {
|
|
245
|
+
b.httpClient._resetForTest();
|
|
246
|
+
if (typeof process.getActiveResourcesInfo !== "function") return;
|
|
247
|
+
await helpers.waitUntil(function () {
|
|
248
|
+
return process.getActiveResourcesInfo().filter(function (t) {
|
|
249
|
+
return t === "TCPSocketWrap" || t === "TCPServerWrap";
|
|
250
|
+
}).length === 0;
|
|
251
|
+
}, { timeoutMs: 5000, label: "azure-blob-bucket-ops: TCP handle drain after _resetForTest" });
|
|
252
|
+
}
|
|
253
|
+
|
|
238
254
|
async function run() {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
255
|
+
try {
|
|
256
|
+
await testSurface();
|
|
257
|
+
await testFactoryValidation();
|
|
258
|
+
await testContainerNameValidation();
|
|
259
|
+
await testCreateContainerWireShape();
|
|
260
|
+
await testCreateContainerConflict();
|
|
261
|
+
await testDeleteContainer();
|
|
262
|
+
await testListContainers();
|
|
263
|
+
await testSetCorsRulesValidation();
|
|
264
|
+
await testSetCorsRulesWireShape();
|
|
265
|
+
await testSetLifecycleNotSupported();
|
|
266
|
+
} finally {
|
|
267
|
+
await _drainTcpHandles();
|
|
268
|
+
}
|
|
249
269
|
}
|
|
250
270
|
|
|
251
271
|
module.exports = { run: run };
|
|
@@ -49,7 +49,28 @@ function _client(port) {
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
// The azure adapter issues requests through the shared b.httpClient
|
|
53
|
+
// keep-alive agent, whose cached client socket (and the mock server it
|
|
54
|
+
// keeps open) would otherwise outlive run() and hold the forked worker's
|
|
55
|
+
// event loop open. Tear the pool down and poll until the TCP handles have
|
|
56
|
+
// actually closed — agent.destroy() schedules the teardown asynchronously,
|
|
57
|
+
// so polling drives the event-loop turns needed to complete it inside run().
|
|
58
|
+
async function _drainTcpHandles() {
|
|
59
|
+
b.httpClient._resetForTest();
|
|
60
|
+
if (typeof process.getActiveResourcesInfo !== "function") return;
|
|
61
|
+
await helpers.waitUntil(function () {
|
|
62
|
+
return process.getActiveResourcesInfo().filter(function (t) {
|
|
63
|
+
return t === "TCPSocketWrap" || t === "TCPServerWrap";
|
|
64
|
+
}).length === 0;
|
|
65
|
+
}, { timeoutMs: 5000, label: "azure-blob-key-encoding: TCP handle drain after _resetForTest" });
|
|
66
|
+
}
|
|
67
|
+
|
|
52
68
|
async function run() {
|
|
69
|
+
try { await _runTests(); }
|
|
70
|
+
finally { await _drainTcpHandles(); }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function _runTests() {
|
|
53
74
|
var srv = await listenRecording();
|
|
54
75
|
try {
|
|
55
76
|
var c = _client(srv.port);
|
|
@@ -16,24 +16,26 @@ var _bodyReq = helpers._bodyReq;
|
|
|
16
16
|
var _bodyRes = helpers._bodyRes;
|
|
17
17
|
|
|
18
18
|
function _runMiddleware(mw, req, res) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
// The middleware settles by calling next() or by ending the response. Wrap
|
|
20
|
+
// in withTestTimeout so a middleware that hangs becomes a hard "test timed
|
|
21
|
+
// out" reject (1500ms budget) instead of stalling the suite — its guard
|
|
22
|
+
// timer clears on settle, so no Timeout handle lingers past run().
|
|
23
|
+
return helpers.withTestTimeout("bearer-auth: middleware settles", function () {
|
|
24
|
+
return new Promise(function (resolve) {
|
|
25
|
+
var settled = false;
|
|
26
|
+
function _settle(value) {
|
|
27
|
+
if (settled) return;
|
|
28
|
+
settled = true;
|
|
29
|
+
resolve(value);
|
|
30
|
+
}
|
|
31
|
+
mw(req, res, function () {
|
|
32
|
+
_settle({ next: true, status: res._endedStatus, user: req.user });
|
|
33
|
+
});
|
|
34
|
+
res.on("finish", function () {
|
|
35
|
+
_settle({ next: false, status: res._endedStatus, user: req.user });
|
|
36
|
+
});
|
|
25
37
|
});
|
|
26
|
-
|
|
27
|
-
if (settled) return;
|
|
28
|
-
settled = true;
|
|
29
|
-
resolve({ next: false, status: res._endedStatus, user: req.user });
|
|
30
|
-
});
|
|
31
|
-
setTimeout(function () {
|
|
32
|
-
if (settled) return;
|
|
33
|
-
settled = true;
|
|
34
|
-
resolve({ next: false, status: res._endedStatus, timeout: true });
|
|
35
|
-
}, 1500); // allow:raw-byte-literal — test safety timeout ms
|
|
36
|
-
});
|
|
38
|
+
}, { timeoutMs: 1500 }); // allow:raw-byte-literal — middleware-settle budget ms
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
function testBearerSurface() {
|
|
@@ -97,6 +99,9 @@ async function run() {
|
|
|
97
99
|
await testBearerInvalidTokenRejected();
|
|
98
100
|
await testBearerVerifyThrowsRejected();
|
|
99
101
|
await testBearerValidAttachesUser();
|
|
102
|
+
// The 401-reject paths emit an audit event, which schedules the audit
|
|
103
|
+
// handler's age-flush timer. Drain it so no timer lingers past run().
|
|
104
|
+
await b.audit.flush();
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
module.exports = { run: run };
|
|
@@ -35,25 +35,27 @@ function _runWithError(headers, parserError) {
|
|
|
35
35
|
var bp = b.middleware.bodyParser();
|
|
36
36
|
var req = _chunkedReq(headers);
|
|
37
37
|
var res = _bodyRes();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
// The parser settles by calling next() or by ending the response after the
|
|
39
|
+
// emitted error. Wrap in withTestTimeout so a parser that hangs becomes a
|
|
40
|
+
// hard "test timed out" reject (1500ms budget) instead of stalling the
|
|
41
|
+
// suite — its guard timer clears on settle, so no Timeout handle lingers.
|
|
42
|
+
return helpers.withTestTimeout("body-parser: malformed-body parser settles", function () {
|
|
43
|
+
return new Promise(function (resolve) {
|
|
44
|
+
var settled = false;
|
|
45
|
+
function _settle(value) {
|
|
46
|
+
if (settled) return;
|
|
47
|
+
settled = true;
|
|
48
|
+
resolve(value);
|
|
49
|
+
}
|
|
50
|
+
bp(req, res, function () {
|
|
51
|
+
_settle({ next: true, status: res._endedStatus, req: req });
|
|
52
|
+
});
|
|
53
|
+
res.on("finish", function () {
|
|
54
|
+
_settle({ next: false, status: res._endedStatus, headers: res._headers, req: req });
|
|
55
|
+
});
|
|
56
|
+
setImmediate(function () { req.emit("error", parserError); });
|
|
44
57
|
});
|
|
45
|
-
|
|
46
|
-
if (settled) return;
|
|
47
|
-
settled = true;
|
|
48
|
-
resolve({ next: false, status: res._endedStatus, headers: res._headers, req: req });
|
|
49
|
-
});
|
|
50
|
-
setImmediate(function () { req.emit("error", parserError); });
|
|
51
|
-
setTimeout(function () {
|
|
52
|
-
if (settled) return;
|
|
53
|
-
settled = true;
|
|
54
|
-
resolve({ next: false, timeout: true, req: req });
|
|
55
|
-
}, 1500);
|
|
56
|
-
});
|
|
58
|
+
}, { timeoutMs: 1500 }); // allow:raw-byte-literal — parser-settle budget ms
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
async function testInvalidChunkSizeRefused() {
|
|
@@ -123,6 +125,9 @@ async function run() {
|
|
|
123
125
|
await testInvalidTransferEncodingRefused();
|
|
124
126
|
await testInvalidEofStateRefused();
|
|
125
127
|
await testNonChunkedErrorAlsoClosesConnection();
|
|
128
|
+
// The malformed-body rejects emit an audit event, which schedules the
|
|
129
|
+
// audit handler's age-flush timer. Drain it so no timer lingers past run().
|
|
130
|
+
await b.audit.flush();
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
module.exports = { run: run };
|
|
@@ -3,7 +3,7 @@ var helpers = require("../helpers");
|
|
|
3
3
|
var b = helpers.b;
|
|
4
4
|
var check = helpers.check;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
async function run() {
|
|
7
7
|
var now = Date.now();
|
|
8
8
|
var d = b.breach.deadline.forStates(["CA", "TX"], now);
|
|
9
9
|
check("forStates returns 2", d.length === 2);
|
|
@@ -118,6 +118,11 @@ var check = helpers.check;
|
|
|
118
118
|
check("auto-tick timer fired the passed alert", true);
|
|
119
119
|
autoClock.stop();
|
|
120
120
|
check("clock stops cleanly", autoClock.status().running === false);
|
|
121
|
+
}
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
module.exports = { run: run };
|
|
124
|
+
|
|
125
|
+
if (require.main === module) {
|
|
126
|
+
run().then(function () { console.log("OK — breach-deadline tests"); })
|
|
127
|
+
.catch(function (e) { console.error(e); process.exit(1); });
|
|
128
|
+
}
|
|
@@ -82,7 +82,29 @@ function _push(idToken, bodyAuthReqId) {
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
// The CIBA client's discovery + JWKS fetches go through the shared
|
|
86
|
+
// b.httpClient keep-alive agent, whose cached client socket (and the mock
|
|
87
|
+
// IdP server it keeps open) would otherwise outlive run() and hold the
|
|
88
|
+
// forked worker's event loop open. Tear the pool down and poll until the
|
|
89
|
+
// TCP handles have actually closed — agent.destroy() schedules the teardown
|
|
90
|
+
// asynchronously, so polling drives the event-loop turns needed to complete
|
|
91
|
+
// it inside run().
|
|
92
|
+
async function _drainTcpHandles() {
|
|
93
|
+
b.httpClient._resetForTest();
|
|
94
|
+
if (typeof process.getActiveResourcesInfo !== "function") return;
|
|
95
|
+
await helpers.waitUntil(function () {
|
|
96
|
+
return process.getActiveResourcesInfo().filter(function (t) {
|
|
97
|
+
return t === "TCPSocketWrap" || t === "TCPServerWrap";
|
|
98
|
+
}).length === 0;
|
|
99
|
+
}, { timeoutMs: 5000, label: "ciba-authreqid-binding: TCP handle drain after _resetForTest" });
|
|
100
|
+
}
|
|
101
|
+
|
|
85
102
|
async function run() {
|
|
103
|
+
try { await _runTests(); }
|
|
104
|
+
finally { await _drainTcpHandles(); }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function _runTests() {
|
|
86
108
|
await _withIdp(async function (issuer) {
|
|
87
109
|
var ciba = _cibaClient(issuer);
|
|
88
110
|
|
|
@@ -9425,6 +9425,20 @@ var KNOWN_ANTIPATTERNS = [
|
|
|
9425
9425
|
allowlist: [],
|
|
9426
9426
|
reason: "The smoke worker requires each test module and awaits its exported run(); a column-0 `run()` / `run().then(...process.exit...)` fires a second unawaited run() at require-time that races the worker's result print (and process.exit() exits before the result line, read as 'no result line' / 'fork failed' on a slow runner). Export `run` and wrap the invocation in `if (require.main === module)`. Fires on any `run(` at the start of a line; `function run()`, `module.exports = { run }`, and an indented `run()` inside the require-main guard stay silent.",
|
|
9427
9427
|
},
|
|
9428
|
+
{
|
|
9429
|
+
id: "test-detached-async-iife",
|
|
9430
|
+
primitive: "define `async function run() {...}`, `module.exports = { run }`, and invoke under `if (require.main === module) run().catch(...)` — never a top-level `(async function () {...})()` IIFE",
|
|
9431
|
+
scanScope: "test",
|
|
9432
|
+
regex: /^\(async\b/m,
|
|
9433
|
+
skipCommentLines: true,
|
|
9434
|
+
allowlist: [
|
|
9435
|
+
// The smoke runner itself — its top-level `(async function () {...})()` is
|
|
9436
|
+
// the orchestrator's process entry point (it forks the per-file workers),
|
|
9437
|
+
// not a worker-awaited test body. It has no run() to export.
|
|
9438
|
+
"test/smoke.js",
|
|
9439
|
+
],
|
|
9440
|
+
reason: "The smoke worker requires each test module and only `await mod.run()`. A test written as a top-level `(async function run(){...})()` IIFE runs DETACHED on require: the worker measures + prints its result before the IIFE's post-await assertions execute, so every check after the first await silently never counts (parsers-standalone reported 4 of 26 checks this way) and a failing post-await assertion is never seen — a false pass. Export `run` and invoke under `if (require.main === module)`. Fires on a column-0 `(async` (function or arrow IIFE); `async function run()` (no leading paren), `module.exports = { run }`, and an indented async IIFE inside a helper stay silent. Synchronous `(function(){...})()` IIFEs complete during require, so they do not undercount and are out of scope here.",
|
|
9441
|
+
},
|
|
9428
9442
|
{
|
|
9429
9443
|
// `Promise + setTimeout` direct sleep in tests is forbidden;
|
|
9430
9444
|
// tests waiting on an asynchronous condition MUST use
|
|
@@ -12273,6 +12287,41 @@ function testEsbuildPinAgreesAcrossArtifacts() {
|
|
|
12273
12287
|
bad);
|
|
12274
12288
|
}
|
|
12275
12289
|
|
|
12290
|
+
// The test-detached-async-iife antipattern (scanScope: "test") covers *.test.js,
|
|
12291
|
+
// but the legacy single-layer entry files (test/00-primitives.js …
|
|
12292
|
+
// 50-integration.js) are required + run directly by smoke.js via _runLayer and
|
|
12293
|
+
// are NOT in _testFiles(). A top-level `(async function () {...})()` there would
|
|
12294
|
+
// have the same detached false-pass — the worker awaits mod.run / mod.groups,
|
|
12295
|
+
// never a require-time IIFE — so scan those files for the same shape here. Scoped
|
|
12296
|
+
// to the IIFE pattern ONLY (not the full test-discipline catalog): those files
|
|
12297
|
+
// carry a separate, larger setTimeout-sleep cleanup that is its own task.
|
|
12298
|
+
function testNoDetachedAsyncIifeInLegacyLayerFiles() {
|
|
12299
|
+
var bad = [];
|
|
12300
|
+
var entries;
|
|
12301
|
+
try { entries = fs.readdirSync(TEST_ROOT); }
|
|
12302
|
+
catch (_e) { entries = []; }
|
|
12303
|
+
for (var i = 0; i < entries.length; i++) {
|
|
12304
|
+
if (!/^[0-9]{2}-[\w-]+\.js$/.test(entries[i])) continue;
|
|
12305
|
+
var content;
|
|
12306
|
+
try { content = fs.readFileSync(path.join(TEST_ROOT, entries[i]), "utf8"); }
|
|
12307
|
+
catch (_e) { continue; }
|
|
12308
|
+
var lines = content.split(/\r?\n/);
|
|
12309
|
+
for (var j = 0; j < lines.length; j++) {
|
|
12310
|
+
if (/^\s*(\/\/|\*|\/\*)/.test(lines[j])) continue; // skip comment lines
|
|
12311
|
+
if (/^\(async\b/.test(lines[j])) {
|
|
12312
|
+
bad.push({ file: "test/" + entries[i], line: j + 1,
|
|
12313
|
+
content: "top-level `(async` IIFE — define `async function run()` + `module.exports = { run }` " +
|
|
12314
|
+
"and invoke under `if (require.main === module)`; a detached async IIFE false-passes its " +
|
|
12315
|
+
"post-await assertions (the worker awaits mod.run / mod.groups, not a require-time IIFE)" });
|
|
12316
|
+
}
|
|
12317
|
+
}
|
|
12318
|
+
}
|
|
12319
|
+
bad = _filterMarkers(bad, "test-detached-async-iife-legacy");
|
|
12320
|
+
_report("no detached top-level async IIFE in the legacy single-layer smoke entry files " +
|
|
12321
|
+
"(test/NN-*.js run via smoke.js _runLayer — an IIFE there false-passes like in a *.test.js)",
|
|
12322
|
+
bad);
|
|
12323
|
+
}
|
|
12324
|
+
|
|
12276
12325
|
// v1 — error codes are the operator-grep contract and must be
|
|
12277
12326
|
// `namespace/kebab-case`. The first string argument to `new XError(...)`
|
|
12278
12327
|
// and `XError.factory(...)` IS the code (defineClass constructor signature
|
|
@@ -13235,6 +13284,7 @@ async function run() {
|
|
|
13235
13284
|
// step's port mapping + curl host.
|
|
13236
13285
|
testWikiPortAgreesAcrossArtifacts();
|
|
13237
13286
|
testEsbuildPinAgreesAcrossArtifacts();
|
|
13287
|
+
testNoDetachedAsyncIifeInLegacyLayerFiles();
|
|
13238
13288
|
testNoTrackedInternalNotes();
|
|
13239
13289
|
testResidencyGatesWired();
|
|
13240
13290
|
testWikiStopGraceExceedsShutdownBudget();
|
|
@@ -681,7 +681,7 @@ function testFetcherValidation() {
|
|
|
681
681
|
|
|
682
682
|
// ---- Run all ----
|
|
683
683
|
|
|
684
|
-
|
|
684
|
+
function _syncTests() {
|
|
685
685
|
testNormalize();
|
|
686
686
|
testTokenize();
|
|
687
687
|
testLevenshtein();
|
|
@@ -715,12 +715,20 @@ function testFetcherValidation() {
|
|
|
715
715
|
testAliasEmpty();
|
|
716
716
|
testAliasExtraPairs();
|
|
717
717
|
testAliasIntegrationWithScreen();
|
|
718
|
-
}
|
|
718
|
+
}
|
|
719
719
|
|
|
720
|
-
// Fetcher tests are async; run them in their own block
|
|
721
|
-
|
|
720
|
+
// Fetcher tests are async; run them in their own block.
|
|
721
|
+
async function _fetcherTests() {
|
|
722
722
|
await testFetcherTickRefresh();
|
|
723
723
|
await testFetcherFetchFailure();
|
|
724
724
|
await testFetcherEmptyResult();
|
|
725
725
|
testFetcherValidation();
|
|
726
|
-
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
async function run() {
|
|
729
|
+
_syncTests();
|
|
730
|
+
await _fetcherTests();
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
module.exports = { run: run };
|
|
734
|
+
if (require.main === module) run().catch(function (e) { console.error(e); process.exit(1); });
|
|
@@ -3,7 +3,7 @@ var helpers = require("../helpers");
|
|
|
3
3
|
var b = helpers.b;
|
|
4
4
|
var check = helpers.check;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
async function run() {
|
|
7
7
|
var cra = b.cra.report.create({
|
|
8
8
|
audit: false,
|
|
9
9
|
productId: "blamejs-1.x",
|
|
@@ -28,4 +28,7 @@ var check = helpers.check;
|
|
|
28
28
|
check("cra refuses missing manufacturer", threwNoMfg);
|
|
29
29
|
|
|
30
30
|
console.log("OK — cra.report tests");
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = { run: run };
|
|
34
|
+
if (require.main === module) run().catch(function (e) { console.error(e); process.exit(1); });
|
|
@@ -47,12 +47,17 @@ function _mockRes() {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function _drive(mw, req, res) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
async function _drive(mw, req, res) {
|
|
51
|
+
// Hung-detection: the middleware is given a real-time window to either call
|
|
52
|
+
// next() or end the response; whichever happened decides the outcome. This
|
|
53
|
+
// is a verify-over-a-window observation (we let the full window elapse to
|
|
54
|
+
// see what the middleware did), so passiveObserve is the right primitive —
|
|
55
|
+
// it clears its own timer when the window completes, leaving nothing behind.
|
|
56
|
+
var nextCalled = false;
|
|
57
|
+
mw(req, res, function () { nextCalled = true; });
|
|
58
|
+
await helpers.passiveObserve(200, "daily-byte-quota: middleware-hung detection window"); // allow:raw-byte-literal — detection window ms
|
|
59
|
+
if (nextCalled) return "next";
|
|
60
|
+
return res._captured.ended ? "next" : "hung";
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
async function testQuotaBelowLimitPasses() {
|
|
@@ -142,12 +147,18 @@ function testSkipPathsBypass() {
|
|
|
142
147
|
check("skipPaths bypass calls next", seen.length === 2);
|
|
143
148
|
}
|
|
144
149
|
|
|
145
|
-
|
|
150
|
+
async function run() {
|
|
146
151
|
await testQuotaBelowLimitPasses();
|
|
147
152
|
await testQuotaAboveLimitRefuses();
|
|
148
153
|
await testGetKeyOverride();
|
|
149
154
|
await testNullKeyBypassesQuota();
|
|
150
155
|
testCreateRefusesBadQuota();
|
|
151
156
|
testSkipPathsBypass();
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
module.exports = { run: run };
|
|
160
|
+
|
|
161
|
+
if (require.main === module) {
|
|
162
|
+
run().then(function () { console.log("OK — daily-byte-quota tests"); })
|
|
163
|
+
.catch(function (e) { console.error(e); process.exit(1); });
|
|
164
|
+
}
|
|
@@ -1002,7 +1002,7 @@ async function testResealValidationAndStore() {
|
|
|
1002
1002
|
|
|
1003
1003
|
// ---- Run all ----
|
|
1004
1004
|
|
|
1005
|
-
|
|
1005
|
+
async function run() {
|
|
1006
1006
|
await testSubmitAccess();
|
|
1007
1007
|
await testSubmitErasure();
|
|
1008
1008
|
await testSubmitInvalidType();
|
|
@@ -1062,4 +1062,10 @@ async function testResealValidationAndStore() {
|
|
|
1062
1062
|
// AAD_ROTATION descriptor + reseal
|
|
1063
1063
|
testAadRotationDescriptor();
|
|
1064
1064
|
await testResealValidationAndStore();
|
|
1065
|
-
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
module.exports = { run: run };
|
|
1068
|
+
|
|
1069
|
+
if (require.main === module) {
|
|
1070
|
+
run().catch(function (e) { console.error(e); process.exit(1); });
|
|
1071
|
+
}
|
|
@@ -445,22 +445,41 @@ async function testInternalVerifyRejectsBadJws() {
|
|
|
445
445
|
|
|
446
446
|
// ---- run ----
|
|
447
447
|
|
|
448
|
+
// fido-mds3.fetch dials the MDS3 endpoint through the shared httpClient
|
|
449
|
+
// keep-alive transport pool; a cached client socket finalizes its destroy on a
|
|
450
|
+
// later event-loop turn, past the forked worker's grace window. Reset the pool,
|
|
451
|
+
// then poll until every TCP handle has actually drained so it doesn't outlive
|
|
452
|
+
// run().
|
|
453
|
+
async function _drainTcpHandles() {
|
|
454
|
+
b.httpClient._resetForTest();
|
|
455
|
+
if (typeof process.getActiveResourcesInfo !== "function") return;
|
|
456
|
+
await helpers.waitUntil(function () {
|
|
457
|
+
return process.getActiveResourcesInfo().filter(function (t) {
|
|
458
|
+
return t === "TCPSocketWrap" || t === "TCPServerWrap";
|
|
459
|
+
}).length === 0;
|
|
460
|
+
}, { timeoutMs: 5000, label: "fido-mds3: TCP handle drain after _resetForTest" });
|
|
461
|
+
}
|
|
462
|
+
|
|
448
463
|
async function run() {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
+
try {
|
|
465
|
+
testSurface();
|
|
466
|
+
testLookupAaguid();
|
|
467
|
+
testVerifyAuthenticatorClean();
|
|
468
|
+
testVerifyAuthenticatorRevoked();
|
|
469
|
+
testVerifyAuthenticatorDecertified();
|
|
470
|
+
testVerifyAuthenticatorPhysicalCompromise();
|
|
471
|
+
testVerifyAuthenticatorRemoteCompromise();
|
|
472
|
+
testVerifyAuthenticatorUnknownAaguid();
|
|
473
|
+
testVerifyAuthenticatorBadInputs();
|
|
474
|
+
testCertifiedLevelPlus();
|
|
475
|
+
await testFetchRoundTrip();
|
|
476
|
+
await testFetchRejectsNonHttps();
|
|
477
|
+
await testFetchRejectsEmptyUrl();
|
|
478
|
+
await testFetchRejectsBadTimeout();
|
|
479
|
+
await testInternalVerifyRejectsBadJws();
|
|
480
|
+
} finally {
|
|
481
|
+
await _drainTcpHandles();
|
|
482
|
+
}
|
|
464
483
|
}
|
|
465
484
|
|
|
466
485
|
module.exports = { run: run };
|
|
@@ -299,16 +299,37 @@ async function testSetCorsRulesShape() {
|
|
|
299
299
|
} finally { await l.close(); }
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
+
// bucketOps.create issues its requests (storage API + token endpoint)
|
|
303
|
+
// through the shared b.httpClient keep-alive agent, whose cached client
|
|
304
|
+
// sockets (and the mock servers they keep open) would otherwise outlive
|
|
305
|
+
// run() and hold the forked worker's event loop open. Tear the pool down
|
|
306
|
+
// and poll until the TCP handles have actually closed — agent.destroy()
|
|
307
|
+
// schedules the teardown asynchronously, so polling drives the event-loop
|
|
308
|
+
// turns needed to complete it inside run().
|
|
309
|
+
async function _drainTcpHandles() {
|
|
310
|
+
b.httpClient._resetForTest();
|
|
311
|
+
if (typeof process.getActiveResourcesInfo !== "function") return;
|
|
312
|
+
await helpers.waitUntil(function () {
|
|
313
|
+
return process.getActiveResourcesInfo().filter(function (t) {
|
|
314
|
+
return t === "TCPSocketWrap" || t === "TCPServerWrap";
|
|
315
|
+
}).length === 0;
|
|
316
|
+
}, { timeoutMs: 5000, label: "gcs-bucket-ops: TCP handle drain after _resetForTest" });
|
|
317
|
+
}
|
|
318
|
+
|
|
302
319
|
async function run() {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
320
|
+
try {
|
|
321
|
+
await testSurface();
|
|
322
|
+
await testFactoryValidation();
|
|
323
|
+
await testBucketNameValidation();
|
|
324
|
+
await testCreateBucketWireShape();
|
|
325
|
+
await testCreateBucketConflict();
|
|
326
|
+
await testDeleteBucket();
|
|
327
|
+
await testListBuckets();
|
|
328
|
+
await testSetLifecycleValidationAndShape();
|
|
329
|
+
await testSetCorsRulesShape();
|
|
330
|
+
} finally {
|
|
331
|
+
await _drainTcpHandles();
|
|
332
|
+
}
|
|
312
333
|
}
|
|
313
334
|
|
|
314
335
|
module.exports = { run: run };
|
|
@@ -124,18 +124,30 @@ async function testGateContractShadowMode() {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
async function testGateContractRuntimeCap() {
|
|
127
|
+
// The slow check deliberately elapses a real-time window longer than the
|
|
128
|
+
// 50ms runtime cap so the gate refuses. passiveObserve is the right
|
|
129
|
+
// primitive for letting that window pass (it clears its own timer when the
|
|
130
|
+
// window completes). The gate aborts the check at the cap but the check's
|
|
131
|
+
// own observation keeps running, so we await its completion below before
|
|
132
|
+
// returning — that drains the in-check window so nothing lingers past run().
|
|
133
|
+
var checkDone = null;
|
|
127
134
|
var g = b.gateContract.defineGate({
|
|
128
135
|
name: "test:runtime-cap",
|
|
129
136
|
maxRuntimeMs: 50,
|
|
130
|
-
check:
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
check: function () {
|
|
138
|
+
checkDone = helpers.passiveObserve(120, "guard-csv: slow check elapses past the runtime cap") // allow:raw-byte-literal — slow-check window > runtime cap
|
|
139
|
+
.then(function () { return { ok: true, action: "serve" }; });
|
|
140
|
+
return checkDone;
|
|
133
141
|
},
|
|
134
142
|
});
|
|
135
143
|
var d = await g.check({ bytes: Buffer.from("x") });
|
|
136
144
|
check("runtime cap: refuses with check-threw issue", d.action === "refuse");
|
|
137
145
|
check("runtime cap: issues array carries check-threw",
|
|
138
146
|
d.issues.length === 1 && d.issues[0].kind === "check-threw");
|
|
147
|
+
// Let the abandoned in-check observation finish so its window-timer self-
|
|
148
|
+
// clears rather than lingering past run() (the gate already returned at the
|
|
149
|
+
// 50ms cap; this just waits out the remaining check window).
|
|
150
|
+
await checkDone;
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
async function testGateContractBeforeCheckHook() {
|