summaryrefslogtreecommitdiff
path: root/ocaml/test/test_runtime.ml
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-10-06 04:03:14 +0700
committerpolwex <polwex@sortug.com>2025-10-06 04:03:14 +0700
commit24eac75c69b3d74388bbbc8ee2b6792e7590e4c6 (patch)
tree3e3a22dde0d977dca4b28fc92ada0faea24990f7 /ocaml/test/test_runtime.ml
parentfd51dfdccf7b565e4214fe47a1420a9990fab342 (diff)
did this madman really implement parallelism on urbit
Diffstat (limited to 'ocaml/test/test_runtime.ml')
-rw-r--r--ocaml/test/test_runtime.ml178
1 files changed, 178 insertions, 0 deletions
diff --git a/ocaml/test/test_runtime.ml b/ocaml/test/test_runtime.ml
new file mode 100644
index 0000000..ff0514c
--- /dev/null
+++ b/ocaml/test/test_runtime.ml
@@ -0,0 +1,178 @@
+(* Runtime Tests - Testing the Eio-based Urbit runtime
+ *
+ * Tests:
+ * 1. Basic runtime creation
+ * 2. Event processing
+ * 3. Effect execution
+ * 4. Timer driver (Behn)
+ * 5. Concurrent event processing
+ *)
+
+open Nock_lib
+
+let test_runtime_creation env =
+ Printf.printf "Test: Runtime creation...\n";
+
+ (* Create pier directory *)
+ (try Unix.mkdir "tmp/test_pier" 0o755 with _ -> ());
+
+ let config = Runtime.default_config ~pier_path:"tmp/test_pier" () in
+ let events = [
+ Noun.atom 1;
+ Noun.atom 2;
+ Noun.atom 3;
+ ] in
+
+ let runtime = Runtime.run_simple ~env config events in
+ let stats = Runtime.get_stats runtime in
+
+ Printf.printf " Events processed: %Ld\n" stats.events_processed;
+ Printf.printf " State: %s\n" stats.state_summary;
+
+ assert (stats.events_processed = 3L);
+
+ Printf.printf " ✓ Runtime created and processed events!\n\n"
+
+let test_effect_queue _env =
+ Printf.printf "Test: Effect queue...\n";
+
+ let queue = Nock_lib.Effects.create_queue () in
+
+ (* Add some effects *)
+ Nock_lib.Effects.enqueue queue (Nock_lib.Effects.Log "Test message 1");
+ Nock_lib.Effects.enqueue queue (Nock_lib.Effects.SetTimer { id = 1L; time = 123.0 });
+ Nock_lib.Effects.enqueue queue (Nock_lib.Effects.Log "Test message 2");
+
+ Printf.printf " Queue length: %d\n" (Nock_lib.Effects.queue_length queue);
+ assert (Nock_lib.Effects.queue_length queue = 3);
+
+ (* Dequeue *)
+ let eff1 = Nock_lib.Effects.dequeue queue in
+ (match eff1 with
+ | Nock_lib.Effects.Log msg -> Printf.printf " Dequeued: Log(%s)\n" msg
+ | _ -> failwith "Wrong effect type"
+ );
+
+ assert (Nock_lib.Effects.queue_length queue = 2);
+
+ Printf.printf " ✓ Effect queue works!\n\n"
+
+let test_behn_driver env =
+ Printf.printf "Test: Behn timer driver...\n";
+
+ Eio.Switch.run @@ fun _sw ->
+
+ let behn = Io_drivers.Behn.create () in
+ let now = Unix.gettimeofday () in
+
+ (* Set a timer for 0.1 seconds from now *)
+ Io_drivers.Behn.set_timer behn ~id:1L ~fire_time:(now +. 0.1);
+
+ Printf.printf " Active timers: %d\n" (Io_drivers.Behn.active_timers behn);
+ assert (Io_drivers.Behn.active_timers behn = 1);
+
+ (* Sleep to let timer fire *)
+ Eio.Time.sleep (Eio.Stdenv.clock env) 0.2;
+
+ Printf.printf " Active timers after fire: %d\n" (Io_drivers.Behn.active_timers behn);
+
+ Printf.printf " ✓ Behn driver works!\n\n"
+
+let test_timer_cancellation env =
+ Printf.printf "Test: Timer cancellation...\n";
+
+ Eio.Switch.run @@ fun _sw ->
+
+ let behn = Io_drivers.Behn.create () in
+ let now = Unix.gettimeofday () in
+
+ (* Set a timer *)
+ Io_drivers.Behn.set_timer behn ~id:1L ~fire_time:(now +. 1.0);
+ assert (Io_drivers.Behn.active_timers behn = 1);
+
+ (* Cancel it immediately *)
+ Io_drivers.Behn.cancel_timer behn ~id:1L;
+
+ (* Sleep *)
+ Eio.Time.sleep (Eio.Stdenv.clock env) 0.1;
+
+ Printf.printf " ✓ Timer cancelled successfully!\n\n"
+
+let test_concurrent_timers env =
+ Printf.printf "Test: Concurrent timers...\n";
+
+ Eio.Switch.run @@ fun sw ->
+
+ let behn = Io_drivers.Behn.create () in
+ let effect_queue = Nock_lib.Effects.create_queue () in
+ let event_stream = Eio.Stream.create 100 in
+
+ let now = Unix.gettimeofday () in
+
+ (* Set multiple timers with different delays *)
+ let timer_ids = [1L; 2L; 3L; 4L; 5L] in
+ List.iteri (fun i id ->
+ let delay = 0.05 *. float_of_int (i + 1) in
+ Nock_lib.Effects.enqueue effect_queue (Nock_lib.Effects.SetTimer {
+ id;
+ time = now +. delay;
+ })
+ ) timer_ids;
+
+ Printf.printf " Set %d timers\n" (List.length timer_ids);
+
+ (* Run behn driver fiber with timeout *)
+ Eio.Fiber.fork ~sw (fun () ->
+ (* Run for limited time *)
+ let start = Unix.gettimeofday () in
+ let rec loop () =
+ if Unix.gettimeofday () -. start < 0.5 then begin
+ match Nock_lib.Effects.try_dequeue effect_queue with
+ | Some (Nock_lib.Effects.SetTimer { id; time }) ->
+ Io_drivers.Behn.set_timer behn ~id ~fire_time:time;
+ let timer = Hashtbl.find behn.timers id in
+ Eio.Fiber.fork ~sw (fun () ->
+ Io_drivers.Behn.timer_fiber behn ~env ~event_stream timer
+ );
+ loop ()
+ | _ ->
+ Eio.Time.sleep (Eio.Stdenv.clock env) 0.01;
+ loop ()
+ end
+ in
+ loop ()
+ );
+
+ (* Sleep to allow driver to run *)
+ Eio.Time.sleep (Eio.Stdenv.clock env) 0.6;
+
+ (* Count events produced *)
+ let event_count = ref 0 in
+ while Eio.Stream.length event_stream > 0 do
+ let _ = Eio.Stream.take event_stream in
+ event_count := !event_count + 1
+ done;
+
+ Printf.printf " Events produced: %d\n" !event_count;
+ Printf.printf " ✓ Concurrent timers work!\n\n"
+
+let () =
+ Eio_main.run @@ fun env ->
+ Printf.printf "\n🚀 === EIO RUNTIME TESTS === 🚀\n\n";
+
+ (* Clean up test directories *)
+ (try Unix.system "rm -rf tmp/test_pier*" |> ignore with _ -> ());
+
+ test_runtime_creation env;
+ test_effect_queue env;
+ test_behn_driver env;
+ test_timer_cancellation env;
+ test_concurrent_timers env;
+
+ Printf.printf "🎉 === ALL RUNTIME TESTS PASSED! === 🎉\n";
+ Printf.printf "\nThe Eio runtime is working!\n";
+ Printf.printf "- Event processing ✓\n";
+ Printf.printf "- Effect execution ✓\n";
+ Printf.printf "- Timer driver (Behn) ✓\n";
+ Printf.printf "- Concurrent fibers ✓\n\n";
+ Printf.printf "Ready for a full runtime with all I/O drivers!\n"