1
+ open Eio.Std
2
+
3
+ let read_all flow =
4
+ let b = Buffer. create 100 in
5
+ Eio.Flow. copy flow (Eio.Flow. buffer_sink b);
6
+ Buffer. contents b
7
+
8
+ let run_client ~sw ~net ~addr =
9
+ traceln " Connecting to server..." ;
10
+ let flow = Eio.Net. connect ~sw net addr in
11
+ Eio. traceln " connected" ;
12
+ Eio.Flow. copy_string " Hello from client" flow;
13
+ Eio.Flow. shutdown flow `Send ;
14
+ let msg = read_all flow in
15
+ msg
16
+
17
+ let run_server ~sw msg socket =
18
+ Eio.Net. accept_fork socket ~sw (fun flow _addr ->
19
+ traceln " Server accepted connection from client" ;
20
+ Fun. protect (fun () ->
21
+ let msg = read_all flow in
22
+ traceln " Server received: %S" msg
23
+ ) ~finally: (fun () -> Eio.Flow. copy_string msg flow)
24
+ )
25
+ ~on_error: (function
26
+ | ex -> traceln " Error handling connection: %s" (Printexc. to_string ex)
27
+ )
28
+
29
+ let test_client_server env addr () =
30
+ Eio.Switch. run @@ fun sw ->
31
+ let server = Eio.Net. listen env#net ~sw ~reuse_addr: true ~backlog: 5 addr in
32
+ let msg = " From the server" in
33
+ Fiber. both
34
+ (fun () -> run_server ~sw msg server)
35
+ (fun () ->
36
+ let client_msg = run_client ~sw ~net: env#net ~addr in
37
+ Alcotest. (check string ) " same message" msg client_msg
38
+ )
39
+
40
+ let run_dgram addr ~net sw msg =
41
+ let e1 = `Udp (addr, 8081 ) in
42
+ let e2 = `Udp (addr, 8082 ) in
43
+ let listening_socket = Eio.Net. datagram_socket ~sw net e2 in
44
+ Fiber. both
45
+ (fun () ->
46
+ let buf = Cstruct. create 20 in
47
+ traceln " Waiting to receive data on %a" Eio.Net.Sockaddr. pp e2;
48
+ let addr, recv = Eio.Net. recv listening_socket buf in
49
+ traceln " Received message from %a"
50
+ Eio.Net.Sockaddr. pp addr;
51
+ Alcotest. (check string ) " same udp msg" msg (Cstruct. (to_string (sub buf 0 recv)))
52
+ )
53
+ (fun () ->
54
+ let e = Eio.Net. datagram_socket ~sw net e1 in
55
+ traceln " Sending data from %a to %a" Eio.Net.Sockaddr. pp e1 Eio.Net.Sockaddr. pp e2;
56
+ Eio.Net. send e e2 (Cstruct. of_string msg))
57
+
58
+ let test_udp env addr () =
59
+ Eio.Switch. run @@ fun sw ->
60
+ run_dgram addr ~net: env#net sw " UDP on Windows"
61
+
62
+ let test_fd env addr () =
63
+ Eio.Switch. run @@ fun sw ->
64
+ let addr = `Tcp (addr, 8081 ) in
65
+ let server = Eio.Net. listen env#net ~sw ~reuse_addr: true ~backlog: 5 addr in
66
+ Alcotest. (check bool ) " Listening socket has Unix FD" (Eio_unix.Resource. fd_opt server <> None ) true ;
67
+ let have_client, have_server =
68
+ Fiber. pair
69
+ (fun () ->
70
+ let flow = Eio.Net. connect ~sw env#net addr in
71
+ (Eio_unix.Resource. fd_opt flow <> None )
72
+ )
73
+ (fun () ->
74
+ let flow, _addr = Eio.Net. accept ~sw server in
75
+ (Eio_unix.Resource. fd_opt flow <> None )
76
+ )
77
+ in
78
+ Alcotest. (check bool ) " Client-side socket has Unix FD" have_client true ;
79
+ Alcotest. (check bool ) " Server-side socket has Unix FD" have_server true
80
+
81
+ let test_wrap_socket pipe_or_socketpair () =
82
+ Switch. run @@ fun sw ->
83
+ let r, w =
84
+ match pipe_or_socketpair with
85
+ | `Pipe -> Unix. pipe ()
86
+ | `Socketpair -> Unix. socketpair Unix. PF_UNIX Unix. SOCK_STREAM 0
87
+ in
88
+ let source = (Eio_unix. import_socket_stream ~sw ~close_unix: true r :> Eio.Flow. source) in
89
+ let sink = (Eio_unix. import_socket_stream ~sw ~close_unix: true w :> Eio.Flow. sink) in
90
+ let msg = " Hello" in
91
+ Fiber. both
92
+ (fun () -> Eio.Flow. copy_string (msg ^ " \n " ) sink)
93
+ (fun () ->
94
+ let b = Eio.Buf_read. of_flow source ~max_size: 1000 in
95
+ Alcotest. (check string ) " same message" (Eio.Buf_read. line b) msg
96
+ )
97
+
98
+ let test_eio_socketpair () =
99
+ Switch. run @@ fun sw ->
100
+ let a, b = Eio_unix. socketpair ~sw () in
101
+ ignore (Eio_unix.Resource. fd a : Eio_unix.Fd.t );
102
+ ignore (Eio_unix.Resource. fd b : Eio_unix.Fd.t );
103
+ Eio.Flow. copy_string " foo" a;
104
+ Eio.Flow. close a;
105
+ let msg = Eio.Buf_read. of_flow b ~max_size: 10 |> Eio.Buf_read. take_all in
106
+ Alcotest. (check string ) " same messagw" " foo" msg
107
+
108
+ let tests env = [
109
+ " tcp-ip4" , `Quick , test_client_server env (`Tcp (Eio.Net.Ipaddr.V4. loopback, 8081 ));
110
+ " tcp-ip6" , `Quick , test_client_server env (`Tcp (Eio.Net.Ipaddr.V6. loopback, 8081 ));
111
+ " unix" , `Quick , test_client_server env (`Unix " eio-test.sock" );
112
+ " udp-ip4" , `Quick , test_udp env Eio.Net.Ipaddr.V4. loopback;
113
+ " udp-ip6" , `Quick , test_udp env Eio.Net.Ipaddr.V6. loopback;
114
+ " fds" , `Quick , test_fd env Eio.Net.Ipaddr.V4. loopback;
115
+ " wrap-pipe" , `Quick , test_wrap_socket `Pipe ;
116
+ " wrap-socketpair" , `Quick , test_wrap_socket `Socketpair ;
117
+ " eio-socketpair" , `Quick , test_eio_socketpair
118
+ ]
0 commit comments