|
1 |
| -// Flags: --expose-internals |
2 | 1 | 'use strict';
|
3 | 2 |
|
4 |
| -// This list must be computed before we require any modules to |
| 3 | +// This list must be computed before we require any builtins to |
5 | 4 | // to eliminate the noise.
|
6 |
| -const actualModules = new Set(process.moduleLoadList.slice()); |
| 5 | +const list = process.moduleLoadList.slice(); |
7 | 6 |
|
8 | 7 | const common = require('../common');
|
9 | 8 | const assert = require('assert');
|
| 9 | +const { inspect } = require('util'); |
10 | 10 |
|
11 |
| -const expectedModules = new Set([ |
| 11 | +const preExecIndex = |
| 12 | + list.findIndex((i) => i.includes('pre_execution')); |
| 13 | +const actual = { |
| 14 | + beforePreExec: new Set(list.slice(0, preExecIndex)), |
| 15 | + atRunTime: new Set(list.slice(preExecIndex)), |
| 16 | +}; |
| 17 | + |
| 18 | +// Currently, we don't add additional builtins to worker snapshots. |
| 19 | +// So for worker snapshots we'll just concatenate the two. Once we |
| 20 | +// add more builtins to worker snapshots, we should also distinguish |
| 21 | +// the two stages for them. |
| 22 | +const expected = {}; |
| 23 | + |
| 24 | +expected.beforePreExec = new Set([ |
12 | 25 | 'Internal Binding builtins',
|
13 | 26 | 'Internal Binding encoding_binding',
|
14 | 27 | 'Internal Binding errors',
|
@@ -84,22 +97,25 @@ const expectedModules = new Set([
|
84 | 97 | 'NativeModule internal/modules/package_json_reader',
|
85 | 98 | 'Internal Binding module_wrap',
|
86 | 99 | 'NativeModule internal/modules/cjs/loader',
|
87 |
| - 'NativeModule internal/vm/module', |
88 |
| - 'NativeModule internal/modules/esm/utils', |
| 100 | +]); |
| 101 | + |
| 102 | +expected.atRunTime = new Set([ |
89 | 103 | 'Internal Binding wasm_web_api',
|
90 | 104 | 'Internal Binding worker',
|
91 | 105 | 'NativeModule internal/modules/run_main',
|
92 | 106 | 'NativeModule internal/net',
|
93 | 107 | 'NativeModule internal/dns/utils',
|
94 | 108 | 'NativeModule internal/process/pre_execution',
|
| 109 | + 'NativeModule internal/vm/module', |
| 110 | + 'NativeModule internal/modules/esm/utils', |
95 | 111 | ]);
|
96 | 112 |
|
97 | 113 | if (common.isMainThread) {
|
98 | 114 | [
|
99 | 115 | 'NativeModule internal/idna',
|
100 | 116 | 'NativeModule url',
|
101 |
| - ].forEach(expectedModules.add.bind(expectedModules)); |
102 |
| -} else { |
| 117 | + ].forEach(expected.beforePreExec.add.bind(expected.beforePreExec)); |
| 118 | +} else { // Worker. |
103 | 119 | [
|
104 | 120 | 'NativeModule diagnostics_channel',
|
105 | 121 | 'NativeModule internal/abort_controller',
|
@@ -127,35 +143,97 @@ if (common.isMainThread) {
|
127 | 143 | 'NativeModule stream/promises',
|
128 | 144 | 'NativeModule string_decoder',
|
129 | 145 | 'NativeModule worker_threads',
|
130 |
| - ].forEach(expectedModules.add.bind(expectedModules)); |
| 146 | + ].forEach(expected.atRunTime.add.bind(expected.atRunTime)); |
| 147 | + // For now we'll concatenate the two stages for workers. We prefer |
| 148 | + // atRunTime here because that's what currently happens for these. |
131 | 149 | }
|
132 | 150 |
|
133 | 151 | if (common.isWindows) {
|
134 | 152 | // On Windows fs needs SideEffectFreeRegExpPrototypeExec which uses vm.
|
135 |
| - expectedModules.add('NativeModule vm'); |
| 153 | + expected.atRunTime.add('NativeModule vm'); |
136 | 154 | }
|
137 | 155 |
|
138 | 156 | if (common.hasIntl) {
|
139 |
| - expectedModules.add('Internal Binding icu'); |
| 157 | + expected.beforePreExec.add('Internal Binding icu'); |
140 | 158 | }
|
141 | 159 |
|
142 | 160 | if (process.features.inspector) {
|
143 |
| - expectedModules.add('Internal Binding inspector'); |
144 |
| - expectedModules.add('NativeModule internal/inspector_async_hook'); |
145 |
| - expectedModules.add('NativeModule internal/util/inspector'); |
| 161 | + expected.beforePreExec.add('Internal Binding inspector'); |
| 162 | + expected.beforePreExec.add('NativeModule internal/util/inspector'); |
| 163 | + expected.atRunTime.add('NativeModule internal/inspector_async_hook'); |
146 | 164 | }
|
147 | 165 |
|
148 | 166 | const difference = (setA, setB) => {
|
149 | 167 | return new Set([...setA].filter((x) => !setB.has(x)));
|
150 | 168 | };
|
151 |
| -const missingModules = difference(expectedModules, actualModules); |
152 |
| -const extraModules = difference(actualModules, expectedModules); |
153 |
| -const printSet = (s) => { return `${[...s].sort().join(',\n ')}\n`; }; |
154 |
| - |
155 |
| -assert.deepStrictEqual(actualModules, expectedModules, |
156 |
| - (missingModules.size > 0 ? |
157 |
| - 'These modules were not loaded:\n ' + |
158 |
| - printSet(missingModules) : '') + |
159 |
| - (extraModules.size > 0 ? |
160 |
| - 'These modules were unexpectedly loaded:\n ' + |
161 |
| - printSet(extraModules) : '')); |
| 169 | + |
| 170 | +// Accumulate all the errors and print them at the end instead of throwing |
| 171 | +// immediately which makes it harder to update the test. |
| 172 | +const errorLogs = []; |
| 173 | +function err(message) { |
| 174 | + if (typeof message === 'string') { |
| 175 | + errorLogs.push(message); |
| 176 | + } else { |
| 177 | + // Show the items in individual lines for easier copy-pasting. |
| 178 | + errorLogs.push(inspect(message, { compact: false })); |
| 179 | + } |
| 180 | +} |
| 181 | + |
| 182 | +if (common.isMainThread) { |
| 183 | + const missing = difference(expected.beforePreExec, actual.beforePreExec); |
| 184 | + const extra = difference(actual.beforePreExec, expected.beforePreExec); |
| 185 | + if (missing.size !== 0) { |
| 186 | + err('These builtins are now no longer loaded before pre-execution.'); |
| 187 | + err('If this is intentional, remove them from `expected.beforePreExec`.'); |
| 188 | + err('\n--- These could be removed from expected.beforePreExec ---'); |
| 189 | + err([...missing].sort()); |
| 190 | + err(''); |
| 191 | + } |
| 192 | + if (extra.size !== 0) { |
| 193 | + err('These builtins are now unexpectedly loaded before pre-execution.'); |
| 194 | + err('If this is intentional, add them to `expected.beforePreExec`.'); |
| 195 | + err('\n# Note: loading more builtins before pre-execution can lead to ' + |
| 196 | + 'startup performance regression or invalid snapshots.'); |
| 197 | + err('- Consider lazy loading builtins that are not used universally.'); |
| 198 | + err('- Make sure that the builtins do not access environment dependent ' + |
| 199 | + 'states e.g. command line arguments or environment variables ' + |
| 200 | + 'during loading.'); |
| 201 | + err('- When in doubt, ask @nodejs/startup.'); |
| 202 | + err('\n--- These could be added to expected.beforePreExec ---'); |
| 203 | + err([...extra].sort()); |
| 204 | + err(''); |
| 205 | + } |
| 206 | +} |
| 207 | + |
| 208 | +if (!common.isMainThread) { |
| 209 | + // For workers, just merge beforePreExec into atRunTime for now. |
| 210 | + // When we start adding modules to the worker snapshot, this branch |
| 211 | + // can be removed and we can just remove the common.isMainThread |
| 212 | + // conditions. |
| 213 | + expected.beforePreExec.forEach(expected.atRunTime.add.bind(expected.atRunTime)); |
| 214 | + actual.beforePreExec.forEach(actual.atRunTime.add.bind(actual.atRunTime)); |
| 215 | +} |
| 216 | + |
| 217 | +{ |
| 218 | + const missing = difference(expected.atRunTime, actual.atRunTime); |
| 219 | + const extra = difference(actual.atRunTime, expected.atRunTime); |
| 220 | + if (missing.size !== 0) { |
| 221 | + err('These builtins are now no longer loaded at run time.'); |
| 222 | + err('If this is intentional, remove them from `expected.atRunTime`.'); |
| 223 | + err('\n--- These could be removed from expected.atRunTime ---'); |
| 224 | + err([...missing].sort()); |
| 225 | + err(''); |
| 226 | + } |
| 227 | + if (extra.size !== 0) { |
| 228 | + err('These builtins are now unexpectedly loaded at run time.'); |
| 229 | + err('If this is intentional, add them to `expected.atRunTime`.'); |
| 230 | + err('\n# Note: loading more builtins at run time can lead to ' + |
| 231 | + 'startup performance regression.'); |
| 232 | + err('- Consider lazy loading builtins that are not used universally.'); |
| 233 | + err('\n--- These could be added to expected.atRunTime ---'); |
| 234 | + err([...extra].sort()); |
| 235 | + err(''); |
| 236 | + } |
| 237 | +} |
| 238 | + |
| 239 | +assert.strictEqual(errorLogs.length, 0, errorLogs.join('\n')); |
0 commit comments