Skip to content

Commit e1dce01

Browse files
committed
stabilize entries_expire in mirage tests
1 parent 1c29921 commit e1dce01

1 file changed

Lines changed: 37 additions & 25 deletions

File tree

test/mirage/tests.ml

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ let get_arp ?backend () =
122122
in
123123
V.connect backend >>= fun netif ->
124124
E.connect netif >>= fun ethif ->
125-
A.connect ~probe_delay:(Duration.of_ms 2) ethif >>= fun arp ->
125+
A.connect ~probe_delay:(Duration.of_ms 1) ethif >>= fun arp ->
126126
Lwt.return { backend; netif; ethif; arp }
127127

128128
(* we almost always want two stacks on the same backend *)
@@ -322,32 +322,44 @@ let os_linux_bsd () =
322322
| Error _ -> false
323323

324324
let entries_expire () =
325-
(* this test fails on windows and macOS for unknown reasons. please, if you
326-
happen to have your hands on such a machine, investigate the issue. *)
327-
if not (os_linux_bsd ()) then
328-
Lwt.return_unit
329-
else
330-
two_arp () >>= fun (listen, speak) ->
331-
A.set_ips listen.arp [ second_ip ] >>= fun () ->
332-
(* here's what we expect listener to emit once its cache entry has expired *)
333-
let expected_arp_query =
334-
Arp_packet.({operation = Request;
335-
source_mac = V.mac listen.netif;
336-
target_mac = Macaddr.broadcast;
337-
source_ip = second_ip; target_ip = first_ip})
325+
two_arp () >>= fun (listen, speak) ->
326+
A.set_ips listen.arp [ second_ip ] >>= fun () ->
327+
(* here's what we expect listener to emit once its cache entry has expired *)
328+
let expected_arp_query =
329+
Arp_packet.({operation = Request;
330+
source_mac = V.mac listen.netif;
331+
target_mac = Macaddr.broadcast;
332+
source_ip = second_ip; target_ip = first_ip})
333+
in
334+
(* Start ARP listener that will stay active throughout the test *)
335+
let listener = start_arp_listener listen () in
336+
Lwt.async (fun () -> V.listen listen.netif ~header_size listener >|= fun _ -> ());
337+
(* Establish cache entry using synchronized query/reply pattern *)
338+
(* Don't set speak's IP to avoid GARP interference *)
339+
let for_listener = arp_reply ~from_netif:speak.netif ~to_netif:listen.netif
340+
~from_ip:first_ip ~to_ip:second_ip in
341+
let establish_entry =
342+
let query = A.query listen.arp first_ip >>= function
343+
| Ok mac when Macaddr.compare mac (V.mac speak.netif) = 0 -> Lwt.return_unit
344+
| Ok mac -> failf "got unexpected MAC %a, expected %a"
345+
Macaddr.pp mac Macaddr.pp (V.mac speak.netif)
346+
| Error e -> failf "query failed: %a" A.pp_error e
338347
in
339-
(* query for IP to accept responses *)
340-
Lwt.async (fun () -> A.query listen.arp first_ip >|= ignore) ;
341-
Lwt.async (fun () -> V.listen listen.netif ~header_size (start_arp_listener listen ()) >|= fun _ -> ());
342-
let test =
343-
Mirage_sleep.ns (Duration.of_ms 10) >>= fun () ->
344-
set_and_check ~listener:listen.arp ~claimant:speak first_ip >>= fun () ->
345-
(* sleep for 5s to make sure we hit `tick` often enough *)
346-
Mirage_sleep.ns (Duration.of_sec 5) >>= fun () ->
347-
(* asking now should generate a query *)
348-
not_in_cache ~listen:speak.netif expected_arp_query listen.arp first_ip
348+
let send_reply =
349+
E.write speak.ethif (V.mac listen.netif) `ARP ~size for_listener >|= function
350+
| Ok _ -> ()
351+
| Error _ -> failf "ethernet write failed"
349352
in
350-
timeout ~time:7000 test
353+
query >>= fun () -> send_reply
354+
in
355+
timeout ~time:1000 establish_entry >>= fun () ->
356+
(* Wait for cache entry to expire. Entry is removed after timeout (800 ticks *
357+
1ms = 1600ms) from initial creation. *)
358+
(* CI for BSD/MacOS has slower ticks, wait longer *)
359+
let delay = if os_linux_bsd () then 5 else 14 in
360+
Mirage_sleep.ns (Duration.of_sec delay) >>= fun () ->
361+
(* Querying now should generate an ARP request since entry should be removed *)
362+
timeout ~time:1000 (not_in_cache ~listen:speak.netif expected_arp_query listen.arp first_ip)
351363

352364
(* RFC isn't strict on how many times to try, so we'll just say any number
353365
greater than 1 is fine *)

0 commit comments

Comments
 (0)