commit dcd76a615d0aaa75ced6062718853a43faa7cea8
parent d7586074d9301c7ba716916bf4dd2525c0044e2e
Author: triesap <tyson@radroots.org>
Date: Wed, 8 Apr 2026 21:33:19 +0000
tests: use direct process pipes for hyf stdio lane
Diffstat:
1 file changed, 70 insertions(+), 7 deletions(-)
diff --git a/tests/test_stdio_contract.mojo b/tests/test_stdio_contract.mojo
@@ -1,6 +1,8 @@
from std.os import getenv, setenv, unsetenv
-from std.subprocess import run
+from std.os import Pipe, Process
from std.testing import assert_equal, assert_true, TestSuite
+from std.ffi import CStringSlice, c_int, external_call
+from std.sys._libc import close, exit, vfork
from mojson import Value, loads
@@ -13,13 +15,74 @@ comptime _PACKAGE_SURFACE_FAULT_ENV = (
)
+def _dup2(oldfd: c_int, newfd: c_int) -> c_int:
+ return external_call["dup2", c_int](oldfd, newfd)
+
+
+def _read_pipe_to_string(mut pipe: Pipe) raises -> String:
+ var buffer = InlineArray[Byte, 4096](fill=0)
+ var output = String("")
+ while True:
+ var read = pipe.read_bytes(Span(buffer))
+ if read == 0:
+ break
+ output += String(
+ from_utf8=Span(ptr=buffer.unsafe_ptr(), length=Int(read))
+ )
+ return output^
+
+
def _run_hyf(request_json: String) raises -> Value:
- var command = (
- "printf '%s\\n' '"
- + request_json
- + "' | mojo run src/main.mojo"
- )
- var output = run(command)
+ var stdin_pipe = Pipe()
+ var stdout_pipe = Pipe()
+ var output = String("")
+ var command = String("mojo")
+ var argv = List[Optional[CStringSlice[ImmutAnyOrigin]]](
+ length=4, fill={}
+ )
+ argv[0] = rebind[CStringSlice[ImmutAnyOrigin]](
+ command.as_c_string_slice()
+ )
+ argv[1] = rebind[CStringSlice[ImmutAnyOrigin]](
+ "run".as_c_string_slice()
+ )
+ argv[2] = rebind[CStringSlice[ImmutAnyOrigin]](
+ "src/main.mojo".as_c_string_slice()
+ )
+
+ var pid = vfork()
+ if pid < 0:
+ raise Error("failed to spawn hyf process test child")
+
+ if pid == 0:
+ if _dup2(c_int(stdin_pipe.fd_in.value().value), 0) < 0:
+ exit(126)
+ if _dup2(c_int(stdout_pipe.fd_out.value().value), 1) < 0:
+ exit(126)
+ _ = close(c_int(stdin_pipe.fd_in.value().value))
+ _ = close(c_int(stdin_pipe.fd_out.value().value))
+ _ = close(c_int(stdout_pipe.fd_in.value().value))
+ _ = close(c_int(stdout_pipe.fd_out.value().value))
+ _ = external_call["execvp", c_int](
+ command.as_c_string_slice().unsafe_ptr(),
+ argv.unsafe_ptr(),
+ )
+ exit(127)
+
+ stdin_pipe.set_output_only()
+ stdout_pipe.set_input_only()
+
+ stdin_pipe.write_bytes((request_json + "\n").as_bytes())
+ stdin_pipe.set_input_only()
+
+ output = _read_pipe_to_string(stdout_pipe)
+ stdout_pipe.set_output_only()
+
+ var process = Process(Int(pid))
+ var status = process.wait()
+ if not status.exit_code or status.exit_code.value() != 0:
+ raise Error("hyf process exited unexpectedly")
+
if output == "":
raise Error("hyf process returned no stdout payload")
return loads(output)