Skip to content

Commit cabd58f

Browse files
joyeecheungaduh95
authored andcommitted
test: use fixture directories for sea tests
Instead of copying and writing files on the fly for SEA tests, put the fixtures into a directory and copy them into tmpdir for testing. This allows easier reproduction and debugging when they do fail - we can just copy the entire fixture directory and test directly from there. PR-URL: #61167 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 24033ee commit cabd58f

File tree

73 files changed

+649
-727
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+649
-727
lines changed

test/common/sea.js

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const common = require('../common');
44
const fixtures = require('../common/fixtures');
55
const tmpdir = require('../common/tmpdir');
66
const { inspect } = require('util');
7+
const fs = require('fs');
8+
const path = require('path');
9+
const assert = require('assert');
710

811
const { readFileSync, copyFileSync, statSync } = require('fs');
912
const {
@@ -70,37 +73,76 @@ function skipIfSingleExecutableIsNotSupported() {
7073
}
7174
}
7275

73-
function generateSEA(targetExecutable, sourceExecutable, seaBlob, verifyWorkflow = false) {
76+
function generateSEA(fixtureDir, options = {}) {
77+
const {
78+
workingDir = tmpdir.path,
79+
configPath = 'sea-config.json',
80+
verifyWorkflow = false,
81+
} = options;
82+
// Copy fixture files to working directory if they are different.
83+
if (fixtureDir !== workingDir) {
84+
fs.cpSync(fixtureDir, workingDir, { recursive: true });
85+
}
86+
87+
// Determine the output executable path.
88+
const outputFile = path.resolve(workingDir, process.platform === 'win32' ? 'sea.exe' : 'sea');
89+
7490
try {
75-
copyFileSync(sourceExecutable, targetExecutable);
91+
// Copy the executable.
92+
copyFileSync(process.execPath, outputFile);
93+
console.log(`Copied ${process.execPath} to ${outputFile}`);
7694
} catch (e) {
77-
const message = `Cannot copy ${sourceExecutable} to ${targetExecutable}: ${inspect(e)}`;
95+
const message = `Cannot copy ${process.execPath} to ${outputFile}: ${inspect(e)}`;
7896
if (verifyWorkflow) {
7997
throw new Error(message);
8098
}
8199
common.skip(message);
82100
}
83-
console.log(`Copied ${sourceExecutable} to ${targetExecutable}`);
84101

102+
// Generate the blob using --experimental-sea-config.
103+
spawnSyncAndExitWithoutError(
104+
process.execPath,
105+
['--experimental-sea-config', configPath],
106+
{
107+
cwd: workingDir,
108+
env: {
109+
NODE_DEBUG_NATIVE: 'SEA',
110+
...process.env,
111+
},
112+
},
113+
);
114+
115+
// Parse the config to get the output file path.
116+
const config = JSON.parse(fs.readFileSync(path.resolve(workingDir, configPath)));
117+
assert.strictEqual(typeof config.output, 'string');
118+
const seaPrepBlob = path.resolve(workingDir, config.output);
119+
assert(fs.existsSync(seaPrepBlob), `Expected SEA blob ${seaPrepBlob} to exist`);
120+
121+
// Use postject to inject the blob.
85122
const postjectFile = fixtures.path('postject-copy', 'node_modules', 'postject', 'dist', 'cli.js');
86123
try {
87124
spawnSyncAndExitWithoutError(process.execPath, [
88125
postjectFile,
89-
targetExecutable,
126+
outputFile,
90127
'NODE_SEA_BLOB',
91-
seaBlob,
128+
seaPrepBlob,
92129
'--sentinel-fuse', 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2',
93130
...process.platform === 'darwin' ? [ '--macho-segment-name', 'NODE_SEA' ] : [],
94131
]);
95132
} catch (e) {
96-
const message = `Cannot inject ${seaBlob} into ${targetExecutable}: ${inspect(e)}`;
133+
const message = `Cannot inject ${seaPrepBlob} into ${outputFile}: ${inspect(e)}`;
97134
if (verifyWorkflow) {
98135
throw new Error(message);
99136
}
100137
common.skip(message);
101138
}
102-
console.log(`Injected ${seaBlob} into ${targetExecutable}`);
139+
console.log(`Injected ${seaPrepBlob} into ${outputFile}`);
140+
141+
signSEA(outputFile, verifyWorkflow);
142+
return outputFile;
143+
}
103144

145+
function signSEA(targetExecutable, verifyWorkflow = false) {
104146
if (process.platform === 'darwin') {
105147
try {
106148
spawnSyncAndExitWithoutError('codesign', [ '--sign', '-', targetExecutable ]);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"main": "sea.js",
3+
"output": "sea-prep.blob",
4+
"disableExperimentalSEAWarning": true,
5+
"assets": {
6+
"hello.node": "binding.node"
7+
}
8+
}

test/fixtures/sea/addon/sea.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const sea = require('node:sea');
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
const addonPath = path.join(process.cwd(), 'hello.node');
6+
fs.writeFileSync(addonPath, new Uint8Array(sea.getRawAsset('hello.node')));
7+
const mod = {exports: {}};
8+
process.dlopen(mod, addonPath);
9+
console.log('hello,', mod.exports.hello());
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"main": "sea.js",
3+
"output": "sea-prep.blob"
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is asset 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is asset 2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is asset 3
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"main": "sea.js",
3+
"output": "sea-prep.blob",
4+
"assets": {
5+
"asset-1.txt": "asset-1.txt",
6+
"asset-2.txt": "asset-2.txt",
7+
"asset-3.txt": "asset-3.txt"
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
const { isSea, getAssetKeys } = require('node:sea');
4+
const assert = require('node:assert');
5+
6+
assert(isSea());
7+
8+
const keys = getAssetKeys();
9+
console.log('Asset keys:', JSON.stringify(keys.sort()));

0 commit comments

Comments
 (0)