Skip to content

Commit b8b5fd0

Browse files
authored
Merge pull request #5838 from edwintorok/private/edvint/fix-timeouts
Fix @StressTest failure
2 parents 80a66c8 + c70d3de commit b8b5fd0

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

ocaml/libs/http-lib/bufio_test.ml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,30 @@ let test_buf_io =
2121
let gen = Gen.tup2 Generate.t timeouts
2222
and print = Print.tup2 Generate.print print_timeout in
2323
Test.make ~name:__FUNCTION__ ~print gen @@ fun (behaviour, timeout) ->
24+
let every_bytes =
25+
Int.min
26+
(Option.map Observations.Delay.every_bytes behaviour.delay_read
27+
|> Option.value ~default:Int.max_int
28+
)
29+
(Option.map Observations.Delay.every_bytes behaviour.delay_write
30+
|> Option.value ~default:Int.max_int
31+
)
32+
in
33+
let operations = Int.max 1 (behaviour.size / every_bytes) in
34+
(* Buf_io uses per-operation timeouts, not a timeout for the whole function,
35+
so if we want a timeout of 0.1s and we insert some delays every 1 byte,
36+
for 64KiB bytes in total, then we need 0.1/65536 timeout for individual operations.
37+
38+
timeout_span remains the span for the entire function,
39+
and timeout the per operation timeout that we'll pass to the function under test.
40+
*)
2441
let timeout_span = Mtime.Span.of_float_ns (timeout *. 1e9) |> Option.get in
42+
let timeout = timeout /. float operations in
43+
let timeout_operation_span =
44+
Mtime.Span.of_float_ns (timeout *. 1e9) |> Option.get
45+
in
46+
(* timeout < 1us would get truncated to 0 *)
47+
QCheck2.assume (timeout > 1e-6) ;
2548
(* Format.eprintf "Testing %s@." (print (behaviour, timeout)); *)
2649
if behaviour.kind <> Unix.S_SOCK then
2750
QCheck2.assume_fail () ;
@@ -59,7 +82,7 @@ let test_buf_io =
5982
expect_string ~expected:write.data ~actual
6083
| {write= Some _; _}, Error (`Exn_trap (Buf_io.Timeout, _)) ->
6184
let elapsed = !test_elapsed in
62-
if Mtime.Span.compare elapsed timeout_span < 0 then
85+
if Mtime.Span.compare elapsed timeout_operation_span < 0 then
6386
Test.fail_reportf "Timed out earlier than requested: %a < %a"
6487
Mtime.Span.pp elapsed Mtime.Span.pp timeout_span
6588
| ( {write= Some write; _}

ocaml/libs/xapi-stdext/lib/xapi-fd-test/generate.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@ let delay_of_size total_delay size =
6262
let open Gen in
6363
let* every_bytes = if size = 0 then return 1 else 1 -- size in
6464
let chunks = max 1 (size / every_bytes) in
65-
let duration = total_delay /. float_of_int chunks |> span_of_s in
66-
return @@ Some (Delay.v ~every_bytes ~duration)
65+
let duration = total_delay /. float_of_int chunks in
66+
if duration < 1e-6 then
67+
return None
68+
else
69+
let duration = duration |> span_of_s in
70+
return @@ Some (Delay.v ~every_bytes ~duration)
6771

6872
let t =
6973
let open Gen in

ocaml/libs/xapi-stdext/lib/xapi-fd-test/observations.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ module CancellableSleep = struct
158158
; buf= Bytes.make 1 ' '
159159
}
160160

161-
let set_rcvtimeo sock timeo = setsockopt_float sock Unix.SO_RCVTIMEO timeo
161+
let set_rcvtimeo sock timeo =
162+
if timeo < 1e-6 then Fmt.invalid_arg "timeout too short: %g" timeo ;
163+
setsockopt_float sock Unix.SO_RCVTIMEO timeo
162164

163165
let sleep t dt =
164166
set_rcvtimeo t.wait (Mtime.Span.to_float_ns dt *. 1e-9) ;
@@ -173,6 +175,8 @@ end
173175
module Delay = struct
174176
type t = {duration: Mtime.span; every_bytes: int}
175177

178+
let every_bytes t = t.every_bytes
179+
176180
let pp =
177181
Fmt.(
178182
record ~sep:(any ";")

ocaml/libs/xapi-stdext/lib/xapi-fd-test/observations.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ module Delay : sig
109109
Note that the time taken to send or receive [after_bytes] is not taken into account to guarantee the insertion of the delay.
110110
*)
111111

112+
val every_bytes : t -> int
113+
(** [every_bytes t] is how often delays are inserted *)
114+
112115
val apply_read :
113116
CancellableSleep.t
114117
-> t

0 commit comments

Comments
 (0)