Update to latest MDX to fix exception reporting

This commit is contained in:
Thomas Leonard 2021-07-13 08:42:44 +01:00
parent cc73b5945b
commit 108aa75230
15 changed files with 91 additions and 151 deletions

View File

@ -216,8 +216,7 @@ Here's what happens if one of the two threads above fails:
(fun () -> for x = 1 to 3 do traceln "x = %d" x; Fibre.yield ~sw () done)
(fun () -> failwith "Simulated error");;
x = 1
Error: Simulated error
- : unit = ()
Exception: Failure "Simulated error".
```
What happened here was:

View File

@ -8,7 +8,7 @@ license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "2.8"}
"dune" {>= "2.9"}
"alcotest" {>= "1.4.0" & with-test}
"ppx_cstruct" {>= "6.0.0"}
"ocplib-endian" {>= "1.1"}
@ -17,7 +17,7 @@ depends: [
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
["dune" "subst" "--root" "."] {dev}
[
"dune"
"build"
@ -25,9 +25,12 @@ build: [
name
"-j"
jobs
"--promote-install-files"
"false"
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
["dune" "install" "-p" name "--create-install-files" name]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"

View File

@ -23,14 +23,12 @@ module Eio_main = struct
let run fn =
Eio_main.run @@ fun env ->
try
fn @@ object
method net = dontcrash env#net
method stdin = dontcrash env#stdin
method stdout = dontcrash env#stdout
method cwd = dontcrash env#cwd
method domain_mgr = dontcrash env#domain_mgr
method clock = fake_clock env#clock
end
with Failure msg -> traceln "Error: %s" msg
fn @@ object
method net = dontcrash env#net
method stdin = dontcrash env#stdin
method stdout = dontcrash env#stdout
method cwd = dontcrash env#cwd
method domain_mgr = dontcrash env#domain_mgr
method clock = fake_clock env#clock
end
end

1
dune
View File

@ -1,4 +1,5 @@
(mdx
(package eio_main)
(packages eio_main)
(preludes doc/prelude.ml)
(files README.md))

View File

@ -1,4 +1,4 @@
(lang dune 2.8)
(lang dune 2.9)
(name eunix)
(generate_opam_files true)
(source (github ocaml-multicore/eio))
@ -39,7 +39,7 @@
(ctf (= :version))
(eio (= :version))
(eunix (= :version))
(mdx :with-test)
(mdx (and (>= 1.10.0) :with-test))
(logs (>= 0.7.0))
(fmt (>= 0.8.9))
(bigstringaf (>= 0.7.0))

View File

@ -8,7 +8,7 @@ license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "2.8"}
"dune" {>= "2.9"}
"ctf" {= version}
"cstruct" {>= "6.0.0"}
"lwt-dllist"
@ -16,7 +16,7 @@ depends: [
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
["dune" "subst" "--root" "."] {dev}
[
"dune"
"build"
@ -24,9 +24,12 @@ build: [
name
"-j"
jobs
"--promote-install-files"
"false"
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
["dune" "install" "-p" name "--create-install-files" name]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"

View File

@ -8,12 +8,12 @@ license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "2.8"}
"dune" {>= "2.9"}
"ocaml-variants" {= "4.12.0+domains+effects"}
"ctf" {= version}
"eio" {= version}
"eunix" {= version}
"mdx" {with-test}
"mdx" {>= "1.10.0" & with-test}
"logs" {>= "0.7.0"}
"fmt" {>= "0.8.9"}
"bigstringaf" {>= "0.7.0"}
@ -21,7 +21,7 @@ depends: [
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
["dune" "subst" "--root" "."] {dev}
[
"dune"
"build"
@ -29,9 +29,12 @@ build: [
name
"-j"
jobs
"--promote-install-files"
"false"
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
["dune" "install" "-p" name "--create-install-files" name]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"

View File

@ -8,12 +8,12 @@ license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "2.8"}
"dune" {>= "2.9"}
"eunix" {= version}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
["dune" "subst" "--root" "."] {dev}
[
"dune"
"build"
@ -21,9 +21,12 @@ build: [
name
"-j"
jobs
"--promote-install-files"
"false"
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
["dune" "install" "-p" name "--create-install-files" name]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"

View File

@ -8,7 +8,7 @@ license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "2.8"}
"dune" {>= "2.9"}
"ocaml-variants" {= "4.12.0+domains+effects"}
"ctf" {= version}
"eio" {= version}
@ -20,7 +20,7 @@ depends: [
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
["dune" "subst" "--root" "."] {dev}
[
"dune"
"build"
@ -28,9 +28,12 @@ build: [
name
"-j"
jobs
"--promote-install-files"
"false"
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
["dune" "install" "-p" name "--create-install-files" name]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"

View File

@ -1,2 +1,3 @@
(mdx
(package eio_main)
(packages eio_main))

View File

@ -8,13 +8,8 @@
open Eio.Std
let run (fn : Eio.Domain_manager.t -> unit) =
try
Eio_main.run @@ fun env ->
fn (Eio.Stdenv.domain_mgr env);
print_endline "ok"
with
| Failure msg -> print_endline msg
| ex -> print_endline (Printexc.to_string ex)
Eio_main.run @@ fun env ->
fn (Eio.Stdenv.domain_mgr env)
```
# Test cases
@ -26,7 +21,6 @@ Spawning a second domain:
let response = Eio.Domain_manager.run_compute_unsafe mgr (fun () -> "Hello from new domain") in
traceln "Got %S from spawned domain" response
Got "Hello from new domain" from spawned domain
ok
- : unit = ()
```
@ -35,8 +29,7 @@ The domain raises an exception:
```ocaml
# run @@ fun mgr ->
Eio.Domain_manager.run_compute_unsafe mgr (fun () -> failwith "Exception from new domain")
Exception from new domain
- : unit = ()
Exception: Failure "Exception from new domain".
```
We can still run other fibres in the main domain while waiting:
@ -56,6 +49,5 @@ We can still run other fibres in the main domain while waiting:
Spawning new domain...
Other fibres can still run
Got "Hello from new domain" from spawned domain
ok
- : unit = ()
```

View File

@ -10,14 +10,9 @@
open Eio.Std
let run (fn : sw:Switch.t -> Eio.Stdenv.t -> unit) =
try
Eio_main.run @@ fun env ->
Switch.top @@ fun sw ->
fn ~sw env;
print_endline "ok"
with
| Failure msg -> print_endline msg
| ex -> print_endline (Printexc.to_string ex)
Eio_main.run @@ fun env ->
Switch.top @@ fun sw ->
fn ~sw env
let read_all ?sw flow =
let b = Buffer.create 100 in
@ -55,7 +50,6 @@ Creating a file and reading it back:
write_file ~sw ~create:(`Exclusive 0o666) cwd "test-file" "my-data";
traceln "Got %S" @@ read_file ~sw cwd "test-file"
Got "my-data"
ok
- : unit = ()
```
@ -74,8 +68,9 @@ Trying to use cwd to access a file outside of that subtree fails:
let cwd = Eio.Stdenv.cwd env in
write_file ~sw ~create:(`Exclusive 0o666) cwd "../test-file" "my-data";
failwith "Should have failed"
Eio.Dir.Permission_denied("../test-file", _)
- : unit = ()
Exception:
Eio.Dir.Permission_denied ("../test-file",
Unix.Unix_error (Unix.EXDEV, "openat2", "")).
```
Trying to use cwd to access an absolute path fails:
@ -84,8 +79,9 @@ Trying to use cwd to access an absolute path fails:
let cwd = Eio.Stdenv.cwd env in
write_file ~sw ~create:(`Exclusive 0o666) cwd "/tmp/test-file" "my-data";
failwith "Should have failed"
Eio.Dir.Permission_denied("/tmp/test-file", _)
- : unit = ()
Exception:
Eio.Dir.Permission_denied ("/tmp/test-file",
Unix.Unix_error (Unix.EXDEV, "openat2", "")).
```
# Creation modes
@ -97,8 +93,7 @@ Exclusive create fails if already exists:
write_file ~sw ~create:(`Exclusive 0o666) cwd "test-file" "first-write";
write_file ~sw ~create:(`Exclusive 0o666) cwd "test-file" "first-write";
failwith "Should have failed"
Unix.Unix_error(Unix.EEXIST, "openat2", "")
- : unit = ()
Exception: Unix.Unix_error(Unix.EEXIST, "openat2", "")
```
If-missing create succeeds if already exists:
@ -109,7 +104,6 @@ If-missing create succeeds if already exists:
write_file ~sw ~create:(`If_missing 0o666) cwd "test-file" "2nd-write";
traceln "Got %S" @@ read_file ~sw cwd "test-file"
Got "2nd-write-original"
ok
- : unit = ()
```
@ -121,7 +115,6 @@ Truncate create succeeds if already exists, and truncates:
write_file ~sw ~create:(`Or_truncate 0o666) cwd "test-file" "2nd-write";
traceln "Got %S" @@ read_file ~sw cwd "test-file"
Got "2nd-write"
ok
- : unit = ()
# Unix.unlink "test-file";;
- : unit = ()
@ -133,8 +126,7 @@ Error if no create and doesn't exist:
let cwd = Eio.Stdenv.cwd env in
write_file ~sw ~create:`Never cwd "test-file" "1st-write-original";
traceln "Got %S" @@ read_file ~sw cwd "test-file"
Unix.Unix_error(Unix.ENOENT, "openat2", "")
- : unit = ()
Exception: Unix.Unix_error(Unix.ENOENT, "openat2", "")
```
Appending to an existing file:
@ -145,7 +137,6 @@ Appending to an existing file:
write_file ~sw ~create:`Never ~append:true cwd "test-file" "2nd-write";
traceln "Got %S" @@ read_file ~sw cwd "test-file"
Got "1st-write-original2nd-write"
ok
- : unit = ()
# Unix.unlink "test-file";;
- : unit = ()
@ -162,7 +153,6 @@ ok
()
mkdir "subdir" -> ok
mkdir "subdir/nested" -> ok
ok
- : unit = ()
# Unix.unlink "subdir/nested/test-file"; Unix.rmdir "subdir/nested"; Unix.rmdir "subdir";;
- : unit = ()
@ -191,7 +181,6 @@ mkdir "to-root/tmp/foo" -> Eio.Dir.Permission_denied("to-root/tmp", _)
mkdir "../foo" -> Eio.Dir.Permission_denied("..", _)
mkdir "to-subdir" -> Unix.Unix_error(Unix.EEXIST, "mkdirat", "to-subdir")
mkdir "dangle/foo" -> Unix.Unix_error(Unix.ENOENT, "openat2", "")
ok
- : unit = ()
```
@ -209,7 +198,6 @@ Create a sandbox, write a file with it, then read it from outside:
mkdir "sandbox" -> ok
mkdir "../new-sandbox" -> Eio.Dir.Permission_denied("..", _)
Got "data"
ok
- : unit = ()
```
@ -238,6 +226,5 @@ write "../test-file" -> Eio.Dir.Permission_denied("../test-file", _)
mkdir "../outside-cwd" -> ok
write "../test-file" -> ok
chdir ".."
ok
- : unit = ()
```

View File

@ -8,14 +8,9 @@
open Eio.Std
let run (fn : net:Eio.Net.t -> Switch.t -> unit) =
try
Eio_main.run @@ fun env ->
let net = Eio.Stdenv.net env in
Switch.top (fn ~net);
print_endline "ok"
with
| Failure msg -> print_endline msg
| ex -> print_endline (Printexc.to_string ex)
Eio_main.run @@ fun env ->
let net = Eio.Stdenv.net env in
Switch.top (fn ~net)
let addr = `Tcp (Unix.inet_addr_loopback, 8081)
@ -79,8 +74,7 @@ Server accepted connection from client
Server received: "Hello from client"
Client received: "Bye"
Client finished - cancelling server
Test is over
- : unit = ()
Exception: Failure "Test is over".
```
Handling one connection on a Unix domain socket:
@ -92,8 +86,7 @@ Server accepted connection from client
Server received: "Hello from client"
Client received: "Bye"
Client finished - cancelling server
Test is over
- : unit = ()
Exception: Failure "Test is over".
```
Handling one connection on an abstract Unix domain socket:
@ -105,8 +98,7 @@ Server accepted connection from client
Server received: "Hello from client"
Client received: "Bye"
Client finished - cancelling server
Test is over
- : unit = ()
Exception: Failure "Test is over".
```
Cancelling the read:
@ -136,8 +128,7 @@ Cancelling the read:
Connecting to server...
Connection opened - cancelling server's read
Client received: "Request cancelled"
Graceful_shutdown
- : unit = ()
Exception: Graceful_shutdown.
```
Calling accept when the switch is already off:
@ -148,6 +139,5 @@ Calling accept when the switch is already off:
Switch.turn_off sw (Failure "Simulated error");
Eio.Net.accept_sub server ~sw (fun ~sw:_ _flow _addr -> assert false)
~on_error:raise
Simulated error
- : unit = ()
Exception: Failure "Simulated error".
```

View File

@ -8,13 +8,8 @@
open Eio.Std
let run (fn : Switch.t -> unit) =
try
Eio_main.run @@ fun _e ->
Switch.top fn;
print_endline "ok"
with
| Failure msg -> print_endline msg
| ex -> print_endline (Printexc.to_string ex)
Eio_main.run @@ fun _e ->
Switch.top fn
```
# Test cases
@ -26,7 +21,6 @@ A very basic example:
traceln "Running"
);
Running
ok
- : unit = ()
```
@ -40,8 +34,7 @@ Turning off a switch still allows you to perform clean-up operations:
);
Running
Clean up
Cancel
- : unit = ()
Exception: Failure "Cancel".
```
`Fibre.both`, both fibres pass:
@ -56,7 +49,6 @@ i = 1
j = 1
i = 2
j = 2
ok
- : unit = ()
```
@ -69,8 +61,7 @@ ok
(fun () -> failwith "Failed")
)
i = 1
Failed
- : unit = ()
Exception: Failure "Failed".
```
`Fibre.both`, only 2nd succeeds:
@ -82,8 +73,7 @@ Failed
(fun () -> for i = 1 to 5 do traceln "i = %d" i; Fibre.yield ~sw () done)
)
i = 1
Failed
- : unit = ()
Exception: Failure "Failed".
```
`Fibre.both`, first fails but the other doesn't stop:
@ -93,8 +83,7 @@ Failed
Fibre.both ~sw (fun () -> failwith "Failed") ignore;
traceln "Not reached"
)
Failed
- : unit = ()
Exception: Failure "Failed".
```
`Fibre.both`, second fails but the other doesn't stop:
@ -104,8 +93,7 @@ Failed
Fibre.both ~sw ignore (fun () -> failwith "Failed");
traceln "not reached"
)
Failed
- : unit = ()
Exception: Failure "Failed".
```
`Fibre.both`, both fibres fail:
@ -116,11 +104,10 @@ Failed
(fun () -> failwith "Failed 1")
(fun () -> failwith "Failed 2")
)
Multiple exceptions:
Exception: Multiple exceptions:
Failure("Failed 1")
and
Failure("Failed 2")
- : unit = ()
```
The switch is already turned off when we try to fork. The new fibre doesn't start:
@ -132,8 +119,7 @@ The switch is already turned off when we try to fork. The new fibre doesn't star
traceln "Main continues"
)
Main continues
Cancel
- : unit = ()
Exception: Failure "Cancel".
```
You can't use a switch after leaving its scope:
@ -143,7 +129,6 @@ You can't use a switch after leaving its scope:
let x = ref None in
run (fun sw -> x := Some sw);
Option.get !x
ok
val sw : Switch.t = <abstr>
# Switch.check sw
Exception: Invalid_argument "Switch finished!".
@ -166,8 +151,7 @@ Turning off a switch runs the cancel callbacks, unless they've been removed by t
Cancel 3
Cancel 1
Cancel 4
Cancelled
- : unit = ()
Exception: Failure "Cancelled".
```
Wait for either a promise or a switch; switch cancelled first:
@ -179,8 +163,7 @@ Wait for either a promise or a switch; switch cancelled first:
Promise.fulfill r ()
)
Waiting
Cancelled
- : unit = ()
Exception: Failure "Cancelled".
```
Wait for either a promise or a switch; promise resolves first:
@ -197,8 +180,7 @@ Wait for either a promise or a switch; promise resolves first:
Waiting
Resolved
Now cancelling...
Cancelled
- : unit = ()
Exception: Failure "Cancelled".
```
Wait for either a promise or a switch; switch cancelled first. Result version.
@ -211,8 +193,7 @@ Wait for either a promise or a switch; switch cancelled first. Result version.
Promise.fulfill r ()
);
Waiting
Cancelled
- : unit = ()
Exception: Failure "Cancelled".
```
Wait for either a promise or a switch; promise resolves first but switch off without yielding:
@ -227,8 +208,7 @@ Wait for either a promise or a switch; promise resolves first but switch off wit
)
Waiting
Now cancelling...
Cancelled
- : unit = ()
Exception: Failure "Cancelled".
```
Child switches are cancelled when the parent is cancelled:
@ -245,8 +225,7 @@ Child 1
Child 2
child: Failure("Cancel parent")
child: Failure("Cancel parent")
Cancel parent
- : unit = ()
Exception: Failure "Cancel parent".
```
A child can fail independently of the parent:
@ -267,7 +246,6 @@ Child 1
Child 2
child: Failure("Child error")
Parent fibre is still running
ok
- : unit = ()
```
@ -290,7 +268,6 @@ A child can be cancelled independently of the parent:
Child 1
child: Failure("Cancel child")
Parent fibre is still running
ok
- : unit = ()
```
@ -306,8 +283,7 @@ A child error handle raises:
traceln "Not reached"
)
Child
Child error escapes
- : unit = ()
Exception: Failure "Child error escapes".
```
A child error handler deals with the exception:
@ -320,7 +296,6 @@ A child error handler deals with the exception:
)
Failure("Child error")
x = 0
ok
- : unit = ()
```
@ -331,8 +306,9 @@ The system deadlocks. The scheduler detects and reports this:
let p, _ = Promise.create () in
Promise.await ~sw p
)
Deadlock detected: no events scheduled but main function hasn't returned
- : unit = ()
Exception:
Failure
"Deadlock detected: no events scheduled but main function hasn't returned".
```
# Release handlers
@ -346,7 +322,6 @@ Release on success:
)
release 2
release 1
ok
- : unit = ()
```
@ -360,8 +335,7 @@ Release on error:
)
release 2
release 1
Test error
- : unit = ()
Exception: Failure "Test error".
```
A release operation itself fails:
@ -375,11 +349,10 @@ A release operation itself fails:
release 3
release 2
release 1
Multiple exceptions:
Exception: Multiple exceptions:
Failure("failure 3")
and
Failure("failure 1")
- : unit = ()
```
Using switch from inside release handler:
@ -409,7 +382,6 @@ Starting release 1
Finished release 2
Finished release 1
Late release
ok
- : unit = ()
```
@ -432,7 +404,6 @@ We release when `fork_sub_ignore` returns:
Allocate resource
Child fibre running
Free resource
ok
- : unit = ()
```
@ -445,8 +416,7 @@ We release when `fork_sub_ignore` fails due to parent switch being already off:
)
Allocate resource
Free resource
Switch already off
- : unit = ()
Exception: Failure "Switch already off".
```
We release when `fork_sub_ignore` fails due to parent switch being invalid:
@ -459,8 +429,7 @@ We release when `fork_sub_ignore` fails due to parent switch being invalid:
)
Allocate resource
Free resource
Invalid_argument("Switch finished!")
- : unit = ()
Exception: Invalid_argument "Switch finished!".
```
We release when `fork_sub_ignore`'s switch is turned off while running:
@ -474,6 +443,5 @@ We release when `fork_sub_ignore`'s switch is turned off while running:
)
Allocate resource
Free resource
Simulated error
- : unit = ()
Exception: Failure "Simulated error".
```

View File

@ -8,14 +8,9 @@
open Eio.Std
let run (fn : clock:Eio.Time.clock -> unit) =
try
Eio_main.run @@ fun env ->
let clock = Eio.Stdenv.clock env in
fn ~clock;
print_endline "ok"
with
| Failure msg -> print_endline msg
| ex -> print_endline (Printexc.to_string ex)
Eio_main.run @@ fun env ->
let clock = Eio.Stdenv.clock env in
fn ~clock
```
# Test cases
@ -28,7 +23,6 @@ Check sleep works:
Eio.Time.sleep clock 0.01;
let t1 = Unix.gettimeofday () in
assert (t1 -. t0 >= 0.01)
ok
- : unit = ()
```
@ -41,7 +35,6 @@ Check sleep works with a switch:
Eio.Time.sleep ~sw clock 0.01;
let t1 = Unix.gettimeofday () in
assert (t1 -. t0 >= 0.01)
ok
- : unit = ()
```
@ -53,8 +46,7 @@ Cancelling sleep:
Fibre.both ~sw
(fun () -> Eio.Time.sleep ~sw clock 1200.; assert false)
(fun () -> Switch.turn_off sw (Failure "Simulated cancel"))
Simulated cancel
- : unit = ()
Exception: Failure "Simulated cancel".
```
Switch is already off:
@ -65,8 +57,7 @@ Switch is already off:
Switch.turn_off sw (Failure "Simulated failure");
Eio.Time.sleep ~sw clock 1200.0;
assert false
Simulated failure
- : unit = ()
Exception: Failure "Simulated failure".
```
Scheduling a timer that's already due:
@ -80,7 +71,6 @@ Scheduling a timer that's already due:
First fibre runs
Second fibre runs
Sleep done
ok
- : unit = ()
```
@ -100,6 +90,5 @@ Check ordering works:
Switch.turn_off sw (Failure "Simulated cancel")
)
Short timer finished
Simulated cancel
- : unit = ()
Exception: Failure "Simulated cancel".
```