| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 949bc3c commit add1edb
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3430,6 +3430,10 @@ added: | |||
| 3430 | 3430 | - v18.9.0 | |
| 3431 | 3431 | - v16.19.0 | |
| 3432 | 3432 | changes: | |
| 3433 | + - version: REPLACEME | ||
| 3434 | + pr-url: https://github.com/nodejs/node/pull/64309 | ||
| 3435 | + description: Added `entryFile` to events forwarded from child processes | ||
| 3436 | + when tests run with process isolation. | ||
| 3433 | 3437 | - version: v24.19.0 | |
| 3434 | 3438 | pr-url: https://github.com/nodejs/node/pull/63435 | |
| 3435 | 3439 | description: Added `parentId` to test events that carry a `testId`. | |
@@ -3514,6 +3518,10 @@ Emitted when code coverage is enabled and all tests have completed. | |||
| 3514 | 3518 | * `cause` {Error} The actual error thrown by the test. | |
| 3515 | 3519 | * `type` {string|undefined} The type of the test, used to denote whether | |
| 3516 | 3520 | this is a suite. | |
| 3521 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3522 | + executed as the entry point of the child process that emitted this event. | ||
| 3523 | + Only present when tests run with process isolation. May differ from | ||
| 3524 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3517 | 3525 | * `file` {string|undefined} The path of the test file, | |
| 3518 | 3526 | `undefined` if test was run through the REPL. | |
| 3519 | 3527 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3543,6 +3551,10 @@ The corresponding declaration ordered events are `'test:pass'` and `'test:fail'` | |||
| 3543 | 3551 | * `data` {Object} | |
| 3544 | 3552 | * `column` {number|undefined} The column number where the test is defined, or | |
| 3545 | 3553 | `undefined` if the test was run through the REPL. | |
| 3554 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3555 | + executed as the entry point of the child process that emitted this event. | ||
| 3556 | + Only present when tests run with process isolation. May differ from | ||
| 3557 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3546 | 3558 | * `file` {string|undefined} The path of the test file, | |
| 3547 | 3559 | `undefined` if test was run through the REPL. | |
| 3548 | 3560 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3569,6 +3581,10 @@ defined. The corresponding declaration ordered event is `'test:start'`. | |||
| 3569 | 3581 | * `data` {Object} | |
| 3570 | 3582 | * `column` {number|undefined} The column number where the test is defined, or | |
| 3571 | 3583 | `undefined` if the test was run through the REPL. | |
| 3584 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3585 | + executed as the entry point of the child process that emitted this event. | ||
| 3586 | + Only present when tests run with process isolation. May differ from | ||
| 3587 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3572 | 3588 | * `file` {string|undefined} The path of the test file, | |
| 3573 | 3589 | `undefined` if test was run through the REPL. | |
| 3574 | 3590 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3590,6 +3606,10 @@ defined. | |||
| 3590 | 3606 | * `data` {Object} | |
| 3591 | 3607 | * `column` {number|undefined} The column number where the test is defined, or | |
| 3592 | 3608 | `undefined` if the test was run through the REPL. | |
| 3609 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3610 | + executed as the entry point of the child process that emitted this event. | ||
| 3611 | + Only present when tests run with process isolation. May differ from | ||
| 3612 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3593 | 3613 | * `file` {string|undefined} The path of the test file, | |
| 3594 | 3614 | `undefined` if test was run through the REPL. | |
| 3595 | 3615 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3622,6 +3642,10 @@ Emitted when a test is enqueued for execution. | |||
| 3622 | 3642 | this is a suite. | |
| 3623 | 3643 | * `attempt` {number|undefined} The attempt number of the test run, | |
| 3624 | 3644 | present only when using the [`--test-rerun-failures`][] flag. | |
| 3645 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3646 | + executed as the entry point of the child process that emitted this event. | ||
| 3647 | + Only present when tests run with process isolation. May differ from | ||
| 3648 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3625 | 3649 | * `file` {string|undefined} The path of the test file, | |
| 3626 | 3650 | `undefined` if test was run through the REPL. | |
| 3627 | 3651 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3685,6 +3709,10 @@ since the parent runner only knows about file-level tests. When using | |||
| 3685 | 3709 | present only when using the [`--test-rerun-failures`][] flag. | |
| 3686 | 3710 | * `passed_on_attempt` {number|undefined} The attempt number the test passed on, | |
| 3687 | 3711 | present only when using the [`--test-rerun-failures`][] flag. | |
| 3712 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3713 | + executed as the entry point of the child process that emitted this event. | ||
| 3714 | + Only present when tests run with process isolation. May differ from | ||
| 3715 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3688 | 3716 | * `file` {string|undefined} The path of the test file, | |
| 3689 | 3717 | `undefined` if test was run through the REPL. | |
| 3690 | 3718 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3714,6 +3742,10 @@ The corresponding execution ordered event is `'test:complete'`. | |||
| 3714 | 3742 | * `data` {Object} | |
| 3715 | 3743 | * `column` {number|undefined} The column number where the test is defined, or | |
| 3716 | 3744 | `undefined` if the test was run through the REPL. | |
| 3745 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3746 | + executed as the entry point of the child process that emitted this event. | ||
| 3747 | + Only present when tests run with process isolation. May differ from | ||
| 3748 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3717 | 3749 | * `file` {string|undefined} The path of the test file, | |
| 3718 | 3750 | `undefined` if test was run through the REPL. | |
| 3719 | 3751 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3730,6 +3762,10 @@ defined. | |||
| 3730 | 3762 | * `data` {Object} | |
| 3731 | 3763 | * `column` {number|undefined} The column number where the test is defined, or | |
| 3732 | 3764 | `undefined` if the test was run through the REPL. | |
| 3765 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3766 | + executed as the entry point of the child process that emitted this event. | ||
| 3767 | + Only present when tests run with process isolation. May differ from | ||
| 3768 | + `file` when the test is defined in a module imported by the entry file. | ||
| 3733 | 3769 | * `file` {string|undefined} The path of the test file, | |
| 3734 | 3770 | `undefined` if test was run through the REPL. | |
| 3735 | 3771 | * `line` {number|undefined} The line number where the test is defined, or | |
@@ -3754,6 +3790,9 @@ The corresponding execution ordered event is `'test:dequeue'`. | |||
| 3754 | 3790 | ### Event: `'test:stderr'` | |
| 3755 | 3791 | ||
| 3756 | 3792 | * `data` {Object} | |
| 3793 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3794 | + executed as the entry point of the child process that emitted this event. | ||
| 3795 | + Only present when tests run with process isolation. | ||
| 3757 | 3796 | * `file` {string} The path of the test file. | |
| 3758 | 3797 | * `message` {string} The message written to `stderr`. | |
| 3759 | 3798 | ||
@@ -3765,6 +3804,9 @@ defined. | |||
| 3765 | 3804 | ### Event: `'test:stdout'` | |
| 3766 | 3805 | ||
| 3767 | 3806 | * `data` {Object} | |
| 3807 | + * `entryFile` {string|undefined} The path of the test file that was | ||
| 3808 | + executed as the entry point of the child process that emitted this event. | ||
| 3809 | + Only present when tests run with process isolation. | ||
| 3768 | 3810 | * `file` {string} The path of the test file. | |
| 3769 | 3811 | * `message` {string} The message written to `stdout`. | |
| 3770 | 3812 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -295,6 +295,10 @@ class FileTest extends Test { | |||
| 295 | 295 | ArrayPrototypeIncludes(kDiagnosticsFilterArgs, StringPrototypeSlice(comment, 0, firstSpaceIndex)); | |
| 296 | 296 | } | |
| 297 | 297 | #handleReportItem(item) { | |
| 298 | + // The name is empty when a single child process runs all test files. | ||
| 299 | + if (this.name !== '') { | ||
| 300 | + item.data.entryFile = this.loc.file; | ||
| 301 | + } | ||
| 298 | 302 | const isTopLevel = item.data.nesting === 0; | |
| 299 | 303 | if (isTopLevel) { | |
| 300 | 304 | if (item.type === 'test:plan' && this.#skipReporting()) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + import { test } from 'node:test'; | ||
| 2 | + import { runShared } from './helper.mjs'; | ||
| 3 | + test('backup A', async (t) => { await runShared(t, 'A'); }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + import { test } from 'node:test'; | ||
| 2 | + import { runShared } from './helper.mjs'; | ||
| 3 | + test('backup B', async (t) => { await runShared(t, 'B'); }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + export async function runShared(t, target) { | ||
| 2 | + await t.test(`restore ${target}`, async () => {}); | ||
| 3 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,59 @@ | |||
| 1 | + import '../common/index.mjs'; | ||
| 2 | + import * as fixtures from '../common/fixtures.mjs'; | ||
| 3 | + import { describe, it, run } from 'node:test'; | ||
| 4 | + import assert from 'node:assert'; | ||
| 5 | + | ||
| 6 | + const aPath = fixtures.path('test-runner', 'entry-file', 'a.test.mjs'); | ||
| 7 | + const bPath = fixtures.path('test-runner', 'entry-file', 'b.test.mjs'); | ||
| 8 | + const helperPath = fixtures.path('test-runner', 'entry-file', 'helper.mjs'); | ||
| 9 | + | ||
| 10 | + async function collectEvents(options) { | ||
| 11 | + const events = []; | ||
| 12 | + const stream = run({ files: [aPath, bPath], ...options }); | ||
| 13 | + stream.on('test:fail', () => {}); | ||
| 14 | + for await (const event of stream) { | ||
| 15 | + events.push(event); | ||
| 16 | + } | ||
| 17 | + return events; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + describe('entryFile attribution in reporter events', { concurrency: false }, () => { | ||
| 21 | + it('stamps entryFile on events forwarded from child processes', async () => { | ||
| 22 | + const events = await collectEvents({ isolation: 'process' }); | ||
| 23 | + const checked = { __proto__: null, A: 0, B: 0 }; | ||
| 24 | + | ||
| 25 | + for (const { type, data } of events) { | ||
| 26 | + if (data?.name === 'restore A' || data?.name === 'restore B') { | ||
| 27 | + const target = data.name === 'restore A' ? 'A' : 'B'; | ||
| 28 | + const expectedEntry = target === 'A' ? aPath : bPath; | ||
| 29 | + assert.strictEqual(data.file, helperPath, | ||
| 30 | + `${type} file should be the definition site`); | ||
| 31 | + assert.strictEqual(data.entryFile, expectedEntry, | ||
| 32 | + `${type} entryFile should be the entry file`); | ||
| 33 | + checked[target]++; | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + // Each subtest emits at least enqueue/dequeue/start/pass/complete. | ||
| 38 | + assert.ok(checked.A >= 4, `expected events for restore A, got ${checked.A}`); | ||
| 39 | + assert.ok(checked.B >= 4, `expected events for restore B, got ${checked.B}`); | ||
| 40 | + }); | ||
| 41 | + | ||
| 42 | + it('stamps entryFile on top-level tests forwarded from child processes', async () => { | ||
| 43 | + const events = await collectEvents({ isolation: 'process' }); | ||
| 44 | + const pass = events.filter(({ type }) => type === 'test:pass'); | ||
| 45 | + const backupA = pass.find(({ data }) => data.name === 'backup A'); | ||
| 46 | + const backupB = pass.find(({ data }) => data.name === 'backup B'); | ||
| 47 | + assert.strictEqual(backupA.data.entryFile, aPath); | ||
| 48 | + assert.strictEqual(backupB.data.entryFile, bPath); | ||
| 49 | + }); | ||
| 50 | + | ||
| 51 | + it('does not stamp entryFile with isolation none', async () => { | ||
| 52 | + const events = await collectEvents({ isolation: 'none' }); | ||
| 53 | + for (const { data } of events) { | ||
| 54 | + if (data?.name === 'restore A' || data?.name === 'restore B') { | ||
| 55 | + assert.strictEqual(data.entryFile, undefined); | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + }); | ||
| 59 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,6 +5,7 @@ import { describe, it, beforeEach } from 'node:test'; | |||
| 5 | 5 | import assert from 'node:assert'; | |
| 6 | 6 | import { finished } from 'node:stream/promises'; | |
| 7 | 7 | import { DefaultSerializer } from 'node:v8'; | |
| 8 | + import { resolve } from 'node:path'; | ||
| 8 | 9 | import serializer from 'internal/test_runner/reporter/v8-serializer'; | |
| 9 | 10 | import runner from 'internal/test_runner/runner'; | |
| 10 | 11 | ||
@@ -14,10 +15,15 @@ async function toArray(chunks) { | |||
| 14 | 15 | return arr; | |
| 15 | 16 | } | |
| 16 | 17 | ||
| 18 | + const entryFile = resolve('filetest'); | ||
| 17 | 19 | const diagnosticEvent = { | |
| 18 | 20 | type: 'test:diagnostic', | |
| 19 | 21 | data: { nesting: 0, details: {}, message: 'diagnostic' }, | |
| 20 | 22 | }; | |
| 23 | + const reportedDiagnosticEvent = { | ||
| 24 | + type: 'test:diagnostic', | ||
| 25 | + data: { ...diagnosticEvent.data, entryFile }, | ||
| 26 | + }; | ||
| 21 | 27 | const chunks = await toArray(serializer([diagnosticEvent])); | |
| 22 | 28 | const defaultSerializer = new DefaultSerializer(); | |
| 23 | 29 | defaultSerializer.writeHeader(); | |
@@ -67,28 +73,28 @@ describe('v8 deserializer', common.mustCall(() => { | |||
| 67 | 73 | it('should deserialize a chunk with no serialization', async () => { | |
| 68 | 74 | const reported = await collectReported([Buffer.from('unknown')]); | |
| 69 | 75 | assert.deepStrictEqual(reported, [ | |
| 70 | - { data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 76 | + { data: { __proto__: null, entryFile, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 71 | 77 | ]); | |
| 72 | 78 | }); | |
| 73 | 79 | ||
| 74 | 80 | it('should deserialize a serialized chunk', async () => { | |
| 75 | 81 | const reported = await collectReported(chunks); | |
| 76 | - assert.deepStrictEqual(reported, [diagnosticEvent]); | ||
| 82 | + assert.deepStrictEqual(reported, [reportedDiagnosticEvent]); | ||
| 77 | 83 | }); | |
| 78 | 84 | ||
| 79 | 85 | it('should deserialize a serialized chunk after non-serialized chunk', async () => { | |
| 80 | 86 | const reported = await collectReported([Buffer.concat([Buffer.from('unknown'), ...chunks])]); | |
| 81 | 87 | assert.deepStrictEqual(reported, [ | |
| 82 | - { data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 83 | - diagnosticEvent, | ||
| 88 | + { data: { __proto__: null, entryFile, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 89 | + reportedDiagnosticEvent, | ||
| 84 | 90 | ]); | |
| 85 | 91 | }); | |
| 86 | 92 | ||
| 87 | 93 | it('should deserialize a serialized chunk before non-serialized output', async () => { | |
| 88 | 94 | const reported = await collectReported([Buffer.concat([ ...chunks, Buffer.from('unknown')])]); | |
| 89 | 95 | assert.deepStrictEqual(reported, [ | |
| 90 | - diagnosticEvent, | ||
| 91 | - { data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 96 | + reportedDiagnosticEvent, | ||
| 97 | + { data: { __proto__: null, entryFile, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 92 | 98 | ]); | |
| 93 | 99 | }); | |
| 94 | 100 | ||
@@ -131,7 +137,7 @@ describe('v8 deserializer', common.mustCall(() => { | |||
| 131 | 137 | oversizedLengthHeader, | |
| 132 | 138 | ...chunks, | |
| 133 | 139 | ]); | |
| 134 | - assert.deepStrictEqual(reported.at(-1), diagnosticEvent); | ||
| 140 | + assert.deepStrictEqual(reported.at(-1), reportedDiagnosticEvent); | ||
| 135 | 141 | assert.strictEqual(reported.filter((event) => event.type === 'test:diagnostic').length, 1); | |
| 136 | 142 | assert.strictEqual(collectStdout(reported), oversizedLengthStdout); | |
| 137 | 143 | }); | |
@@ -152,7 +158,7 @@ describe('v8 deserializer', common.mustCall(() => { | |||
| 152 | 158 | const data = chunks[0]; | |
| 153 | 159 | const reported = await collectReported([data.subarray(0, i), data.subarray(i)]); | |
| 154 | 160 | assert.deepStrictEqual(reported, [ | |
| 155 | - diagnosticEvent, | ||
| 161 | + reportedDiagnosticEvent, | ||
| 156 | 162 | ]); | |
| 157 | 163 | }); | |
| 158 | 164 | ||
@@ -163,9 +169,9 @@ describe('v8 deserializer', common.mustCall(() => { | |||
| 163 | 169 | Buffer.concat([data.subarray(i), Buffer.from('unknown')]), | |
| 164 | 170 | ]); | |
| 165 | 171 | assert.deepStrictEqual(reported, [ | |
| 166 | - { data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 167 | - diagnosticEvent, | ||
| 168 | - { data: { __proto__: null, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 172 | + { data: { __proto__: null, entryFile, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 173 | + reportedDiagnosticEvent, | ||
| 174 | + { data: { __proto__: null, entryFile, file: 'filetest', message: 'unknown' }, type: 'test:stdout' }, | ||
| 169 | 175 | ]); | |
| 170 | 176 | } | |
| 171 | 177 | ); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments