This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,49 @@
In this test we check a cycle when a library depends on a genrated source file which in
turn depends on the inline-test-name alias of the inline tests of the library.
$ cat >dune-project <<EOF
> (lang dune 3.18)
> EOF
$ cat >test.ml <<EOF
> (*TEST: assert (1 = 2) *)
> EOF
$ cat >dune <<EOF
> (library
> (name backend_simple)
> (modules ())
> (inline_tests.backend
> (generate_runner (run sed "s/(\\\\*TEST:\\\\(.*\\\\)\\\\*)/let () = if \\"%{inline_tests}\\" = \\"enabled\\" then \\\\1;;/" %{impl-files}))))
>
> (library
> (name foo_simple)
> (inline_tests (backend backend_simple)))
>
> (rule
> (deps
> (alias runtest-foo_simple))
> (action
> (with-outputs-to bar.ml
> (echo "let message = \"Hello world\""))))
> EOF
This kind of cycle has a difficult to understand error message.
$ dune build 2>&1 | grep -vwE "sed"
File "dune", lines 7-9, characters 0-69:
7 | (library
8 | (name foo_simple)
9 | (inline_tests (backend backend_simple)))
Error: Dependency cycle between:
_build/default/.foo_simple.objs/foo_simple__Bar.impl.all-deps
-> _build/default/.foo_simple.objs/byte/foo_simple__Bar.cmi
-> _build/default/.foo_simple.inline-tests/.t.eobjs/native/dune__exe__Main.cmx
-> _build/default/.foo_simple.inline-tests/inline-test-runner.exe
-> alias runtest-foo_simple in dune:9
-> _build/default/bar.ml
-> _build/default/.foo_simple.objs/foo_simple__Bar.impl.d
-> _build/default/.foo_simple.objs/foo_simple__Bar.impl.all-deps
-> required by _build/default/.foo_simple.objs/byte/foo_simple__Bar.cmo
-> required by _build/default/foo_simple.cma
-> required by alias all
-> required by alias default

View file

@ -0,0 +1,53 @@
Failing inline tests shouldn't hinder the diffing or promotion of other tests.
$ cat >dune-project <<EOF
> (lang dune 3.7)
> EOF
$ cat > dune << EOF
> (library
> (name test)
> (inline_tests)
> (wrapped false)
> (preprocess (pps ppx_expect)))
> EOF
Here is a broken test in it's own file.
$ cat > print.ml << EOF
> let f = Printf.printf
> EOF
We have two files with an inline test. Both tests should fail.
$ cat > test1.ml << EOF
> let%expect_test "test1" = Print.f "hello"; [%expect {| |}]
> EOF
$ cat > test2.ml << EOF
> let%expect_test "test1" = Print.f "hello"; [%expect {| |}]
> EOF
$ dune test
File "test1.ml", line 1, characters 0-0:
Error: Files _build/default/test1.ml and _build/default/test1.ml.corrected
differ.
File "test2.ml", line 1, characters 0-0:
Error: Files _build/default/test2.ml and _build/default/test2.ml.corrected
differ.
[1]
$ dune promote
Promoting _build/default/test1.ml.corrected to test1.ml.
Promoting _build/default/test2.ml.corrected to test2.ml.
$ cat test1.ml
let%expect_test "test1" = Print.f "hello"; [%expect {| hello |}]
$ cat test2.ml
let%expect_test "test1" = Print.f "hello"; [%expect {| hello |}]
We can see that running test again succeed.
$ dune test
$ dune promote
$ cat test1.ml
let%expect_test "test1" = Print.f "hello"; [%expect {| hello |}]
$ cat test2.ml
let%expect_test "test1" = Print.f "hello"; [%expect {| hello |}]

View file

@ -0,0 +1,13 @@
(cram
(applies_to github6607 reason-expect concurrent-fail)
(deps
(package ppx_expect)))
(cram
(applies_to reason-expect)
(deps %{bin:refmt}))
(cram
(applies_to github6607)
(deps
(package stdune)))

View file

@ -0,0 +1,3 @@
(library
(name foo_tests)
(inline_tests (backend foo)))

View file

@ -0,0 +1,19 @@
(library
(name foo)
(public_name foo)
(modules ())
(inline_tests.backend
(runner_libraries str)
(generate_runner
(progn
(echo "let () = print_int 41")
(echo "\n")
(echo "let () = print_int 42")
(echo "\n")
(echo "let () = print_int 43;;")))
(flags inline-test-runner %{library-name}
-source-tree-root %{workspace_root} -diff-cmd -)))
(library
(name foo_tests)
(inline_tests (backend foo)))

View file

@ -0,0 +1,31 @@
This test makes sure that inline_tests backends are functional when they are
externally installed.
First we build and use the backend locally:
$ dune runtest dune-file
414243
Then we install the backend and check that the "inline_tests.backend"
field is properly generated in the installed `dune-package` file:
$ dune build dune-file/foo.install
$ dune install foo --prefix _install
$ grep -A8 inline_tests.backend _install/lib/foo/dune-package
(inline_tests.backend
(runner_libraries str)
(flags
inline-test-runner
%{library-name}
-source-tree-root
%{workspace_root}
-diff-cmd
-)
Now we make sure that we can use the backend when it's available as an external
package:
$ export OCAMLPATH=$PWD/_install/lib; dune runtest --root dune-file-user
Entering directory 'dune-file-user'
414243
Leaving directory 'dune-file-user'

View file

@ -0,0 +1,22 @@
enabled_if inside the inline_tests field in the library stanza
$ mkdir tmp && cd tmp
$ cat >dune-project <<EOF
> (lang dune 3.0)
> EOF
$ cat >dune <<EOF
> (library
> (name backend_mbc)
> (modules ())
> (inline_tests.backend
> (generate_runner (echo "print_endline \"backend_mbc\""))))
>
> (library
> (name foo_mbc)
> (inline_tests
> (enabled_if false)
> (backend backend_mbc))
> (libraries backend_mbc))
> EOF
$ dune runtest

View file

@ -0,0 +1,17 @@
This test ensures that compilation fails when an invalid option is supplied
to flags field in executable field in inline_tests field.
First, we pass a valid option to flags field expecting compilation
to be successful.
$ dune runtest valid_options --root ./test-project
Entering directory 'test-project'
backend_foo
Leaving directory 'test-project'
Lastly, we pass an invalid option to flags field expecting compilation
to fail.
$ output=$(dune runtest invalid_options --root ./test-project 2>&1); result=$?; (echo $output | grep -o "unknown option '-option-that-is-not-accepted-by-ocaml'."); (exit $result)
unknown option '-option-that-is-not-accepted-by-ocaml'.
[1]

View file

@ -0,0 +1,6 @@
(library
(name backend_foo)
(modules ())
(inline_tests.backend
(generate_runner
(echo "let () = print_endline \"backend_foo\""))))

View file

@ -0,0 +1,6 @@
(library
(name invalid_option_test)
(inline_tests
(backend backend_foo)
(executable
(flags -option-that-is-not-accepted-by-ocaml))))

View file

@ -0,0 +1,6 @@
(library
(name valid_option_test)
(inline_tests
(backend backend_foo)
(executable
(flags -nolabels))))

View file

@ -0,0 +1,58 @@
This shows that the test suite is impacted by CLICOLOR_FORCE=1 (#6607).
This environment variable should only impact the output of dune, not behavior
visible from within the test suite.
$ cat > dune-project << EOF
> (lang dune 1.0)
> EOF
$ cat > dune << EOF
> (library
> (name l)
> (libraries stdune)
> (preprocess (pps ppx_expect))
> (inline_tests))
> EOF
$ cat > l.ml << EOF
> open[@ocaml.alert "-unstable"] Stdune
>
> let%expect_test _ =
> User_message.print (User_error.make []);
> [%expect]
> EOF
When running with `CLICOLOR_FORCE=0`, no escape codes are present in the output
string. But when it is set to `1`, escape codes are present.
Remarks:
- it is necessary to pipe into `tr` to see the difference because otherwise these
escape codes are stripped by cram, and it is necessary
- it is necessary to call `dune clean` because `dune` does not know that the
runtest depends on `CLICOLOR_FORCE`.
The expected outcome would be that both of these runs output the same corrected
file.
$ CLICOLOR_FORCE=0 dune runtest --auto-promote
File "l.ml", line 1, characters 0-0:
Error: Files _build/default/l.ml and _build/default/l.ml.corrected differ.
Promoting _build/default/l.ml.corrected to l.ml.
[1]
$ < l.ml tr '\033' '?'
open[@ocaml.alert "-unstable"] Stdune
let%expect_test _ =
User_message.print (User_error.make []);
[%expect {| Error: |}]
$ dune clean
$ CLICOLOR_FORCE=1 dune runtest --auto-promote
File "l.ml", line 1, characters 0-0:
Error: Files _build/default/l.ml and _build/default/l.ml.corrected differ.
Promoting _build/default/l.ml.corrected to l.ml.
[1]
$ < l.ml tr '\033' '?'
open[@ocaml.alert "-unstable"] Stdune
let%expect_test _ =
User_message.print (User_error.make []);
[%expect {| ?[1;31mError?[0m: |}]

View file

@ -0,0 +1,24 @@
$ cat >dune-project <<EOF
> (lang dune 2.6)
> EOF
$ cat >dune <<EOF
> (library
> (name backend_mbc1)
> (modules ())
> (inline_tests.backend
> (generate_runner (echo "print_endline \"backend_mbc1\""))))
>
> (library
> (name backend_mbc2)
> (modules ())
> (inline_tests.backend
> (generate_runner (echo "print_endline \"backend_mbc2\""))))
>
> (library
> (name foo_mbc)
> (inline_tests (backend backend_mbc1))
> (libraries backend_mbc1 backend_mbc2))
> EOF
$ dune runtest
backend_mbc1

View file

@ -0,0 +1,15 @@
$ cat >dune-project <<EOF
> (lang dune 2.6)
> EOF
$ cat >dune <<EOF
> (library
> (name foo_mb)
> (inline_tests))
> EOF
$ dune runtest
File "dune", line 3, characters 1-15:
3 | (inline_tests))
^^^^^^^^^^^^^^
Error: No inline tests backend found.
[1]

View file

@ -0,0 +1,31 @@
Test for multiple libraries with inline_tests set in the same directory
$ cat >dune-project <<EOF
> (lang dune 2.6)
> EOF
Create a dummy backend and two libraries with inline_tests
$ cat >dune <<EOF
> (library
> (name backend_simple)
> (modules ())
> (inline_tests.backend
> (generate_runner (echo "print_endline \"test\""))))
>
> (library
> (name foo_simple1)
> (modules ())
> (inline_tests (backend backend_simple)))
>
> (library
> (name foo_simple2)
> (modules ())
> (inline_tests (backend backend_simple)))
> EOF
try to run them:
$ env -u OCAMLRUNPARAM dune runtest
test
test

View file

@ -0,0 +1,19 @@
(library
(name fake_backend_1)
(modules ())
(inline_tests.backend
(runner_libraries fake_backend_runner)
(generate_runner (echo "let () = Fake_backend_runner.run ();;"))
(flags "--libname" %{library-name})))
(library
(name fake_backend_2)
(modules ())
(inline_tests.backend
(extends fake_backend_1)
(list_partitions_flags ("--libname" %{library-name} "--list-partitions"))
(flags ("--partition" %{partition}))))
(library
(name fake_backend_runner)
(modules fake_backend_runner))

View file

@ -0,0 +1,49 @@
module StringSet = Set.Make(String)
let usage_msg = ""
let list_partitions = ref false
let partition = ref ""
let libname = ref ""
let anon_fun _ = ()
let speclist =
[ ("--libname", Arg.Set_string libname, "libname")
; ("--partition", Arg.Set_string partition, "partition")
; ("--list-partitions", Arg.Set list_partitions, "list partitions")
]
type t =
{ libname : string
; partition : string
; name : string
; run : unit -> unit
}
let tests = ref []
let register ~libname ~partition name run =
tests := { libname; partition; name; run } :: !tests
let run () =
Arg.parse speclist anon_fun usage_msg;
if !libname = "" then failwith "Should specify libname";
if !list_partitions then
let partitions =
List.fold_left
(fun acc t -> if !libname = t.libname then StringSet.add t.partition acc else acc)
StringSet.empty !tests
in
StringSet.iter print_endline partitions;
List.iter
(fun t ->
if t.libname = !libname && t.partition = !partition then (
Printf.printf "Running %s\n" t.name;
try
t.run ();
Printf.printf "Ok\n"
with e -> Printf.printf "Error: %s\n" (Printexc.to_string e)))
(List.rev !tests)

View file

@ -0,0 +1,30 @@
First, build silently to avoid some noise
$ dune build
See that `test1/runtest`, which uses `fake_backend_1, only runs one inline test runner
$ dune build --display short @test1/runtest 2>&1 | grep alias
inline-test-runner alias test1/runtest-test_lib1
See that `test2/runtest`, which uses `fake_backend_2`, runs one inline test runner per partition
$ dune build --display short @test2/runtest 2>&1 | grep alias
inline-test-runner alias test2/runtest-test_lib2
inline-test-runner alias test2/runtest-test_lib2
inline-test-runner alias test2/runtest-test_lib2
See that we indeed have 3 partitions
$ cat _build/default/test2/.test_lib2.inline-tests/partitions-best
p1
p2
p3
$ dune build --display short @test3/runtest 2>&1 | grep alias
[1]
See that we have no partition.
$ cat _build/default/test3/.test_lib3.inline-tests/partitions-best

View file

@ -0,0 +1,4 @@
(library
(name test_lib1)
(libraries fake_backend_runner)
(inline_tests (backend fake_backend_1)))

View file

@ -0,0 +1,19 @@
let () =
Fake_backend_runner.register ~libname:"test_lib" ~partition:"p1" "first test"
(fun () -> assert true)
let () =
Fake_backend_runner.register ~libname:"test_lib" ~partition:"p1" "second test"
(fun () -> () )
let () =
Fake_backend_runner.register ~libname:"test_lib" ~partition:"p2" "first test"
(fun () -> ())
let () =
Fake_backend_runner.register ~libname:"test_lib" ~partition:"p3" "first test"
(fun () -> failwith "This failure is expected")
let () =
Fake_backend_runner.register ~libname:"other_lib" ~partition:"p1"
"second test" (fun () -> assert false)

View file

@ -0,0 +1,4 @@
(library
(name test_lib2)
(libraries fake_backend_runner)
(inline_tests (backend fake_backend_2)))

View file

@ -0,0 +1,23 @@
let () =
Fake_backend_runner.register ~libname:"test_lib2" ~partition:"p1" "first test"
(fun () -> assert true)
let () =
Fake_backend_runner.register ~libname:"test_lib2" ~partition:"p1" "second test"
(fun () -> () )
let () =
Fake_backend_runner.register ~libname:"test_lib2" ~partition:"p2" "first test"
(fun () -> ())
let () =
Fake_backend_runner.register ~libname:"test_lib2" ~partition:"p3" "first test"
(fun () -> failwith "This failure is expected")
let () =
Fake_backend_runner.register ~libname:"other_lib" ~partition:"p1"
"second test" (fun () -> assert false)
let () =
Fake_backend_runner.register ~libname:"other_lib" ~partition:"pn"
"second test" (fun () -> assert false)

View file

@ -0,0 +1,4 @@
(library
(name test_lib3)
(libraries fake_backend_runner)
(inline_tests (backend fake_backend_2)))

View file

@ -0,0 +1,3 @@
let () =
Fake_backend_runner.register ~libname:"other_lib" ~partition:"p1"
"second test" (fun () -> assert false)

View file

@ -0,0 +1,28 @@
Testing the interaction of reason syntax and ppx expect
$ cat > dune << EOF
> (library
> (name test)
> (inline_tests)
> (preprocess (pps ppx_expect)))
> EOF
$ cat > test.re << EOF
> let%expect_test _ =
> print_endline("Hello, world!");
> [%expect {| |}]
> EOF
In https://github.com/ocaml/dune/issues/7930 there is an issue where reason
syntax and ppx_expect break at dune lang 3.3 due to the sandboxing of ppx.
$ cat > dune-project << EOF
> (lang dune 3.9)
> EOF
$ dune test 2>&1 | head -n 6
File "dune", line 3, characters 1-15:
3 | (inline_tests)
^^^^^^^^^^^^^^
Fatal error: exception Invalid_argument("pos + len past end: 0 + 79 > 72")
Raised at Stdlib.invalid_arg in file "stdlib.ml", line 30, characters 20-45
Called from Base__Ordered_collection_common0.check_pos_len_exn in file "src/ordered_collection_common0.ml" (inlined), line 31, characters 7-53

View file

@ -0,0 +1,66 @@
$ cat >test.ml <<EOF
> (*TEST: assert (1 = 2) *)
> EOF
$ cat >dune-project <<EOF
> (lang dune 2.6)
> EOF
$ cat >dune <<EOF
> (library
> (name backend_simple)
> (modules ())
> (inline_tests.backend
> (generate_runner (run sed "s/(\\\\*TEST:\\\\(.*\\\\)\\\\*)/let () = if \\"%{inline_tests}\\" = \\"enabled\\" then \\\\1;;/" %{impl-files}))))
>
> (library
> (name foo_simple)
> (inline_tests (backend backend_simple)))
>
> (env
> (ignore-inline-tests (inline_tests ignored))
> (enable-inline-tests (inline_tests enabled))
> (disable-inline-tests (inline_tests disabled)))
> EOF
$ env -u OCAMLRUNPARAM dune runtest
File "dune", line 9, characters 1-40:
9 | (inline_tests (backend backend_simple)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fatal error: exception File ".foo_simple.inline-tests/main.ml-gen", line 1, characters 40-46: Assertion failed
[1]
Inline tests also generate an alias
$ dune build @runtest-foo_simple
File "dune", line 9, characters 1-40:
9 | (inline_tests (backend backend_simple)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fatal error: exception File ".foo_simple.inline-tests/main.ml-gen", line 1, characters 40-46: Assertion failed
[1]
Make sure building both aliases doesn't build both
$ dune build @runtest @lib-foo_simple
Error: Alias "lib-foo_simple" specified on the command line is empty.
It is not defined in . or any of its descendants.
File "dune", line 9, characters 1-40:
9 | (inline_tests (backend backend_simple)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fatal error: exception File ".foo_simple.inline-tests/main.ml-gen", line 1, characters 40-46: Assertion failed
[1]
This test demonstrates that the action is being run once
$ cat _build/log | sed 's/\$ //g' | grep inline-test-runner
(cd _build/default && .foo_simple.inline-tests/inline-test-runner.exe)
The expected behavior for the following three tests is to output nothing: the tests are disabled or ignored.
$ env -u OCAMLRUNPARAM dune runtest --profile release
$ env -u OCAMLRUNPARAM dune runtest --profile disable-inline-tests
$ env -u OCAMLRUNPARAM dune runtest --profile ignore-inline-tests
$ env -u OCAMLRUNPARAM dune runtest --profile enable-inline-tests
File "dune", line 9, characters 1-40:
9 | (inline_tests (backend backend_simple)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fatal error: exception File ".foo_simple.inline-tests/main.ml-gen", line 1, characters 40-46: Assertion failed
[1]

View file

@ -0,0 +1,30 @@
$ cat >dune-project <<EOF
> (lang dune 2.6)
> EOF
$ cat >dune <<EOF
> (library
> (name backend_tmb1)
> (modules ())
> (inline_tests.backend
> (generate_runner (echo foo))))
>
> (library
> (name backend_tmb2)
> (modules ())
> (inline_tests.backend
> (generate_runner (echo foo))))
>
> (library
> (name foo_tmb)
> (inline_tests)
> (libraries backend_tmb1 backend_tmb2))
> EOF
$ dune runtest
File "dune", line 15, characters 1-15:
15 | (inline_tests)
^^^^^^^^^^^^^^
Error: Too many independent inline tests backends found:
- "backend_tmb1" in _build/default
- "backend_tmb2" in _build/default
[1]