Skip to content

Commit 85ee712

Browse files
fix(matrix): use fixed crypto bootstrap command (#97181)
* fix(matrix): use fixed crypto bootstrap command * chore(matrix): drop release metadata bump
1 parent 72f837a commit 85ee712

2 files changed

Lines changed: 50 additions & 63 deletions

File tree

extensions/matrix/src/matrix/deps.test.ts

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -56,55 +56,54 @@ function resolveTestNativeBindingFilename(): string | null {
5656

5757
describe("ensureMatrixCryptoRuntime", () => {
5858
it("returns immediately when matrix SDK loads", async () => {
59-
const runCommand = vi.fn();
6059
const requireFn = vi.fn(() => ({}));
6160

6261
await ensureMatrixCryptoRuntime({
6362
log: logStub,
6463
requireFn,
65-
runCommand,
6664
resolveFn: () => "/tmp/download-lib.js",
67-
nodeExecutable: "/usr/bin/node",
6865
});
6966

7067
expect(requireFn).toHaveBeenCalledTimes(1);
71-
expect(runCommand).not.toHaveBeenCalled();
7268
});
7369

7470
it("bootstraps missing crypto runtime and retries matrix SDK load", async () => {
75-
let bootstrapped = false;
71+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-crypto-bootstrap-"));
72+
const scriptPath = path.join(tmpDir, "download-lib.js");
73+
const markerPath = path.join(tmpDir, "bootstrapped");
74+
fs.writeFileSync(
75+
scriptPath,
76+
[
77+
'const fs = require("node:fs");',
78+
`if (fs.realpathSync(process.cwd()) !== ${JSON.stringify(fs.realpathSync(tmpDir))}) process.exit(2);`,
79+
'if (process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT !== "0") process.exit(3);',
80+
`fs.writeFileSync(${JSON.stringify(markerPath)}, "ok");`,
81+
].join("\n"),
82+
);
7683
const requireFn = vi.fn(() => {
77-
if (!bootstrapped) {
84+
if (!fs.existsSync(markerPath)) {
7885
throw new Error(
7986
"Cannot find module '@matrix-org/matrix-sdk-crypto-nodejs-linux-x64-gnu' (required by matrix sdk)",
8087
);
8188
}
8289
return {};
8390
});
84-
const runCommand = vi.fn(async () => {
85-
bootstrapped = true;
86-
return { code: 0, stdout: "", stderr: "" };
87-
});
8891

89-
await ensureMatrixCryptoRuntime({
90-
log: logStub,
91-
requireFn,
92-
runCommand,
93-
resolveFn: () => "/tmp/download-lib.js",
94-
nodeExecutable: "/usr/bin/node",
95-
});
92+
try {
93+
await ensureMatrixCryptoRuntime({
94+
log: logStub,
95+
requireFn,
96+
resolveFn: () => scriptPath,
97+
});
9698

97-
expect(runCommand).toHaveBeenCalledWith({
98-
argv: ["/usr/bin/node", "/tmp/download-lib.js"],
99-
cwd: "/tmp",
100-
timeoutMs: 300_000,
101-
env: { COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" },
102-
});
103-
expect(requireFn).toHaveBeenCalledTimes(2);
99+
expect(fs.readFileSync(markerPath, "utf8")).toBe("ok");
100+
expect(requireFn).toHaveBeenCalledTimes(2);
101+
} finally {
102+
fs.rmSync(tmpDir, { recursive: true, force: true });
103+
}
104104
});
105105

106106
it("rethrows non-crypto module errors without bootstrapping", async () => {
107-
const runCommand = vi.fn();
108107
const requireFn = vi.fn(() => {
109108
throw new Error("Cannot find module 'not-the-matrix-crypto-runtime'");
110109
});
@@ -113,13 +112,10 @@ describe("ensureMatrixCryptoRuntime", () => {
113112
ensureMatrixCryptoRuntime({
114113
log: logStub,
115114
requireFn,
116-
runCommand,
117115
resolveFn: () => "/tmp/download-lib.js",
118-
nodeExecutable: "/usr/bin/node",
119116
}),
120117
).rejects.toThrow("Cannot find module 'not-the-matrix-crypto-runtime'");
121118

122-
expect(runCommand).not.toHaveBeenCalled();
123119
expect(requireFn).toHaveBeenCalledTimes(1);
124120
});
125121

@@ -132,38 +128,39 @@ describe("ensureMatrixCryptoRuntime", () => {
132128
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-crypto-runtime-"));
133129
const scriptPath = path.join(tmpDir, "download-lib.js");
134130
const nativeBindingPath = path.join(tmpDir, nativeBindingFilename);
135-
fs.writeFileSync(scriptPath, "");
131+
fs.writeFileSync(
132+
scriptPath,
133+
[
134+
'const fs = require("node:fs");',
135+
`fs.writeFileSync(${JSON.stringify(nativeBindingPath)}, Buffer.alloc(1_000_000));`,
136+
].join("\n"),
137+
);
136138
fs.writeFileSync(nativeBindingPath, Buffer.alloc(16));
137139

138-
let bootstrapped = false;
139140
const requireFn = vi.fn(() => {
140-
if (!bootstrapped) {
141+
if (!fs.existsSync(nativeBindingPath) || fs.statSync(nativeBindingPath).size < 1_000_000) {
141142
throw new Error(
142143
"Cannot find module '@matrix-org/matrix-sdk-crypto-nodejs-linux-x64-gnu' (required by matrix sdk)",
143144
);
144145
}
145146
return {};
146147
});
147-
const runCommand = vi.fn(async () => {
148-
bootstrapped = true;
149-
fs.writeFileSync(nativeBindingPath, Buffer.alloc(1_000_000));
150-
return { code: 0, stdout: "", stderr: "" };
151-
});
152148

153-
await ensureMatrixCryptoRuntime({
154-
log: logStub,
155-
requireFn,
156-
runCommand,
157-
resolveFn: () => scriptPath,
158-
nodeExecutable: "/usr/bin/node",
159-
});
160-
161-
expect(runCommand).toHaveBeenCalledTimes(1);
162-
expect(requireFn).toHaveBeenCalledTimes(2);
163-
expect(fs.statSync(nativeBindingPath).size).toBe(1_000_000);
164-
expect(logStub).toHaveBeenCalledWith(
165-
"matrix: removed incomplete native crypto runtime (16 bytes); it will be downloaded again",
166-
);
149+
try {
150+
await ensureMatrixCryptoRuntime({
151+
log: logStub,
152+
requireFn,
153+
resolveFn: () => scriptPath,
154+
});
155+
156+
expect(requireFn).toHaveBeenCalledTimes(2);
157+
expect(fs.statSync(nativeBindingPath).size).toBe(1_000_000);
158+
expect(logStub).toHaveBeenCalledWith(
159+
"matrix: removed incomplete native crypto runtime (16 bytes); it will be downloaded again",
160+
);
161+
} finally {
162+
fs.rmSync(tmpDir, { recursive: true, force: true });
163+
}
167164
});
168165
});
169166

extensions/matrix/src/matrix/deps.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,7 @@ export const MATRIX_COMMAND_OUTPUT_TAIL_BYTES = 64 * 1024;
1616

1717
type MatrixCryptoRuntimeDeps = {
1818
requireFn?: (id: string) => unknown;
19-
runCommand?: (params: {
20-
argv: string[];
21-
cwd: string;
22-
timeoutMs: number;
23-
env?: NodeJS.ProcessEnv;
24-
}) => Promise<CommandResult>;
2519
resolveFn?: (id: string) => string;
26-
nodeExecutable?: string;
2720
log?: (message: string) => void;
2821
};
2922

@@ -266,8 +259,7 @@ function removeIncompleteMatrixCryptoNativeBinding(params: {
266259
export async function ensureMatrixCryptoRuntime(
267260
params: MatrixCryptoRuntimeDeps = {},
268261
): Promise<void> {
269-
const usesDefaultRuntime =
270-
!params.requireFn && !params.runCommand && !params.resolveFn && !params.nodeExecutable;
262+
const usesDefaultRuntime = !params.requireFn && !params.resolveFn;
271263
if (usesDefaultRuntime && defaultMatrixCryptoRuntimeEnsurePromise) {
272264
await defaultMatrixCryptoRuntimeEnsurePromise;
273265
return;
@@ -300,10 +292,8 @@ async function ensureMatrixCryptoRuntimeOnce(params: MatrixCryptoRuntimeDeps): P
300292

301293
const scriptPath = resolveFn("@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js");
302294
params.log?.("matrix: bootstrapping native crypto runtime");
303-
const runCommand = params.runCommand ?? runFixedCommandWithTimeout;
304-
const nodeExecutable = params.nodeExecutable ?? process.execPath;
305-
const result = await runCommand({
306-
argv: [nodeExecutable, scriptPath],
295+
const result = await runFixedCommandWithTimeout({
296+
argv: [process.execPath, scriptPath],
307297
cwd: path.dirname(scriptPath),
308298
timeoutMs: 300_000,
309299
env: { COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" },

0 commit comments

Comments
 (0)