Skip to content

Commit fcd9c8d

Browse files
committed
fix: dune test dirtest.t/run.t running cram test incorrectly
We fix an issue where a user can write ``` dune test dirtest.t/run.t ``` and the corresponding cram test was being run incorrectly. This was due to the buggy parent detection code in runtest.ml. We fix how the parent directory of a cram test is actually detected and do some cleanup for cram source related code. The runtest.ml test is updated to better reflect what we expect the command to do. Signed-off-by: Ali Caglayan <[email protected]>
1 parent 02f3995 commit fcd9c8d

File tree

4 files changed

+67
-42
lines changed

4 files changed

+67
-42
lines changed

bin/runtest.ml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ let runtest_info =
3333
;;
3434

3535
let find_cram_test path ~parent_dir =
36+
(* We correct the [path] and [parent_dir] if we have a directory test and the
37+
user has given a path to "run.t" rather than the directory cram test itself. *)
38+
let path, parent_dir =
39+
Option.value ~default:(path, parent_dir)
40+
@@
41+
let open Option.O in
42+
let* basename = Path.Source.basename_opt path in
43+
if String.equal basename Source.Cram_test.fname_in_dir_test
44+
then
45+
let* parent_dir_of_run = Path.Source.parent path in
46+
let+ parent_dir = Path.Source.parent parent_dir_of_run in
47+
parent_dir_of_run, parent_dir
48+
else None
49+
in
3650
let open Memo.O in
3751
Source_tree.nearest_dir parent_dir
3852
>>= Dune_rules.Cram_rules.cram_tests
@@ -42,13 +56,11 @@ let find_cram_test path ~parent_dir =
4256
>>| List.filter_map ~f:Result.to_option
4357
(* We search our list of known cram tests for the test we are looking
4458
for. *)
45-
>>| List.find ~f:(fun (test : Source.Cram_test.t) ->
46-
let src =
47-
match test with
48-
| File src -> src
49-
| Dir { dir = src; _ } -> src
50-
in
51-
Path.Source.equal path src)
59+
>>| List.find_map ~f:(fun (test : Source.Cram_test.t) ->
60+
let open Option.O in
61+
let* cram_basename = Source.Cram_test.path test |> Path.Source.basename_opt in
62+
let* basename = Path.Source.basename_opt path in
63+
Option.some_if (Filename.equal cram_basename basename) (test, parent_dir))
5264
;;
5365

5466
let explain_unsuccessful_search path ~parent_dir =
@@ -92,7 +104,7 @@ let disambiguate_test_name path =
92104
let open Memo.O in
93105
find_cram_test path ~parent_dir
94106
>>= (function
95-
| Some test ->
107+
| Some (test, parent_dir) ->
96108
(* If we find the cram test, then we request that is run. *)
97109
Memo.return (`Test (parent_dir, Source.Cram_test.name test))
98110
| None ->

src/source/cram_test.ml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ type t =
77
; dir : Path.Source.t
88
}
99

10-
let is_cram_suffix = String.is_suffix ~suffix:".t"
10+
let fname_in_dir_test = "run.t"
11+
let suffix = ".t"
12+
let is_cram_suffix = String.is_suffix ~suffix
1113

12-
let dyn_of_t =
14+
let to_dyn =
1315
let open Dyn in
1416
function
1517
| File f -> variant "File" [ Path.Source.to_dyn f ]
@@ -19,19 +21,17 @@ let dyn_of_t =
1921
[ record [ "file", Path.Source.to_dyn file; "dir", Path.Source.to_dyn dir ] ]
2022
;;
2123

24+
let path = function
25+
| File file -> file
26+
| Dir d -> d.dir
27+
;;
28+
2229
let name t =
23-
String.drop_suffix
24-
~suffix:".t"
25-
(match t with
26-
| File file -> Path.Source.basename file
27-
| Dir { file = _; dir } -> Path.Source.basename dir)
28-
|> Option.value_exn
30+
path t |> Path.Source.basename |> String.drop_suffix ~suffix |> Option.value_exn
2931
;;
3032

3133
let script t =
3234
match t with
3335
| File f -> f
3436
| Dir d -> d.file
3537
;;
36-
37-
let fname_in_dir_test = "run.t"

src/source/cram_test.mli

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,31 @@
11
open Import
22

3+
(** [t] represents the source file associated to a cram test. *)
34
type t =
45
| File of Path.Source.t
56
| Dir of
67
{ file : Path.Source.t
78
; dir : Path.Source.t
89
}
910

10-
val is_cram_suffix : string -> bool
11-
val dyn_of_t : t -> Dyn.t
12-
val name : t -> string
11+
val to_dyn : t -> Dyn.t
12+
13+
(** Checks if a filename has the ".t" suffix for a cram test. *)
14+
val is_cram_suffix : Filename.t -> bool
15+
16+
(** The "run.t" filename for directory cram tests. *)
1317
val fname_in_dir_test : Filename.t
18+
19+
(** The [name] of a cram test. If this is a file test, then it will be the file
20+
name without the cram suffix. If this is a directory test, then it will be
21+
the directory name without the cram suffix. *)
22+
val name : t -> string
23+
24+
(** The [path] associated to a cram test. If this is a file test, then it will
25+
be the file. If this is a directory test, then it will be the directory. *)
26+
val path : t -> Path.Source.t
27+
28+
(** The [script] of a cram test. If this is a file test, then it will be the
29+
file. If this is a directory test, then it will be the "run.t" file inside
30+
that directory. *)
1431
val script : t -> Path.Source.t

test/blackbox-tests/test-cases/runtest-cmd.t

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,54 +6,50 @@ Here we test the features of the `dune runtest` command.
66

77
$ cat > mytest.t <<EOF
88
> $ echo "Hello, world!"
9-
> "Goodbye, world!"
9+
> "Goodbye, world!"
1010
> EOF
1111
$ mkdir -p tests/myothertest.t
1212
$ echo 'Hello, world!' > tests/myothertest.t/hello.world
1313
$ cat > tests/myothertest.t/run.t <<EOF
1414
> $ cat hello.world
15-
> "Goodbye, world!"
15+
> "Goodbye, world!"
1616
> EOF
1717
$ cat > tests/filetest.t <<EOF
1818
> $ echo "Hello, world!"
19-
> "Goodbye, world!"
19+
> "Goodbye, world!"
2020
> EOF
2121

22-
2322
This should work:
2423

2524
$ dune test tests/myothertest.t
2625
File "tests/myothertest.t/run.t", line 1, characters 0-0:
2726
Error: Files _build/default/tests/myothertest.t/run.t and
2827
_build/default/tests/myothertest.t/run.t.corrected differ.
2928
[1]
30-
31-
There's no diff produced because the test passes
32-
3329
$ dune promotion diff tests/myothertest.t/run.t
3430

35-
This should not work
36-
37-
$ dune test myotherttest.t
38-
Error: "myotherttest.t" does not match any known test.
39-
[1]
31+
We use the promotion diff to make sure that a promotion is being registered. If
32+
there is no promotion it will warn.
4033

41-
This is a bug. Running the test this way does not correctly include the
42-
dependencies.
34+
If the user writes the run.t file of a directory test, we should correct it to
35+
be the corresponding directory cram test.
4336

4437
$ dune test tests/myothertest.t/run.t
4538
File "tests/myothertest.t/run.t", line 1, characters 0-0:
4639
Error: Files _build/default/tests/myothertest.t/run.t and
4740
_build/default/tests/myothertest.t/run.t.corrected differ.
4841
[1]
49-
5042
$ dune promotion diff tests/myothertest.t/run.t
5143

52-
$ cat _build/.promotion-staging/tests/myothertest.t/run.t
53-
$ cat hello.world
54-
cat: hello.world: No such file or directory
55-
[1]
56-
"Goodbye, world!"
44+
We cannot give the name of a cram test in a subdirectory and expect Dune to
45+
find it.
46+
47+
$ dune test myothertest.t
48+
Error: "myothertest.t" does not match any known test.
49+
[1]
50+
51+
$ dune promotion diff tests/myothertest.t/run.t
52+
Warning: Nothing to promote for tests/myothertest.t/run.t.
5753

5854
Passing no arguments to $ dune runtest should be equivalent to $ dune build
5955
@runtest.
@@ -128,7 +124,7 @@ messages are informative enough.
128124
Error: "testt" does not match any known test.
129125
Hint: did you mean tests?
130126
[1]
131-
- Note that this doesn't handle the case where the path is mostly correct but
127+
- Note that this does not handle the case where the path is mostly correct but
132128
the directory is mispelled.
133129
$ dune test testss/myothertest.t
134130
Error: "testss/myothertest.t" does not match any known test.

0 commit comments

Comments
 (0)