From 1e298318f4065fad86a58c3b95733648ef0c70b7 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Thu, 26 Nov 2020 14:13:13 -0800 Subject: [PATCH] generalize tests more test everything methodically Signed-off-by: Rudi Grinberg --- .../test-cases/github3766.t/run.t | 190 +++++++++++------- .../test-cases/github3766.t/test.ml | 169 +++++++++++----- 2 files changed, 231 insertions(+), 128 deletions(-) diff --git a/test/blackbox-tests/test-cases/github3766.t/run.t b/test/blackbox-tests/test-cases/github3766.t/run.t index 7ec4441623e4..d5250e9f2410 100644 --- a/test/blackbox-tests/test-cases/github3766.t/run.t +++ b/test/blackbox-tests/test-cases/github3766.t/run.t @@ -4,20 +4,24 @@ ocaml 4.12. In 4.11 - .a are always created In 4.12 - they are omitted if there are no modules or stubs -A single test case is in test.ml +There's a combination of 3 options: +- With or without stubs +- Wrapped or unwrapped +- Contains an mli only module - $ ./test.exe unwrapped_empty < (library - > (public_name foo) - > (wrapped false) - > (modules ())) - > EOF +Our test checks each of the above with an internal and external library. + + $ ./test.exe + # mli_only_wrapped_stubs -> creating dune-project # build the library and see if .a is present -> creating dune + -> creating stub.c + -> creating foo.mli % dune build --root . @install % ls _build/install/default/lib/foo/*.a _build/install/default/lib/foo/foo.a + _build/install/default/lib/foo/libfoo_stubs.a # create a dummy executable to test -> creating dune @@ -32,15 +36,12 @@ A single test case is in test.ml % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe exe working - $ ./test.exe wrapped_empty < (library - > (public_name foo) - > (wrapped true) - > (modules ())) - > EOF + + # mli_only_wrapped_no_stubs -> creating dune-project # build the library and see if .a is present -> creating dune + -> creating foo.mli % dune build --root . @install % ls _build/install/default/lib/foo/*.a _build/install/default/lib/foo/foo.a @@ -58,16 +59,13 @@ A single test case is in test.ml % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe exe working - $ ./test.exe unwrapped_empty_with_stubs --stub baz < (library - > (public_name foo) - > (wrapped false) - > (foreign_stubs (language c) (names baz))) - > EOF + + # mli_only_unwrapped_stubs -> creating dune-project # build the library and see if .a is present -> creating dune - -> creating baz.c + -> creating stub.c + -> creating foo.mli % dune build --root . @install % ls _build/install/default/lib/foo/*.a _build/install/default/lib/foo/foo.a @@ -86,25 +84,15 @@ A single test case is in test.ml % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe exe working - - $ ./test.exe mli_only_no_stubs --mli-only < (library - > (public_name foo) - > (modules_without_implementation foo)) - > EOF + + # mli_only_unwrapped_no_stubs -> creating dune-project # build the library and see if .a is present -> creating dune - -> creating mli_only_no_stubs.mli + -> creating foo.mli % dune build --root . @install - File "lib/dune", line 3, characters 33-36: - 3 | (modules_without_implementation foo)) - ^^^ - Error: Module Foo doesn't exist. - [1] % ls _build/install/default/lib/foo/*.a - ls: _build/install/default/lib/foo/*.a: No such file or directory - [1] + _build/install/default/lib/foo/foo.a # create a dummy executable to test -> creating dune @@ -112,44 +100,91 @@ A single test case is in test.ml # make sure that this library is usable locally % dune exec ./exe/b.exe - File "lib/dune", line 3, characters 33-36: - 3 | (modules_without_implementation foo)) - ^^^ - Error: Module Foo doesn't exist. - [1] + exe working # make sure that this library is usable externally % rm -rf lib % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe - File "exe/dune", line 5, characters 12-15: - 5 | (libraries foo)) - ^^^ - Error: Library "foo" not found. - Hint: try: - dune external-lib-deps --missing --build-dir _b2 ./exe/b.exe - [1] + exe working - - $ ./test.exe mli_only_no_stubs --mli-only --stub baz < (library - > (public_name foo) - > (foreign_stubs (language c) (names baz)) - > (modules_without_implementation foo)) - > EOF + + # no_mli_wrapped_stubs + -> creating dune-project + # build the library and see if .a is present + -> creating dune + -> creating stub.c + % dune build --root . @install + % ls _build/install/default/lib/foo/*.a + _build/install/default/lib/foo/foo.a + _build/install/default/lib/foo/libfoo_stubs.a + + # create a dummy executable to test + -> creating dune + -> creating b.ml + + # make sure that this library is usable locally + % dune exec ./exe/b.exe + exe working + + # make sure that this library is usable externally + % rm -rf lib + % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe + exe working + + + # no_mli_wrapped_no_stubs + -> creating dune-project + # build the library and see if .a is present + -> creating dune + % dune build --root . @install + % ls _build/install/default/lib/foo/*.a + _build/install/default/lib/foo/foo.a + + # create a dummy executable to test + -> creating dune + -> creating b.ml + + # make sure that this library is usable locally + % dune exec ./exe/b.exe + exe working + + # make sure that this library is usable externally + % rm -rf lib + % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe + exe working + + + # no_mli_unwrapped_stubs + -> creating dune-project + # build the library and see if .a is present + -> creating dune + -> creating stub.c + % dune build --root . @install + % ls _build/install/default/lib/foo/*.a + _build/install/default/lib/foo/foo.a + _build/install/default/lib/foo/libfoo_stubs.a + + # create a dummy executable to test + -> creating dune + -> creating b.ml + + # make sure that this library is usable locally + % dune exec ./exe/b.exe + exe working + + # make sure that this library is usable externally + % rm -rf lib + % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe + exe working + + + # no_mli_unwrapped_no_stubs -> creating dune-project # build the library and see if .a is present -> creating dune - -> creating baz.c - -> creating mli_only_no_stubs.mli % dune build --root . @install - File "lib/dune", line 4, characters 33-36: - 4 | (modules_without_implementation foo)) - ^^^ - Error: Module Foo doesn't exist. - [1] % ls _build/install/default/lib/foo/*.a - ls: _build/install/default/lib/foo/*.a: No such file or directory - [1] + _build/install/default/lib/foo/foo.a # create a dummy executable to test -> creating dune @@ -157,20 +192,27 @@ A single test case is in test.ml # make sure that this library is usable locally % dune exec ./exe/b.exe - File "lib/dune", line 4, characters 33-36: - 4 | (modules_without_implementation foo)) - ^^^ - Error: Module Foo doesn't exist. - [1] + exe working # make sure that this library is usable externally % rm -rf lib % OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 ./exe/b.exe - File "exe/dune", line 5, characters 12-15: - 5 | (libraries foo)) - ^^^ - Error: Library "foo" not found. - Hint: try: - dune external-lib-deps --missing --build-dir _b2 ./exe/b.exe - [1] + exe working + + mli_only_wrapped_stubs - external - pass + mli_only_wrapped_stubs - internal - pass + mli_only_wrapped_no_stubs - external - pass + mli_only_wrapped_no_stubs - internal - pass + mli_only_unwrapped_stubs - external - pass + mli_only_unwrapped_stubs - internal - pass + mli_only_unwrapped_no_stubs - external - pass + mli_only_unwrapped_no_stubs - internal - pass + no_mli_wrapped_stubs - external - pass + no_mli_wrapped_stubs - internal - pass + no_mli_wrapped_no_stubs - external - pass + no_mli_wrapped_no_stubs - internal - pass + no_mli_unwrapped_stubs - external - pass + no_mli_unwrapped_stubs - internal - pass + no_mli_unwrapped_no_stubs - external - pass + no_mli_unwrapped_no_stubs - internal - pass diff --git a/test/blackbox-tests/test-cases/github3766.t/test.ml b/test/blackbox-tests/test-cases/github3766.t/test.ml index 170f39387cae..6c0b88623e33 100644 --- a/test/blackbox-tests/test-cases/github3766.t/test.ml +++ b/test/blackbox-tests/test-cases/github3766.t/test.ml @@ -1,27 +1,5 @@ open! Stdune -let mli_only = ref false - -let stub = ref None - -let name = ref "" - -let () = - let anon s = name := s in - let set_stub s = stub := Some s in - let args = - [ ("--stub", Arg.String set_stub, "C stub") - ; ("--mli-only", Arg.Set mli_only, "mli only") - ] - in - Arg.parse (Arg.align args) anon "./test.exe [--stub]" - -let stub = !stub - -let mli_only = !mli_only - -let name = !name - let stanza = Io.read_all stdin let cwd () = Path.external_ (Path.External.cwd ()) @@ -30,7 +8,7 @@ let chdir dir = Unix.chdir (Path.to_absolute_filename dir) let prefix = "test.exe." -let suffix = "." ^ name +let suffix = ".t" let file name c = let path = Path.relative (cwd ()) name in @@ -39,8 +17,9 @@ let file name c = let descr s f = printfn "# %s" s; - f (); - print_endline "" + let res = f () in + print_endline ""; + res let sh = let path = Env.path Env.initial in @@ -53,7 +32,7 @@ let in_dir name f = chdir dir; Exn.protect ~f ~finally:(fun () -> chdir cwd) -let cmd s = +let cmd_res s = let script = Temp.create File ~prefix ~suffix in Io.write_file script s; print_endline ("% " ^ s); @@ -66,41 +45,123 @@ let cmd s = let pid', code = Unix.wait () in assert (Pid.equal pid (Pid.of_int pid')); match code with - | WEXITED 0 -> () - | WEXITED n -> printfn "[%d]" n - | _ -> () + | WEXITED 0 -> Ok () + | WEXITED n -> + printfn "[%d]" n; + Ok () + | _ -> Error () -let () = - in_dir name (fun () -> - file "dune-project" {|(lang dune 2.8) +let cmd s = + match cmd_res s with + | Error () -> () + | Ok () -> () + +module Spec = struct + type t = + { mli_only : bool + ; wrapped : bool + ; stubs : bool + } + + let name { mli_only; wrapped; stubs } = + sprintf "%s_%s_%s" + ( if mli_only then + "mli_only" + else + "no_mli" ) + ( if wrapped then + "wrapped" + else + "unwrapped" ) + ( if stubs then + "stubs" + else + "no_stubs" ) + + let all = + let for_all f = List.concat_map [ true; false ] ~f in + for_all (fun mli_only -> + for_all (fun wrapped -> + for_all (fun stubs -> [ { mli_only; wrapped; stubs } ]))) + + type res = + { internal : bool + ; external_ : bool + } + + let run_body t () = + let res = ref { internal = false; external_ = false } in + let cmd_report k s = + let new_res = Result.is_ok (cmd_res s) in + match k with + | `Internal -> res := { !res with internal = new_res } + | `External -> res := { !res with external_ = new_res } + in + file "dune-project" {|(lang dune 2.8) (package (name foo)) |}; - descr "build the library and see if .a is present" (fun () -> - in_dir "lib" (fun () -> - file "dune" stanza; - Option.iter stub ~f:(fun name -> - file (name ^ ".c") "void foo() {}"); - if mli_only then file (name ^ ".mli") "type x = unit"); - cmd "dune build --root . @install"; - cmd "ls _build/install/default/lib/foo/*.a"); - - descr "create a dummy executable to test" (fun () -> - in_dir "exe" (fun () -> - file "dune" - {| + descr "build the library and see if .a is present" (fun () -> + in_dir "lib" (fun () -> + let stubs = + if t.stubs then + "(foreign_stubs (language c) (names stub))" + else + "" + in + file "dune" + (Printf.sprintf + {| +(library + (public_name foo) + (wrapped %b) + %s + (modules ())) +|} + t.wrapped stubs); + if t.stubs then file "stub.c" "void foo() {}"; + if t.mli_only then file "foo.mli" "type x = unit"); + cmd "dune build --root . @install"; + cmd "ls _build/install/default/lib/foo/*.a"); + + descr "create a dummy executable to test" (fun () -> + in_dir "exe" (fun () -> + file "dune" + {| (executable (name b) (link_flags -linkall) (libraries foo)) |}; - file "b.ml" "print_endline \"exe working\"")); - - descr "make sure that this library is usable locally" (fun () -> - cmd "dune exec ./exe/b.exe"); + file "b.ml" "print_endline \"exe working\"")); + + descr "make sure that this library is usable locally" (fun () -> + cmd_report `Internal "dune exec ./exe/b.exe"); + + descr "make sure that this library is usable externally" (fun () -> + cmd "rm -rf lib"; + cmd_report `External + "OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 \ + ./exe/b.exe"); + !res + + let run t = + let name = name t in + descr name (fun () -> in_dir name (run_body t)) + + let report t { external_; internal } = + let name = name t in + let res x = + if x then + "pass" + else + "fail" + in + Printf.printf "%s - external - %s\n" name (res external_); + Printf.printf "%s - internal - %s\n" name (res internal) +end - descr "make sure that this library is usable externally" (fun () -> - cmd "rm -rf lib"; - cmd - "OCAMLPATH=_build/install/default/lib dune exec --build-dir=_b2 \ - ./exe/b.exe")) +let () = + Spec.all + |> List.map ~f:(fun t -> (t, Spec.run t)) + |> List.iter ~f:(fun (t, res) -> Spec.report t res)