Skip to content

Commit 92225f6

Browse files
committed
Add a basic test for the Computation.Tx interface
1 parent e6c5baa commit 92225f6

File tree

1 file changed

+75
-11
lines changed

1 file changed

+75
-11
lines changed

test/test_picos.ml

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,74 @@ let test_computation_basics () =
8585
let _ : int = Computation.await computation in
8686
()
8787

88-
let test_thread_cancelation () =
88+
let test_computation_tx () =
89+
let module Tx = Computation.Tx in
90+
let exit_bt = Exn_bt.get_callstack 0 Exit in
91+
let n_case_1 = ref 0 and n_case_2 = ref 0 in
92+
let n = 1_000 in
93+
let deadline = Unix.gettimeofday () +. 60.0 in
94+
while (!n_case_1 < n || !n_case_2 < n) && Unix.gettimeofday () < deadline do
95+
let a = Computation.create () in
96+
let b = Computation.create () in
97+
let barrier = Atomic.make 2 in
98+
let either which =
99+
if which then begin
100+
finally Domain.join @@ fun () ->
101+
Domain.spawn @@ fun () ->
102+
Atomic.decr barrier;
103+
while Atomic.get barrier <> 0 do
104+
Domain.cpu_relax ()
105+
done;
106+
while
107+
Computation.is_running a
108+
&& not
109+
(let tx = Tx.create () in
110+
Tx.try_return tx a 101 && Tx.try_cancel tx b exit_bt
111+
&& Tx.try_commit tx)
112+
do
113+
Domain.cpu_relax ()
114+
done
115+
end
116+
else begin
117+
finally Domain.join @@ fun () ->
118+
Domain.spawn @@ fun () ->
119+
Atomic.decr barrier;
120+
while Atomic.get barrier <> 0 do
121+
Domain.cpu_relax ()
122+
done;
123+
while
124+
Computation.is_running a
125+
&& not
126+
(let tx = Tx.create () in
127+
not
128+
(Tx.try_return tx b 42 && Tx.try_cancel tx a exit_bt
129+
&& Tx.try_commit tx))
130+
do
131+
Domain.cpu_relax ()
132+
done
133+
end
134+
in
135+
let which = Random.bool () in
136+
let@ _ = either which in
137+
let@ _ = either (not which) in
138+
while Computation.is_running a || Computation.is_running b do
139+
Domain.cpu_relax ()
140+
done;
141+
if
142+
Computation.peek a = Some (Ok 101)
143+
&& Computation.peek b = Some (Error exit_bt)
144+
then incr n_case_1
145+
else if
146+
Computation.peek a = Some (Error exit_bt)
147+
&& Computation.peek b = Some (Ok 42)
148+
then incr n_case_2
149+
else assert false
150+
done;
151+
assert (n <= !n_case_1 && n <= !n_case_2)
152+
153+
let test_cancel () =
89154
Alcotest.check_raises "should be canceled" Exit @@ fun () ->
90-
Test_scheduler.run @@ fun () ->
155+
Test_scheduler.run ~max_domains:2 @@ fun () ->
91156
let computation = Computation.create () in
92157
let@ _ =
93158
finally Computation.await @@ fun () ->
@@ -174,17 +239,16 @@ let test_computation_completion_signals_triggers_in_order () =
174239

175240
let () =
176241
[
177-
("Trigger basics", [ Alcotest.test_case "" `Quick test_trigger_basics ]);
178-
( "Computation basics",
179-
[ Alcotest.test_case "" `Quick test_computation_basics ] );
180-
("Fiber.FLS basics", [ Alcotest.test_case "" `Quick test_fls_basics ]);
181-
( "Thread cancelation",
182-
[ Alcotest.test_case "" `Quick test_thread_cancelation ] );
183-
("Cancel after", [ Alcotest.test_case "" `Quick test_cancel_after ]);
184-
( "Computation signals in order",
242+
("Trigger", [ Alcotest.test_case "basics" `Quick test_trigger_basics ]);
243+
( "Computation",
185244
[
186-
Alcotest.test_case "" `Quick
245+
Alcotest.test_case "basics" `Quick test_computation_basics;
246+
Alcotest.test_case "tx" `Quick test_computation_tx;
247+
Alcotest.test_case "signals in order" `Quick
187248
test_computation_completion_signals_triggers_in_order;
188249
] );
250+
("Fiber.FLS", [ Alcotest.test_case "basics" `Quick test_fls_basics ]);
251+
("Cancel", [ Alcotest.test_case "" `Quick test_cancel ]);
252+
("Cancel after", [ Alcotest.test_case "" `Quick test_cancel_after ]);
189253
]
190254
|> Alcotest.run "Picos"

0 commit comments

Comments
 (0)