@bongos/core 1.19.920 → 1.19.921

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.
@@ -28,6 +28,8 @@
28
28
  import assert from 'node:assert/strict';
29
29
  import { test } from 'node:test';
30
30
  import { execFileSync } from 'node:child_process';
31
+ import fs from 'node:fs';
32
+ import os from 'node:os';
31
33
  import path from 'node:path';
32
34
  import { fileURLToPath } from 'node:url';
33
35
  import { countSkips } from '../scripts/gds/run-unit-tests.js';
@@ -43,6 +45,52 @@ const SUITES = [
43
45
  { file: 'modules/security/tests/mirror.mjs', skips: 1 },
44
46
  ];
45
47
 
48
+ // realSymlinkReason — why the CONTROL run cannot be evaluated here, or null (task 1004112).
49
+ //
50
+ // Every case below that passes `forceNoSymlink: true` is evaluable anywhere: it asks a suite to
51
+ // take its skip path and checks the accounting. But the pair's second case also runs a CONTROL
52
+ // (`forceNoSymlink: false`) and asserts `ran.skipped === 0` — "where symlinks work, nothing is
53
+ // skipped". That carries an unstated precondition: symlinks work HERE.
54
+ //
55
+ // On Windows without Developer Mode they do not. A directory JUNCTION can be created, which is
56
+ // why link cases elsewhere still run and the failure looks selective, but `fs.symlinkSync` refuses
57
+ // with EPERM — so the control run legitimately skips, `ran.skipped` is 1 or 2 rather than 0, and
58
+ // four cases go red over a platform fact nobody claimed.
59
+ //
60
+ // That is a FALSE FAIL, and it is this file's own defect in mirror image: a case that does not
61
+ // apply to the platform, asserted anyway instead of skipped. The shape task 1004051 fixed in
62
+ // tests/quarantine_canonical.mjs, and the inverse of the false PASS in task 1003993 that this file
63
+ // exists to police. The file whose job is skip honesty was inferring its platform instead of
64
+ // asking.
65
+ //
66
+ // So ASK, with the same probe the suites use (mirror.mjs `canSymlink`): try to make a real
67
+ // symlink. Not `process.platform` — the question is a CAPABILITY, and Windows in Developer Mode
68
+ // answers yes while a container without CAP_SYMLINK answers no.
69
+ //
70
+ // Returns a REASON for node:test's skip, never a bare early `return`, which prints as a pass and
71
+ // is precisely the 1003993 defect.
72
+ function realSymlinkReason() {
73
+ // Deliberately ignores BONGOS_TEST_FORCE_NO_SYMLINK: that hook is how this file ASKS a suite to
74
+ // take its skip path, and honouring it here would skip the control run on every box, deleting
75
+ // the coverage instead of gating it.
76
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'skip-is-not-pass-probe-'));
77
+ const target = path.join(dir, 'probe-target');
78
+ const link = path.join(dir, 'probe-link');
79
+ try {
80
+ fs.writeFileSync(target, 'probe', 'utf8');
81
+ fs.symlinkSync(target, link);
82
+ return null;
83
+ } catch (err) {
84
+ return 'this platform cannot create a REAL symlink '
85
+ + `(${err.code || err.message}), so the control run's own link cases skip too and `
86
+ + '"where symlinks work, nothing is skipped" cannot be evaluated here. On Windows, '
87
+ + 'Developer Mode or an elevated shell makes this case run.';
88
+ } finally {
89
+ fs.rmSync(dir, { recursive: true, force: true });
90
+ }
91
+ }
92
+ const NO_REAL_SYMLINK = realSymlinkReason();
93
+
46
94
  function runSuite(file, { forceNoSymlink }) {
47
95
  const env = { ...process.env, NODE_ENV: 'test' };
48
96
  if (forceNoSymlink) env.BONGOS_TEST_FORCE_NO_SYMLINK = '1';
@@ -65,7 +113,11 @@ for (const { file, skips } of SUITES) {
65
113
  assert.equal(r.failed, 0, 'a skip is not a failure');
66
114
  });
67
115
 
68
- test(`${file}: THE BUG — skipped cases no longer inflate the passed count`, () => {
116
+ // The only case here that needs a real symlink: it compares the skip run against a CONTROL run
117
+ // in which nothing skips. Gated, not deleted — wherever symlinks work (every CI runner, Linux,
118
+ // macOS, Windows in Developer Mode) it asserts in full.
119
+ test(`${file}: THE BUG — skipped cases no longer inflate the passed count`,
120
+ { skip: NO_REAL_SYMLINK ?? false }, () => {
69
121
  // The heart of it. Under the old code BOTH runs printed the same pass count: the cases
70
122
  // that did not run were indistinguishable from the ones that did. If these two ever
71
123
  // agree again, the fake pass is back, whatever the summary line claims.
@@ -96,6 +148,31 @@ for (const { file, skips } of SUITES) {
96
148
  });
97
149
  }
98
150
 
151
+ // THE SKIP HAS TO JUSTIFY ITSELF, or it is the defect this file polices.
152
+ //
153
+ // The gate above is the dangerous kind of fix: if `realSymlinkReason()` ever returns a reason on a
154
+ // box where symlinks DO work, four cases quietly stop running and the suite still reads green —
155
+ // task 1003993's false pass, reintroduced by the file written to prevent it. A skip is only honest
156
+ // if its stated reason is TRUE.
157
+ //
158
+ // So each half checks the other, and exactly one of them runs on any given box:
159
+ //
160
+ // - where the probe says it CANNOT symlink, the control run must genuinely skip. If the probe is
161
+ // lying, the control run skips nothing and this reds.
162
+ // - where the probe says it CAN, the four gated cases are running, and their own
163
+ // `ran.skipped === 0` is the same assertion from the other side.
164
+ //
165
+ // Neither box can verify the other's branch, which is why the reason is CHECKED rather than
166
+ // trusted: "this platform cannot create a real symlink" is falsifiable right here.
167
+ test('the skip reason is TRUE — a platform that claims it cannot symlink really does skip',
168
+ { skip: NO_REAL_SYMLINK ? false : 'symlinks work here, so the gated cases are running and assert it themselves' }, () => {
169
+ const ran = runSuite('modules/security/tests/mirror.mjs', { forceNoSymlink: false });
170
+ assert.ok(ran.skipped > 0,
171
+ 'realSymlinkReason() claimed this platform cannot create a real symlink, but the control run '
172
+ + `skipped nothing (${ran.skipped}) — the probe is wrong and it is silently deleting the `
173
+ + 'coverage this file exists to protect');
174
+ });
175
+
99
176
  test('sanitize_rebuild names both physical-confinement cases it lost', () => {
100
177
  // The two that matter most: they are the ONLY coverage of physical confinement, and the
101
178
  // pair whose silent absence let task 1003848 reach CI red.
@@ -119,3 +196,16 @@ test('the runner counts those SKIP lines, so a green roll-up still says coverage
119
196
  // NAME contains the word must not be miscounted.
120
197
  assert.equal(countSkips(' ok refuses to SKIP a dangerous entry\n'), 0);
121
198
  });
199
+
200
+ test('countSkips also reads node:test\'s own summary — otherwise THIS file\'s skips are invisible', () => {
201
+ // The gap this file's own fix opened (task 1004112). node:test suites print no SKIP lines; they
202
+ // report `ℹ skipped N`. Uncounted, the roll-up says "all passed" over unrun coverage — the
203
+ // 1003993 defect one layer up, and exactly what gating the four cases above would have caused.
204
+ assert.equal(countSkips('ℹ tests 15\nℹ pass 11\nℹ fail 0\nℹ skipped 4\nℹ todo 0\n'), 4);
205
+ assert.equal(countSkips('ℹ tests 3\nℹ pass 3\nℹ skipped 0\n'), 0);
206
+ // A suite printing both formats SUMS rather than picking one — under-reporting is the failure
207
+ // mode this counter exists to prevent.
208
+ assert.equal(countSkips(' SKIP one\n SKIP two\nℹ skipped 3\n'), 5);
209
+ // The word in a case NAME must not be counted, same discipline as the SKIP line rule.
210
+ assert.equal(countSkips(' ok reports how many it skipped 9\n'), 0);
211
+ });