Skip to content

Commit 8bcaba2

Browse files
fix(ci): allow retries for fetch test
Signed-off-by: Victor Adossi <[email protected]>
1 parent 246e4da commit 8bcaba2

File tree

4 files changed

+88
-25
lines changed

4 files changed

+88
-25
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/builtins/fetch.js

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
1+
import { URL, fileURLToPath } from 'node:url';
2+
import { createServer } from 'node:net';
3+
14
import { strictEqual, ok } from 'node:assert';
25

3-
export const source = `
6+
const FETCH_URL = 'http://localhost';
7+
8+
export const state = async () => {
9+
const { getRandomPort } = await import(
10+
fileURLToPath(new URL('../util.js', import.meta.url))
11+
);
12+
const port = await getRandomPort();
13+
return { port };
14+
};
15+
16+
export const source = (testState) => {
17+
let port = testState?.port ? ':' + testState.port : '';
18+
return `
419
export async function run () {
5-
const res = await fetch('https://httpbin.org/anything');
20+
const res = await fetch('${FETCH_URL}${port}');
621
const source = await res.json();
722
console.log(source.url);
823
}
924
export function ready () {
1025
return true;
1126
}
1227
`;
28+
};
1329

1430
export const enableFeatures = ['http'];
1531

16-
export async function test(run) {
32+
export async function test(run, testState) {
33+
// Get the randomly generated port
34+
const port = testState.port;
35+
if (!port) {
36+
throw new Error('missing port on test state');
37+
}
38+
39+
// Run a local server on some port
40+
const server = createServer(async (req, res) => {
41+
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
42+
res.write(
43+
JSON.stringify({
44+
status: 'ok',
45+
}),
46+
);
47+
res.end();
48+
}).listen(port);
49+
1750
const { stdout, stderr } = await run();
1851
strictEqual(stderr, '');
19-
strictEqual(stdout.trim(), 'https://httpbin.org/anything');
52+
strictEqual(stdout.trim(), FETCH_URL);
2053
}

test/test.js

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const LOG_DEBUGGING = false;
1111
const enableAot = process.env.WEVAL_TEST == '1';
1212
const debugBuild = process.env.DEBUG_TEST == '1';
1313

14+
const noOp = async () => {};
15+
1416
function maybeLogging(disableFeatures) {
1517
if (!LOG_DEBUGGING) return disableFeatures;
1618
if (disableFeatures && disableFeatures.includes('stdio')) {
@@ -25,12 +27,23 @@ suite('Builtins', () => {
2527
const name = filename.slice(0, -3);
2628
test(name, async () => {
2729
const {
30+
state,
2831
source,
2932
test: runTest,
3033
disableFeatures,
3134
enableFeatures,
3235
} = await import(`./builtins/${filename}`);
3336

37+
// If an args object was provided, generate the arguments to feed to both
38+
// source generation (if necessary) and the test run itself
39+
let stateFn = state ?? noOp;
40+
const stateObj = await stateFn();
41+
42+
// If the source is a function then invoke it to generate the source string, possibly with arguments
43+
if (typeof source === 'function') {
44+
source(stateObj);
45+
}
46+
3447
const { component } = await componentize(
3548
source,
3649
`
@@ -46,7 +59,7 @@ suite('Builtins', () => {
4659
enableFeatures,
4760
disableFeatures: maybeLogging(disableFeatures),
4861
enableAot,
49-
}
62+
},
5063
);
5164

5265
const { files } = await transpile(component, {
@@ -61,13 +74,13 @@ suite('Builtins', () => {
6174

6275
await writeFile(
6376
new URL(`./output/${name}.component.wasm`, import.meta.url),
64-
component
77+
component,
6578
);
6679

6780
for (const file of Object.keys(files)) {
6881
await writeFile(
6982
new URL(`./output/${name}/${file}`, import.meta.url),
70-
files[file]
83+
files[file],
7184
);
7285
}
7386

@@ -76,11 +89,12 @@ suite('Builtins', () => {
7689
`
7790
import { run } from './${name}.js';
7891
run();
79-
`
92+
`,
8093
);
8194

8295
try {
83-
await runTest(async function run() {
96+
// Build a run function to pass to the test
97+
const runFn = async function run() {
8498
let stdout = '',
8599
stderr = '',
86100
timeout;
@@ -90,10 +104,10 @@ suite('Builtins', () => {
90104
process.argv[0],
91105
[
92106
fileURLToPath(
93-
new URL(`./output/${name}/run.js`, import.meta.url)
107+
new URL(`./output/${name}/run.js`, import.meta.url),
94108
),
95109
],
96-
{ stdio: 'pipe' }
110+
{ stdio: 'pipe' },
97111
);
98112
cp.stdout.on('data', (chunk) => {
99113
stdout += chunk;
@@ -103,16 +117,16 @@ suite('Builtins', () => {
103117
});
104118
cp.on('error', reject);
105119
cp.on('exit', (code) =>
106-
code === 0 ? resolve() : reject(new Error(stderr || stdout))
120+
code === 0 ? resolve() : reject(new Error(stderr || stdout)),
107121
);
108122
timeout = setTimeout(() => {
109123
reject(
110124
new Error(
111125
'test timed out with output:\n' +
112126
stdout +
113127
'\n\nstderr:\n' +
114-
stderr
115-
)
128+
stderr,
129+
),
116130
);
117131
}, 10_000);
118132
});
@@ -123,7 +137,10 @@ suite('Builtins', () => {
123137
}
124138

125139
return { stdout, stderr };
126-
});
140+
};
141+
142+
// Run the actual test
143+
await runTest(runFn, stateObj);
127144
} catch (err) {
128145
if (err.stderr) console.error(err.stderr);
129146
throw err.err || err;
@@ -138,7 +155,7 @@ suite('Bindings', () => {
138155
test(name, async () => {
139156
const source = await readFile(
140157
new URL(`./cases/${name}/source.js`, import.meta.url),
141-
'utf8'
158+
'utf8',
142159
);
143160

144161
let witWorld,
@@ -148,14 +165,14 @@ suite('Bindings', () => {
148165
try {
149166
witWorld = await readFile(
150167
new URL(`./cases/${name}/world.wit`, import.meta.url),
151-
'utf8'
168+
'utf8',
152169
);
153170
} catch (e) {
154171
if (e?.code == 'ENOENT') {
155172
try {
156173
isWasiTarget = true;
157174
witPath = fileURLToPath(
158-
new URL(`./cases/${name}/wit`, import.meta.url)
175+
new URL(`./cases/${name}/wit`, import.meta.url),
159176
);
160177
await readdir(witPath);
161178
} catch (e) {
@@ -229,14 +246,14 @@ suite('Bindings', () => {
229246

230247
await writeFile(
231248
new URL(`./output/${name}.component.wasm`, import.meta.url),
232-
component
249+
component,
233250
);
234251

235252
for (const file of Object.keys(files)) {
236253
let source = files[file];
237254
await writeFile(
238255
new URL(`./output/${name}/${file}`, import.meta.url),
239-
source
256+
source,
240257
);
241258
}
242259

@@ -274,12 +291,12 @@ suite('WASI', () => {
274291
worldName: 'test1',
275292
enableAot,
276293
debugBuild,
277-
}
294+
},
278295
);
279296

280297
await writeFile(
281298
new URL(`./output/wasi.component.wasm`, import.meta.url),
282-
component
299+
component,
283300
);
284301

285302
const { files } = await transpile(component, { tracing: DEBUG_TRACING });
@@ -291,7 +308,7 @@ suite('WASI', () => {
291308
for (const file of Object.keys(files)) {
292309
await writeFile(
293310
new URL(`./output/wasi/${file}`, import.meta.url),
294-
files[file]
311+
files[file],
295312
);
296313
}
297314

test/util.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createServer } from 'node:net';
2+
3+
// Utility function for getting a random port
4+
export async function getRandomPort() {
5+
return await new Promise((resolve) => {
6+
const server = createServer();
7+
server.listen(0, function () {
8+
const port = this.address().port;
9+
server.on('close', () => resolve(port));
10+
server.close();
11+
});
12+
});
13+
}

0 commit comments

Comments
 (0)