Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions crates/native-sidecar/tests/builtin_conformance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4905,6 +4905,77 @@ fn unrefd_timeout_does_not_keep_guest_process_alive() {
run_isolated_builtin_conformance_test("timer-unref-exit");
}

fn unrefd_http_server_does_not_keep_guest_process_alive_impl() {
let cwd = temp_dir("builtin-http-server-unref-exit");
let entrypoint = cwd.join("entry.mjs");
write_fixture(
&entrypoint,
r#"
import http from "node:http";

const server = http.createServer((_request, response) => response.end("ok"));
server.listen(0, "127.0.0.1", () => {
server.unref();
console.log(JSON.stringify({ listening: server.listening }));
});
"#,
);

let mut sidecar = new_sidecar("http-server-unref-exit");
let connection_id = authenticate_wire(&mut sidecar, "conn-http-server-unref-exit");
let session_id = open_session_wire(&mut sidecar, 2, &connection_id);
let allowed_builtins =
serde_json::to_string(&["http", "net"]).expect("serialize http builtin allowlist");
let mut metadata = HashMap::new();
metadata.insert(
String::from("env.AGENTOS_ALLOWED_NODE_BUILTINS"),
allowed_builtins,
);
let vm_id = create_vm_with_metadata_and_permissions(
&mut sidecar,
3,
&connection_id,
&session_id,
GuestRuntimeKind::JavaScript,
&cwd,
metadata,
wire_permissions_allow_all(),
);

execute_wire(
&mut sidecar,
4,
&connection_id,
&session_id,
&vm_id,
"proc-http-server-unref-exit",
GuestRuntimeKind::JavaScript,
&entrypoint,
Vec::new(),
);

// Host Node exits as soon as the only listener is unref'd; the guest must
// not wait for the server to close.
let (stdout, stderr, exit_code) = collect_builtin_process_output_with_timeout(
&mut sidecar,
&connection_id,
&session_id,
&vm_id,
"proc-http-server-unref-exit",
Duration::from_secs(5),
);
dispose_vm_and_close_session_wire(&mut sidecar, &connection_id, &session_id, &vm_id);

assert_eq!(exit_code, 0, "guest process should exit cleanly: {stderr}");
let payload: Value = serde_json::from_str(stdout.trim()).expect("parse server stdout JSON");
assert_eq!(payload["listening"], Value::Bool(true));
}

#[test]
fn unrefd_http_server_does_not_keep_guest_process_alive() {
run_isolated_builtin_conformance_test("http-server-unref-exit");
}

fn run_named_case(case_name: &str) {
match case_name {
"fs" => fs_conformance_matches_host_node(),
Expand Down Expand Up @@ -4998,6 +5069,7 @@ fn __builtin_conformance_extra_test_runner() {
"os-resource-limits" => os_resource_limits_are_vm_scoped_impl(),
"timer-handle-ref-refresh" => timer_handle_ref_refresh_matches_host_node_impl(),
"timer-unref-exit" => unrefd_timeout_does_not_keep_guest_process_alive_impl(),
"http-server-unref-exit" => unrefd_http_server_does_not_keep_guest_process_alive_impl(),
"fs-write-file-numeric-fd" => write_file_sync_numeric_fd_matches_host_node_impl(),
other => panic!("unknown builtin conformance extra test: {other}"),
}
Expand Down
6 changes: 6 additions & 0 deletions packages/build-tools/bridge-src/builtins/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3556,6 +3556,7 @@ var Server = class {
_listeners = {};
_serverId;
_netServer = null;
_refed = true;
_listenPromise = null;
_address = null;
_handleId = null;
Expand Down Expand Up @@ -3633,6 +3634,7 @@ var Server = class {
debugBridgeNetwork("server listen start", this._serverId, port, hostname);
const netServer = new NetServer({ allowHalfOpen: true });
this._netServer = netServer;
if (!this._refed) netServer.unref();
netServer.on("connection", (socket) => {
if (this._tlsOptions) {
const tlsSocket = new TLSSocket(socket, {
Expand Down Expand Up @@ -3806,9 +3808,13 @@ var Server = class {
return this;
}
ref() {
this._refed = true;
this._netServer?.ref();
return this;
}
unref() {
this._refed = false;
this._netServer?.unref();
return this;
}
};
Expand Down
Loading