Source
tests/purrc/socket_sys_test.cpp
1
// Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).2
// Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.3
// System-level test for the `socket` stdlib module: ONE cohesive program that4
// exercises EVERY purr-callable function in stdlib/socket/socket.hpp end to end5
// (purrc + the C++ backend + the runtime + the linked libcheatah_socket).6
//7
// Unlike the per-function compile-run probes (socket_cr_test.cpp), this stands up8
// real loopback TCP connections on 127.0.0.1 and does full round-trips inside a9
// SINGLE cheatah process, driving both the low-level BSD path and the high-level10
// convenience helpers:11
//12
// low-level : socket -> set_reuseaddr -> bind -> listen -> local_port13
// -> (client) socket -> connect -> accept14
// -> send / recv / sendall / recv -> close15
// high-level: tcp_listen -> local_port -> tcp_connect -> accept16
// -> sendall -> recv17
// error path: connect(-1, ...) deliberately fails -> last_error() is non-empty18
//19
// All 14 exported functions are called: tcp_listen, tcp_connect, accept, recv,20
// send, sendall, close, socket, set_reuseaddr, bind, listen, connect,21
// local_port, last_error.22
//23
// Why it doesn't deadlock in one process: for 127.0.0.1 the kernel completes the24
// TCP handshake on connect() and queues the connection on the listener's accept25
// backlog, so we connect() BEFORE accept() and accept() returns immediately. The26
// payloads are tiny (fit the send buffer), so send()/sendall() never block on a27
// reader. Ports are OS-assigned (bind to port 0) so nothing depends on a fixed28
// port or external network. Output is only booleans + fixed labels, so it is29
// fully deterministic and asserted byte-for-byte. The harness runs the program30
// under `timeout` so a regression that blocks fails fast instead of hanging.32
#include "e2e_harness.hpp"35
TEST(StdlibE2E, Socket) {36
e2e::expect_e2e("socket_sys", R"PURR(import io37
import socket39
# ---- low-level BSD path: socket/set_reuseaddr/bind/listen/local_port ----40
let srv = socket.socket()41
let reuse = socket.set_reuseaddr(srv)42
let bound = socket.bind(srv, "127.0.0.1", 0)43
let lstn = socket.listen(srv, 8)44
let port = socket.local_port(srv)46
# client socket, connect BEFORE accept (kernel queues the loopback handshake)47
let cli = socket.socket()48
let conn = socket.connect(cli, "127.0.0.1", port)49
let peer = socket.accept(srv)51
# ---- per-connection I/O: send + sendall + recv ----52
let s1 = socket.send(cli, "AB")53
let got1 = socket.recv(peer, 16)54
let s2 = socket.sendall(peer, "PONG")55
let got2 = socket.recv(cli, 16)57
# ---- high-level convenience path: tcp_listen / tcp_connect ----58
let hl_srv = socket.tcp_listen("127.0.0.1", 0, 8)59
let hl_port = socket.local_port(hl_srv)60
let hl_cli = socket.tcp_connect("127.0.0.1", hl_port)61
let hl_peer = socket.accept(hl_srv)62
let hl_s = socket.sendall(hl_cli, "hi")63
let hl_got = socket.recv(hl_peer, 16)65
# ---- deliberate failure + last_error ----66
let fail = socket.connect(-1, "127.0.0.1", 1)67
let err = socket.last_error()69
# ---- verdicts (deterministic) ----70
io.print("socket_ok", srv >= 0)71
io.print("reuse_ok", reuse == 0)72
io.print("bind_ok", bound == 0)73
io.print("listen_ok", lstn == 0)74
io.print("port_ok", port > 0)75
io.print("connect_ok", conn == 0)76
io.print("accept_ok", peer >= 0)77
io.print("send_ok", s1 == 2)78
io.print("recv1_ok", got1 == "AB")79
io.print("sendall_ok", s2 == 0)80
io.print("recv2_ok", got2 == "PONG")81
io.print("tcp_listen_ok", hl_srv >= 0)82
io.print("tcp_connect_ok", hl_cli >= 0)83
io.print("hl_roundtrip_ok", hl_got == "hi")84
io.print("fail_ok", fail < 0)85
io.print("last_error_ok", err != "")87
let c1 = socket.close(peer)88
let c2 = socket.close(cli)89
let c3 = socket.close(srv)90
socket.close(hl_peer)91
socket.close(hl_cli)92
socket.close(hl_srv)93
io.print("close_ok", c1 == 0, c2 == 0, c3 == 0)94
)PURR",95
"socket_ok True\n"96
"reuse_ok True\n"97
"bind_ok True\n"98
"listen_ok True\n"99
"port_ok True\n"100
"connect_ok True\n"101
"accept_ok True\n"102
"send_ok True\n"103
"recv1_ok True\n"104
"sendall_ok True\n"105
"recv2_ok True\n"106
"tcp_listen_ok True\n"107
"tcp_connect_ok True\n"108
"hl_roundtrip_ok True\n"109
"fail_ok True\n"110
"last_error_ok True\n"111
"close_ok True True True\n");112
}