Skip to content

Commit 865d4bc

Browse files
committed
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.
1 parent d991f69 commit 865d4bc

File tree

73 files changed

+695
-738
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

+695
-738
lines changed

test/common/sea.js

Lines changed: 45 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,71 @@ function skipIfSingleExecutableIsNotSupported() {
7073
}
7174
}
7275

73-
function generateSEA(targetExecutable, sourceExecutable, seaBlob, verifyWorkflow = false) {
76+
function generateSEA(fixtureDir, workingDir = tmpdir.path, configPath = 'sea-config.json', verifyWorkflow = false) {
77+
// Copy fixture files to working directory if they are different.
78+
if (fixtureDir !== workingDir) {
79+
fs.cpSync(fixtureDir, workingDir, { recursive: true });
80+
}
81+
82+
// Determine the output executable path.
83+
const outputFile = path.resolve(workingDir, process.platform === 'win32' ? 'sea.exe' : 'sea');
84+
7485
try {
75-
copyFileSync(sourceExecutable, targetExecutable);
86+
// Copy the executable.
87+
copyFileSync(process.execPath, outputFile);
88+
console.log(`Copied ${process.execPath} to ${outputFile}`);
7689
} catch (e) {
77-
const message = `Cannot copy ${sourceExecutable} to ${targetExecutable}: ${inspect(e)}`;
90+
const message = `Cannot copy ${process.execPath} to ${outputFile}: ${inspect(e)}`;
7891
if (verifyWorkflow) {
7992
throw new Error(message);
8093
}
8194
common.skip(message);
8295
}
83-
console.log(`Copied ${sourceExecutable} to ${targetExecutable}`);
8496

97+
// Generate the blob using --experimental-sea-config.
98+
spawnSyncAndExitWithoutError(
99+
process.execPath,
100+
['--experimental-sea-config', configPath],
101+
{
102+
cwd: workingDir,
103+
env: {
104+
NODE_DEBUG_NATIVE: 'SEA',
105+
...process.env,
106+
},
107+
},
108+
);
109+
110+
// Parse the config to get the output file path.
111+
const config = JSON.parse(fs.readFileSync(path.resolve(workingDir, configPath)));
112+
assert.strictEqual(typeof config.output, 'string');
113+
const seaPrepBlob = path.resolve(workingDir, config.output);
114+
assert(fs.existsSync(seaPrepBlob), `Expected SEA blob ${seaPrepBlob} to exist`);
115+
116+
// Use postject to inject the blob.
85117
const postjectFile = fixtures.path('postject-copy', 'node_modules', 'postject', 'dist', 'cli.js');
86118
try {
87119
spawnSyncAndExitWithoutError(process.execPath, [
88120
postjectFile,
89-
targetExecutable,
121+
outputFile,
90122
'NODE_SEA_BLOB',
91-
seaBlob,
123+
seaPrepBlob,
92124
'--sentinel-fuse', 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2',
93125
...process.platform === 'darwin' ? [ '--macho-segment-name', 'NODE_SEA' ] : [],
94126
]);
95127
} catch (e) {
96-
const message = `Cannot inject ${seaBlob} into ${targetExecutable}: ${inspect(e)}`;
128+
const message = `Cannot inject ${seaPrepBlob} into ${outputFile}: ${inspect(e)}`;
97129
if (verifyWorkflow) {
98130
throw new Error(message);
99131
}
100132
common.skip(message);
101133
}
102-
console.log(`Injected ${seaBlob} into ${targetExecutable}`);
134+
console.log(`Injected ${seaPrepBlob} into ${outputFile}`);
135+
136+
signSEA(outputFile, verifyWorkflow);
137+
return outputFile;
138+
}
103139

140+
function signSEA(targetExecutable, verifyWorkflow = false) {
104141
if (process.platform === 'darwin') {
105142
try {
106143
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)