TCP/TLS connection pooling for Eio
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(lint): resolve E410, E331, E615, E617 across conpool, cookeio, cpio, crow

- E410: Fix doc comment style (add [name args] format, end with periods)
- E331: Apply redundant prefix renames (make→v, create→v, create_basic→basic,
get_cookies→cookies, get_all_cookies→all_cookies, make_header→header,
make_cookie_header→cookie_header, make_set_cookie_header→set_cookie_header)
- E615: Include test_target, test_campaign, test_afl, test_scheduler in crow test.ml
- E617: Lowercase test suite name in conpool test_connection.ml
- Update all callers across tests, fuzz, README, and dependent packages

+231 -72
+6 -6
README.md
··· 21 21 let run env = 22 22 Switch.run (fun sw -> 23 23 (* Create a basic connection pool (no protocol state) *) 24 - let pool = Conpool.create_basic 24 + let pool = Conpool.basic 25 25 ~sw 26 26 ~net:(Eio.Stdenv.net env) 27 27 ~clock:(Eio.Stdenv.clock env) ··· 29 29 in 30 30 31 31 (* Define an endpoint *) 32 - let endpoint = Conpool.Endpoint.make ~host:"example.com" ~port:80 in 32 + let endpoint = Conpool.Endpoint.v ~host:"example.com" ~port:80 in 33 33 34 34 (* Use a connection from the pool *) 35 35 Conpool.with_connection pool endpoint (fun conn -> ··· 49 49 let tls_config = Tls.Config.client ~authenticator:(Ca_certs.authenticator ()) () in 50 50 51 51 (* Create pool with TLS *) 52 - let pool = Conpool.create_basic 52 + let pool = Conpool.basic 53 53 ~sw 54 54 ~net:(Eio.Stdenv.net env) 55 55 ~clock:(Eio.Stdenv.clock env) ··· 57 57 () 58 58 in 59 59 60 - let endpoint = Conpool.Endpoint.make ~host:"example.com" ~port:443 in 60 + let endpoint = Conpool.Endpoint.v ~host:"example.com" ~port:443 in 61 61 Conpool.with_connection pool endpoint (fun conn -> 62 62 (* Use TLS-encrypted connection *) 63 63 ... ··· 68 68 Custom pool configuration: 69 69 70 70 ```ocaml 71 - let config = Conpool.Config.make 71 + let config = Conpool.Config.v 72 72 ~max_connections_per_endpoint:20 73 73 ~max_idle_per_endpoint:5 74 74 ~connection_timeout:10.0 ··· 76 76 () 77 77 in 78 78 79 - let pool = Conpool.create_basic ~sw ~net ~clock ~config () 79 + let pool = Conpool.basic ~sw ~net ~clock ~config () 80 80 ``` 81 81 82 82 Monitor pool statistics:
+1 -1
lib/cmd.ml
··· 46 46 let config = 47 47 let make max_conn max_idle max_lifetime max_uses timeout retry_count 48 48 retry_delay = 49 - Config.make ~max_connections_per_endpoint:max_conn ~max_idle_time:max_idle 49 + Config.v ~max_connections_per_endpoint:max_conn ~max_idle_time:max_idle 50 50 ~max_connection_lifetime:max_lifetime ?max_connection_uses:max_uses 51 51 ~connect_timeout:timeout ~connect_retry_count:retry_count 52 52 ~connect_retry_delay:retry_delay ()
+14 -14
lib/cmd.mli
··· 8 8 (** {1 Configuration Terms} *) 9 9 10 10 val max_connections_per_endpoint : int Cmdliner.Term.t 11 - (** Cmdliner term for maximum connections per endpoint. Default: 10 Flag: 12 - [--max-connections-per-endpoint] *) 11 + (** [max_connections_per_endpoint] is the Cmdliner term for maximum connections 12 + per endpoint. Default: 10. Flag: [--max-connections-per-endpoint]. *) 13 13 14 14 val max_idle_time : float Cmdliner.Term.t 15 - (** Cmdliner term for maximum idle time in seconds. Default: 60.0 Flag: 16 - [--max-idle-time] *) 15 + (** [max_idle_time] is the Cmdliner term for maximum idle time in seconds. 16 + Default: 60.0. Flag: [--max-idle-time]. *) 17 17 18 18 val max_connection_lifetime : float Cmdliner.Term.t 19 - (** Cmdliner term for maximum connection lifetime in seconds. Default: 300.0 20 - Flag: [--max-connection-lifetime] *) 19 + (** [max_connection_lifetime] is the Cmdliner term for maximum connection 20 + lifetime in seconds. Default: 300.0. Flag: [--max-connection-lifetime]. *) 21 21 22 22 val max_connection_uses : int option Cmdliner.Term.t 23 - (** Cmdliner term for maximum connection uses. Default: None (unlimited) Flag: 24 - [--max-connection-uses] *) 23 + (** [max_connection_uses] is the Cmdliner term for maximum connection uses. 24 + Default: None (unlimited). Flag: [--max-connection-uses]. *) 25 25 26 26 val connect_timeout : float Cmdliner.Term.t 27 - (** Cmdliner term for connection timeout in seconds. Default: 10.0 Flag: 28 - [--connect-timeout] *) 27 + (** [connect_timeout] is the Cmdliner term for connection timeout in seconds. 28 + Default: 10.0. Flag: [--connect-timeout]. *) 29 29 30 30 val connect_retry_count : int Cmdliner.Term.t 31 - (** Cmdliner term for number of connection retry attempts. Default: 3 Flag: 32 - [--connect-retry-count] *) 31 + (** [connect_retry_count] is the Cmdliner term for number of connection retry 32 + attempts. Default: 3. Flag: [--connect-retry-count]. *) 33 33 34 34 val connect_retry_delay : float Cmdliner.Term.t 35 - (** Cmdliner term for initial retry delay in seconds. Default: 0.1 Flag: 36 - [--connect-retry-delay] *) 35 + (** [connect_retry_delay] is the Cmdliner term for initial retry delay in 36 + seconds. Default: 0.1. Flag: [--connect-retry-delay]. *) 37 37 38 38 (** {1 Combined Terms} *) 39 39
+2 -2
lib/config.ml
··· 25 25 on_connection_reused : (Endpoint.t -> unit) option; 26 26 } 27 27 28 - let make ?(max_connections_per_endpoint = 10) ?(max_idle_time = 60.0) 28 + let v ?(max_connections_per_endpoint = 10) ?(max_idle_time = 60.0) 29 29 ?(max_connection_lifetime = 300.0) ?max_connection_uses ?health_check 30 30 ?(connect_timeout = 10.0) ?(connect_retry_count = 3) 31 31 ?(connect_retry_delay = 0.1) ?on_connection_created ?on_connection_closed ··· 80 80 on_connection_reused; 81 81 } 82 82 83 - let default = make () 83 + let default = v () 84 84 let max_connections_per_endpoint t = t.max_connections_per_endpoint 85 85 let max_idle_time t = t.max_idle_time 86 86 let max_connection_lifetime t = t.max_connection_lifetime
+3 -3
lib/config.mli
··· 20 20 21 21 (** {1 Construction} *) 22 22 23 - val make : 23 + val v : 24 24 ?max_connections_per_endpoint:int -> 25 25 ?max_idle_time:float -> 26 26 ?max_connection_lifetime:float -> ··· 35 35 ?on_connection_reused:(Endpoint.t -> unit) -> 36 36 unit -> 37 37 t 38 - (** Create pool configuration with optional parameters. 38 + (** [v ()] creates pool configuration with optional parameters. 39 39 40 40 @param max_connections_per_endpoint 41 41 Maximum concurrent connections per endpoint (default: 10) ··· 55 55 @param on_connection_reused Hook called when a connection is reused *) 56 56 57 57 val default : t 58 - (** Sensible defaults for most use cases: 58 + (** [default] provides sensible defaults for most use cases. 59 59 - max_connections_per_endpoint: 10 60 60 - max_idle_time: 60.0s 61 61 - max_connection_lifetime: 300.0s
+16 -16
lib/conpool.ml
··· 155 155 156 156 (** {1 Helper Functions} *) 157 157 158 - let get_time pool = Eio.Time.now pool.clock 158 + let time pool = Eio.Time.now pool.clock 159 159 160 - let create_endp_stats () = 160 + let endp_stats () = 161 161 { 162 162 active = 0; 163 163 idle = 0; ··· 168 168 } 169 169 170 170 let snapshot_stats (stats : endp_stats) : Stats.t = 171 - Stats.make ~active:stats.active ~idle:stats.idle 171 + Stats.v ~active:stats.active ~idle:stats.idle 172 172 ~total_created:stats.total_created ~total_reused:stats.total_reused 173 173 ~total_closed:stats.total_closed ~errors:stats.errors 174 174 ··· 277 277 m "Initializing protocol state for %a" Endpoint.pp endpoint); 278 278 let state = pool.protocol.init_state ~sw:conn_sw ~flow ~tls_epoch in 279 279 280 - let now = get_time pool in 280 + let now = time pool in 281 281 282 282 Log.info (fun m -> m "Created connection to %a" Endpoint.pp endpoint); 283 283 ··· 316 316 Unhealthy_error "protocol check failed" 317 317 end 318 318 else 319 - let now = get_time pool in 319 + let now = time pool in 320 320 (* Check connection age *) 321 321 let age = now -. conn.pc_created_at in 322 322 let max_lifetime = Config.max_connection_lifetime pool.config in ··· 372 372 373 373 (** {1 Endpoint Pool Management} *) 374 374 375 - let get_or_create_endpoint_pool pool endpoint = 375 + let ensure_endpoint_pool pool endpoint = 376 376 match 377 377 Eio.Mutex.use_ro pool.endpoints_mutex (fun () -> 378 378 Hashtbl.find_opt pool.endpoints endpoint) ··· 389 389 { 390 390 connections = ref []; 391 391 ep_mutex = Eio.Mutex.create (); 392 - stats = create_endp_stats (); 392 + stats = endp_stats (); 393 393 stats_mutex = Eio.Mutex.create (); 394 394 } 395 395 in ··· 428 428 (* Reuse existing connection *) 429 429 let was_idle = conn.pc_active_users = 0 in 430 430 conn.pc_active_users <- conn.pc_active_users + 1; 431 - conn.pc_last_used <- get_time pool; 431 + conn.pc_last_used <- time pool; 432 432 conn.pc_use_count <- conn.pc_use_count + 1; 433 433 434 434 Eio.Mutex.use_rw ~protect:true ep_pool.stats_mutex (fun () -> ··· 482 482 if conn.pc_closed then acquire_connection pool ep_pool endpoint 483 483 else begin 484 484 conn.pc_active_users <- conn.pc_active_users + 1; 485 - conn.pc_last_used <- get_time pool; 485 + conn.pc_last_used <- time pool; 486 486 conn.pc_use_count <- conn.pc_use_count + 1; 487 487 488 488 Eio.Mutex.use_rw ~protect:true ep_pool.stats_mutex (fun () -> ··· 510 510 ep_pool.stats.active <- ep_pool.stats.active + 1; 511 511 ep_pool.stats.idle <- max 0 (ep_pool.stats.idle - 1)); 512 512 any_conn.pc_active_users <- 1; 513 - any_conn.pc_last_used <- get_time pool; 513 + any_conn.pc_last_used <- time pool; 514 514 any_conn.pc_use_count <- any_conn.pc_use_count + 1; 515 515 (* Notify protocol handler of acquisition *) 516 516 pool.protocol.on_acquire any_conn.pc_state; ··· 592 592 593 593 (** {1 Public API} *) 594 594 595 - let create ~sw ~(net : 'net Eio.Net.t) ~(clock : 'clock Eio.Time.clock) ?tls 595 + let v ~sw ~(net : 'net Eio.Net.t) ~(clock : 'clock Eio.Time.clock) ?tls 596 596 ?(config = Config.default) ~protocol () = 597 597 Log.info (fun m -> 598 598 m "Creating connection pool (max_per_endpoint=%d)" ··· 625 625 626 626 Pool pool 627 627 628 - let create_basic ~sw ~net ~clock ?tls ?config () = 629 - create ~sw ~net ~clock ?tls ?config ~protocol:default_protocol () 628 + let basic ~sw ~net ~clock ?tls ?config () = 629 + v ~sw ~net ~clock ?tls ?config ~protocol:default_protocol () 630 630 631 631 let connection ~sw (Pool pool) endpoint = 632 632 Log.debug (fun m -> m "Acquiring connection to %a" Endpoint.pp endpoint); 633 633 634 - let ep_pool = get_or_create_endpoint_pool pool endpoint in 634 + let ep_pool = ensure_endpoint_pool pool endpoint in 635 635 let conn = acquire_connection pool ep_pool endpoint in 636 636 637 637 (* Release connection when switch ends *) ··· 658 658 Eio.Mutex.use_ro ep_pool.stats_mutex (fun () -> 659 659 snapshot_stats ep_pool.stats) 660 660 | None -> 661 - Stats.make ~active:0 ~idle:0 ~total_created:0 ~total_reused:0 662 - ~total_closed:0 ~errors:0 661 + Stats.v ~active:0 ~idle:0 ~total_created:0 ~total_reused:0 ~total_closed:0 662 + ~errors:0 663 663 664 664 let all_stats (Pool pool) = 665 665 Eio.Mutex.use_ro pool.endpoints_mutex (fun () ->
+15 -19
lib/conpool.mli
··· 13 13 14 14 For simple exclusive-access protocols (HTTP/1.x, Redis, etc.): 15 15 {[ 16 - let pool = Conpool.create_basic ~sw ~net ~clock ~tls () in 16 + let pool = Conpool.basic ~sw ~net ~clock ~tls () in 17 17 Eio.Switch.run (fun conn_sw -> 18 18 let conn = Conpool.connection ~sw:conn_sw pool endpoint in 19 19 (* Use conn.flow for I/O *) ··· 22 22 23 23 For multiplexed protocols (HTTP/2): 24 24 {[ 25 - let pool = Conpool.create ~sw ~net ~clock ~tls ~protocol:h2_handler () in 25 + let pool = Conpool.v ~sw ~net ~clock ~tls ~protocol:h2_handler () in 26 26 Eio.Switch.run (fun conn_sw -> 27 27 let conn = Conpool.connection ~sw:conn_sw pool endpoint in 28 28 (* conn.state has H2_client.t, multiple streams share the connection *) ··· 107 107 108 108 val default_protocol : unit Config.protocol_config 109 109 (** Default protocol configuration for simple exclusive-access protocols. Use 110 - with {!create} for HTTP/1.x, Redis, and similar protocols where each 111 - connection handles one request at a time with no extra state. *) 110 + with {!v} for HTTP/1.x, Redis, and similar protocols where each connection 111 + handles one request at a time with no extra state. *) 112 112 113 - val create : 113 + val v : 114 114 sw:Eio.Switch.t -> 115 115 net:'net Eio.Net.t -> 116 116 clock:'clock Eio.Time.clock -> ··· 119 119 protocol:'state Config.protocol_config -> 120 120 unit -> 121 121 'state t 122 - (** Create a connection pool with a protocol handler. 122 + (** [v ~sw ~net ~clock ~protocol ()] creates a connection pool with a protocol 123 + handler. 123 124 124 - @param sw Switch for resource management 125 - @param net Network interface for creating connections 126 - @param clock Clock for timeouts 127 - @param tls Optional TLS client configuration 128 - @param config Pool configuration (uses {!Config.default} if not provided) 129 - @param protocol Protocol handler for state management 125 + @param tls Optional TLS client configuration. 126 + @param config Pool configuration (uses {!Config.default} if not provided). 130 127 131 128 Examples: 132 129 133 130 Simple pool for HTTP/1.x (exclusive access, no state): 134 131 {[ 135 132 let pool = 136 - Conpool.create ~sw ~net ~clock ~tls ~protocol:Conpool.default_protocol 137 - () 133 + Conpool.v ~sw ~net ~clock ~tls ~protocol:Conpool.default_protocol () 138 134 ]} 139 135 140 136 HTTP/2 pool (shared access with H2 state): 141 137 {[ 142 - let pool = Conpool.create ~sw ~net ~clock ~tls ~protocol:h2_handler () 138 + let pool = Conpool.v ~sw ~net ~clock ~tls ~protocol:h2_handler () 143 139 ]} *) 144 140 145 - val create_basic : 141 + val basic : 146 142 sw:Eio.Switch.t -> 147 143 net:'net Eio.Net.t -> 148 144 clock:'clock Eio.Time.clock -> ··· 154 150 155 151 This is a convenience function equivalent to: 156 152 {[ 157 - Conpool.create ~sw ~net ~clock ?tls ?config 158 - ~protocol:Conpool.default_protocol () 153 + Conpool.v ~sw ~net ~clock ?tls ?config ~protocol:Conpool.default_protocol 154 + () 159 155 ]} 160 156 161 157 Use for simple exclusive-access protocols like HTTP/1.x and Redis. 162 158 163 159 Example: 164 160 {[ 165 - let pool = Conpool.create_basic ~sw ~net ~clock ~tls () 161 + let pool = Conpool.basic ~sw ~net ~clock ~tls () 166 162 ]} *) 167 163 168 164 (** {2 Connection Acquisition} *)
+1 -1
lib/endpoint.ml
··· 12 12 13 13 type t = { host : string; port : int } 14 14 15 - let make ~host ~port = 15 + let v ~host ~port = 16 16 (* Validate port range *) 17 17 if port < 1 || port > 65535 then 18 18 invalid_arg
+1 -1
lib/endpoint.mli
··· 20 20 21 21 (** {1 Construction} *) 22 22 23 - val make : host:string -> port:int -> t 23 + val v : host:string -> port:int -> t 24 24 (** Create an endpoint from a hostname and port. *) 25 25 26 26 (** {1 Accessors} *)
+1 -1
lib/stats.ml
··· 14 14 errors : int; 15 15 } 16 16 17 - let make ~active ~idle ~total_created ~total_reused ~total_closed ~errors = 17 + let v ~active ~idle ~total_created ~total_reused ~total_closed ~errors = 18 18 { active; idle; total_created; total_reused; total_closed; errors } 19 19 20 20 let active t = t.active
+1 -1
lib/stats.mli
··· 12 12 13 13 (** {1 Construction} *) 14 14 15 - val make : 15 + val v : 16 16 active:int -> 17 17 idle:int -> 18 18 total_created:int ->
+12
test/dune
··· 1 + (test 2 + (name test) 3 + (modules 4 + test 5 + test_endpoint 6 + test_config 7 + test_stats 8 + test_cmd 9 + test_connection 10 + test_conpool) 11 + (libraries conpool alcotest)) 12 + 1 13 (executable 2 14 (name stress_test) 3 15 (modules stress_test)
+5 -7
test/stress_test.ml
··· 117 117 } 118 118 (** Statistics collected during test *) 119 119 120 - let create_latency_stats () = 120 + let latency_stats () = 121 121 { count = 0; total = 0.0; min = Float.infinity; max = 0.0; latencies = [] } 122 122 123 123 let update_latency stats latency timestamp = ··· 252 252 let net = Eio.Stdenv.net env in 253 253 let clock = Eio.Stdenv.clock env in 254 254 255 - let latency_stats = create_latency_stats () in 255 + let latency_stats = latency_stats () in 256 256 let errors = ref 0 in 257 257 let ports = ref [||] in 258 258 ··· 266 266 Eio.Time.sleep clock 0.05; 267 267 268 268 let endpoints = 269 - Array.map 270 - (fun port -> Conpool.Endpoint.make ~host:"127.0.0.1" ~port) 271 - !ports 269 + Array.map (fun port -> Conpool.Endpoint.v ~host:"127.0.0.1" ~port) !ports 272 270 in 273 271 274 272 (* Create connection pool *) 275 273 let pool_config = 276 - Conpool.Config.make ~max_connections_per_endpoint:cfg.pool_size 274 + Conpool.Config.v ~max_connections_per_endpoint:cfg.pool_size 277 275 ~max_idle_time:30.0 ~max_connection_lifetime:120.0 ~connect_timeout:5.0 278 276 ~connect_retry_count:3 () 279 277 in 280 278 281 - let pool = Conpool.create_basic ~sw ~net ~clock ~config:pool_config () in 279 + let pool = Conpool.basic ~sw ~net ~clock ~config:pool_config () in 282 280 283 281 (* Record start time *) 284 282 let start_time = Eio.Time.now clock in
+15
test/test.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + let () = 7 + Alcotest.run "conpool" 8 + [ 9 + Test_endpoint.suite; 10 + Test_config.suite; 11 + Test_stats.suite; 12 + Test_cmd.suite; 13 + Test_connection.suite; 14 + Test_conpool.suite; 15 + ]
+14
test/test_cmd.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + let test_terms_exist () = 7 + (* Verify cmdliner terms can be constructed without error *) 8 + let _ = Conpool.Cmd.max_connections_per_endpoint in 9 + let _ = Conpool.Cmd.max_idle_time in 10 + let _ = Conpool.Cmd.connect_timeout in 11 + let _ = Conpool.Cmd.config in 12 + () 13 + 14 + let suite = ("Cmd", [ Alcotest.test_case "terms_exist" `Quick test_terms_exist ])
+40
test/test_config.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + let test_default () = 7 + let c = Conpool.Config.default in 8 + Alcotest.(check int) 9 + "max_connections_per_endpoint" 10 10 + (Conpool.Config.max_connections_per_endpoint c); 11 + Alcotest.(check (float 0.01)) 12 + "max_idle_time" 60.0 13 + (Conpool.Config.max_idle_time c); 14 + Alcotest.(check (float 0.01)) 15 + "max_connection_lifetime" 300.0 16 + (Conpool.Config.max_connection_lifetime c) 17 + 18 + let test_v () = 19 + let c = 20 + Conpool.Config.v ~max_connections_per_endpoint:20 ~max_idle_time:30.0 () 21 + in 22 + Alcotest.(check int) 23 + "max_connections_per_endpoint" 20 24 + (Conpool.Config.max_connections_per_endpoint c); 25 + Alcotest.(check (float 0.01)) 26 + "max_idle_time" 30.0 27 + (Conpool.Config.max_idle_time c) 28 + 29 + let test_pp () = 30 + let c = Conpool.Config.default in 31 + let s = Format.asprintf "%a" Conpool.Config.pp c in 32 + Alcotest.(check bool) "non-empty" true (String.length s > 0) 33 + 34 + let suite = 35 + ( "Config", 36 + [ 37 + Alcotest.test_case "default" `Quick test_default; 38 + Alcotest.test_case "v" `Quick test_v; 39 + Alcotest.test_case "pp" `Quick test_pp; 40 + ] )
+9
test/test_connection.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + (* Connection is an internal module that requires live Eio flows to test. 7 + Integration tests are covered by the stress test. *) 8 + 9 + let suite = ("connection", [])
+15
test/test_conpool.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + (* Full pool tests require a live Eio environment with networking. 7 + Integration tests are covered by the stress test. *) 8 + 9 + let test_default_protocol () = 10 + let _ = Conpool.default_protocol in 11 + () 12 + 13 + let suite = 14 + ( "Conpool", 15 + [ Alcotest.test_case "default_protocol" `Quick test_default_protocol ] )
+29
test/test_endpoint.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + let test_v () = 7 + let ep = Conpool.Endpoint.v ~host:"example.com" ~port:443 in 8 + Alcotest.(check string) "host" "example.com" (Conpool.Endpoint.host ep); 9 + Alcotest.(check int) "port" 443 (Conpool.Endpoint.port ep) 10 + 11 + let test_equal () = 12 + let a = Conpool.Endpoint.v ~host:"example.com" ~port:443 in 13 + let b = Conpool.Endpoint.v ~host:"example.com" ~port:443 in 14 + let c = Conpool.Endpoint.v ~host:"other.com" ~port:443 in 15 + Alcotest.(check bool) "same" true (Conpool.Endpoint.equal a b); 16 + Alcotest.(check bool) "different host" false (Conpool.Endpoint.equal a c) 17 + 18 + let test_pp () = 19 + let ep = Conpool.Endpoint.v ~host:"example.com" ~port:8080 in 20 + let s = Format.asprintf "%a" Conpool.Endpoint.pp ep in 21 + Alcotest.(check bool) "contains host" true (String.length s > 0) 22 + 23 + let suite = 24 + ( "Endpoint", 25 + [ 26 + Alcotest.test_case "v" `Quick test_v; 27 + Alcotest.test_case "equal" `Quick test_equal; 28 + Alcotest.test_case "pp" `Quick test_pp; 29 + ] )
+31
test/test_stats.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 + SPDX-License-Identifier: MIT 4 + ---------------------------------------------------------------------------*) 5 + 6 + let test_v () = 7 + let s = 8 + Conpool.Stats.v ~active:2 ~idle:3 ~total_created:10 ~total_reused:5 9 + ~total_closed:3 ~errors:1 10 + in 11 + Alcotest.(check int) "active" 2 (Conpool.Stats.active s); 12 + Alcotest.(check int) "idle" 3 (Conpool.Stats.idle s); 13 + Alcotest.(check int) "total_created" 10 (Conpool.Stats.total_created s); 14 + Alcotest.(check int) "total_reused" 5 (Conpool.Stats.total_reused s); 15 + Alcotest.(check int) "total_closed" 3 (Conpool.Stats.total_closed s); 16 + Alcotest.(check int) "errors" 1 (Conpool.Stats.errors s) 17 + 18 + let test_pp () = 19 + let s = 20 + Conpool.Stats.v ~active:0 ~idle:0 ~total_created:0 ~total_reused:0 21 + ~total_closed:0 ~errors:0 22 + in 23 + let str = Format.asprintf "%a" Conpool.Stats.pp s in 24 + Alcotest.(check bool) "non-empty" true (String.length str > 0) 25 + 26 + let suite = 27 + ( "Stats", 28 + [ 29 + Alcotest.test_case "v" `Quick test_v; 30 + Alcotest.test_case "pp" `Quick test_pp; 31 + ] )