linol/thirdparty/lsp/submodules/lev/lev-fiber/test/sockets.ml

76 lines
2.5 KiB
OCaml

open! Stdune
open Fiber.O
open Lev_fiber
let%expect_test "server & client" =
let path = "levfiber.sock" in
(try Unix.unlink path with Unix.Unix_error _ -> ());
let server_sockaddr =
if Sys.win32 then Unix.ADDR_INET (Unix.inet_addr_loopback, 0)
else Unix.ADDR_UNIX path
in
let domain = Unix.domain_of_sockaddr server_sockaddr in
let socket () =
Lev_fiber.Fd.create
(Unix.socket ~cloexec:true domain Unix.SOCK_STREAM 0)
(`Non_blocking false)
in
let client_sockaddr = Fiber.Ivar.create () in
let run () =
let ready_client = Fiber.Ivar.create () in
let server () =
print_endline "server: starting";
let fd = socket () in
let unix_fd = Lev_fiber.Fd.fd_exn fd in
Unix.setsockopt unix_fd Unix.SO_REUSEADDR true;
let* server = Socket.Server.create fd server_sockaddr ~backlog:10 in
let* () = Fiber.Ivar.fill client_sockaddr (Unix.getsockname unix_fd) in
print_endline "server: created";
let* () = Fiber.Ivar.fill ready_client () in
print_endline "server: serving";
Socket.Server.serve server ~f:(fun session ->
let* i, o = Socket.Server.Session.io session in
print_endline "server: client connected";
let* contents = Io.with_read i ~f:Io.Reader.to_string in
printfn "server: received %S" contents;
let* () =
Io.with_write o ~f:(fun w ->
Io.Writer.add_string w "pong";
Io.Writer.flush w)
in
Io.close o;
Io.close i;
Socket.Server.close server)
in
let client () =
let* () = Fiber.Ivar.read ready_client in
let fd = socket () in
print_endline "client: starting";
let* sockaddr = Fiber.Ivar.read client_sockaddr in
let* () = Socket.connect fd sockaddr in
print_endline "client: successfully connected";
let* i, o = Io.create_rw fd in
let* () =
Io.with_write o ~f:(fun w ->
Io.Writer.add_string w "ping";
Io.Writer.flush w)
in
Unix.shutdown (Lev_fiber.Fd.fd_exn fd) SHUTDOWN_SEND;
let+ result = Io.with_read i ~f:Io.Reader.to_string in
printfn "client: received %S" result;
Io.close o;
Io.close i
in
Fiber.fork_and_join_unit client server
in
Lev_fiber.run run |> Lev_fiber.Error.ok_exn;
[%expect
{|
server: starting
server: created
server: serving
client: starting
client: successfully connected
server: client connected
server: received "ping"
client: received "pong" |}]