Skip to content

Commit

Permalink
Implement a Fuzzy CI to catch regressions
Browse files Browse the repository at this point in the history
This commit implements a Fuzzy CI to catch end-to-end regressions in Merlin
by checking the responses of a set of ocamlmerlin queries. That set of
queries is determined by a deterministic but randomly chosen set of file
location samples on the Irmin code base. The CI passes automatically if the
responses on all samples remain the same before and after the PR. If there's a
diff in the responses, the CI fails and makes the diff available as a GH action
artifact.

There's a high-level description of the CI in much more detail on
https://github.com/ocaml/merlin/wiki/Merlin-Fuzzy-CI.

Co-authored-by: Enguerrand Decorne <[email protected]>
  • Loading branch information
pitag-ha and abbysmal committed Jan 9, 2024
1 parent b3a9476 commit 842515e
Show file tree
Hide file tree
Showing 3 changed files with 555 additions and 1 deletion.
45 changes: 45 additions & 0 deletions .github/fuzzy-ci-helpers/create_diff.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
type read_result = Success | Eof

let read_line_opt () = try Some (read_line ()) with End_of_file -> None
let delimiter1 = Sys.argv.(1)
let delimiter2 = Sys.argv.(2)
let diff_file = Sys.argv.(3)

let rec loop () =
let rec stdin_to_file ~until file_oc =
match read_line_opt () with
| None -> Eof
| Some line ->
if String.equal line until then Success
else (
output_string file_oc (line ^ "\n");
stdin_to_file ~until file_oc)
in
let label1 = read_line_opt () in
let tmp1 = Filename.temp_file "tmp1" "" in
let oc = open_out tmp1 in
let read_result1 = stdin_to_file ~until:delimiter1 oc in
close_out oc;
let label2 = read_line_opt () in
let tmp2 = Filename.temp_file "tmp2" "" in
let oc = open_out tmp2 in
let read_result2 = stdin_to_file ~until:delimiter2 oc in
close_out oc;
match (label1, read_result1, label2, read_result2) with
| Some label1, Success, Some label2, Success ->
let diff_cmd =
Printf.sprintf
"diff -U 5 --label=\"%s\" --label=\"%s\" \"%s\" \"%s\" >> %s" label1
label2 tmp1 tmp2 diff_file
in
let _ = Sys.command diff_cmd in
loop ()
| Some _, Success, Some _, Eof ->
raise (Failure "EOF before reaching delimiter2 when reading second JSON.")
| Some _, Success, None, _ ->
raise (Failure "EOF before reaching delimiter2 when second label.")
| Some _, Eof, _, _ ->
raise (Failure "EOF before reaching delimiter1 when reading first JSON.")
| None, _, _, _ -> ()

let () = loop ()
Loading

0 comments on commit 842515e

Please sign in to comment.