Skip to content

Commit cf3ac85

Browse files
NathanFlurryclaude
andcommitted
test: add http.createServer inside VM integration test
Verifies that CJS scripts using http.createServer can listen on a port and respond to HTTP requests through the kernel socket table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 87858c1 commit cf3ac85

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Tests for http.createServer inside the V8 runtime.
3+
*
4+
* Verifies that CJS scripts using http.createServer can listen on a port
5+
* and respond to HTTP requests routed through the kernel's socket table
6+
* and HostNetworkAdapter.
7+
*/
8+
9+
import { describe, it, expect, afterEach } from 'vitest';
10+
import { createNodeRuntime } from '../src/kernel-runtime.ts';
11+
import { createNodeHostNetworkAdapter } from '../src/host-network-adapter.ts';
12+
import { createKernel, createInMemoryFileSystem, allowAll } from '@secure-exec/core';
13+
import type { Kernel } from '@secure-exec/core';
14+
15+
describe('http.createServer inside VM', () => {
16+
let kernel: Kernel;
17+
18+
afterEach(async () => {
19+
await kernel?.dispose();
20+
});
21+
22+
it('CJS http server listens and responds to requests', async () => {
23+
kernel = createKernel({
24+
filesystem: createInMemoryFileSystem(),
25+
hostNetworkAdapter: createNodeHostNetworkAdapter(),
26+
permissions: allowAll,
27+
});
28+
await kernel.mount(createNodeRuntime());
29+
30+
const serverScript = `
31+
const http = require("http");
32+
const server = http.createServer((req, res) => {
33+
res.writeHead(200, { "Content-Type": "application/json" });
34+
res.end(JSON.stringify({ status: "ok", method: req.method, url: req.url }));
35+
});
36+
server.listen(0, "0.0.0.0", () => {
37+
console.log("LISTENING:" + server.address().port);
38+
});
39+
`;
40+
await kernel.vfs.writeFile('/tmp/server.js', serverScript);
41+
42+
let resolvePort: (port: number) => void;
43+
const portPromise = new Promise<number>((resolve) => {
44+
resolvePort = resolve;
45+
});
46+
47+
const proc = kernel.spawn('node', ['/tmp/server.js'], {
48+
onStdout: (data) => {
49+
const text = new TextDecoder().decode(data);
50+
const match = text.match(/LISTENING:(\d+)/);
51+
if (match) resolvePort(Number(match[1]));
52+
},
53+
});
54+
55+
const port = await portPromise;
56+
expect(port).toBeGreaterThan(0);
57+
58+
// Make a request to the server running inside the VM
59+
const response = await globalThis.fetch(`http://127.0.0.1:${port}/test`);
60+
expect(response.ok).toBe(true);
61+
62+
const json = await response.json();
63+
expect(json).toEqual({
64+
status: 'ok',
65+
method: 'GET',
66+
url: '/test',
67+
});
68+
69+
proc.kill();
70+
}, 30_000);
71+
});

0 commit comments

Comments
 (0)