Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor(clerk): use ninja as backend to run tests #186

Merged
merged 44 commits into from
Mar 7, 2022

Conversation

EmileRolley
Copy link
Collaborator

@EmileRolley EmileRolley commented Jan 31, 2022

related issue: #181

Use ninja to run tests, following this steps:

  1. for each input, test files and scopes are retrieved,
  2. a Ninja_utils.ninja structure is built according to them,
  3. the corresponding build.ninja file is written,
  4. and finally, clerk runs ninja test.

Note: One requirement of Clerk is to be able to generate build.ninja files only if needed. This feature is not implemented by this PR, indeed, this will add complexity to the code and for the moment it will not be justified -- the generation time is insignificant.

Changelog

  • Clerk now uses ninja to perform the tests
  • New helper module Ninja_utils
  • Clerk now supports multiple input files/folders
  • Add an output flag for the build.ninja file
  • Add tests for the build system -- very minimal for now, see Clerk: improve the test suite #214
  • Add a basic README file
  • Fix the CI link in the main README file
  • (New ocamlformat rule: break-fun-decl = smart)?

Perfs

  • make tests without ninja takes ~6 seconds.
  • make tests with ninja takes ~2 seconds.

Screenshot

Screenshot from 2022-02-22 16-38-04

@EmileRolley EmileRolley added 🏗️ build system Build system or Makefile ✨ enhancement New feature or request labels Jan 31, 2022
  + ninja_utils.ml: implement helper functions for basic ninja rules and builds.
  + clerk.ml: for single test files, clerk now generates the wanted ninja.build file
    before executing ninja.
@EmileRolley
Copy link
Collaborator Author

@denismerigoux could you take a look to the CI please? I added ninja-build to the external dependencies of run-builds.yml but it doesn't seem to be enough...

@denismerigoux
Copy link
Contributor

Hi Émile, you can retry now, I manually installed the dependency on the runners.

@denismerigoux
Copy link
Contributor

The CI is still failing but that's on you I think, you forgot to supply the scope -s option to tests using the Dcalc backend.

@EmileRolley
Copy link
Collaborator Author

EmileRolley commented Feb 10, 2022

Thanks!

The CI is still failing but that's on you I think, you forgot to supply the scope -s option to tests using the Dcalc backend.

I don't get how the tested scope could be retrieved from the output files for the Dcalc backend...

After some investigations, I found that the error come from the last two lines:

in
TestBool_6

which are printed out when executing catala Dcalc tests/test_bool/good/test_bool.catala_en but aren't printed when specifying an output file with the -o flag.

Is it the wanted behavior?

@denismerigoux
Copy link
Contributor

The two line differences comes from this piece of code:

catala/compiler/driver.ml

Lines 198 to 211 in b6d9d7c

if backend = Cli.Dcalc then begin
let fmt, at_end =
match output_file with
| Some f ->
let oc = open_out f in
(Format.formatter_of_out_channel oc, fun _ -> close_out oc)
| None -> (Format.std_formatter, fun _ -> ())
in
if Option.is_some ex_scope then
Format.fprintf fmt "%a\n"
(Dcalc.Print.format_scope prgm.decl_ctx)
(let _, _, s = List.find (fun (name, _, _) -> name = scope_uid) prgm.scopes in
(scope_uid, s))
else Format.fprintf fmt "%a\n" (Dcalc.Print.format_expr prgm.decl_ctx) prgrm_dcalc_expr;

When you specify a scope to print with -s, it should only print that scope. If you don't specify a scope, it prints the whole program that includes those two lines at the end (the whole program is viewed as a value so you "return" a scope at the end). What I don't understand is why those two lines are not printed in the expected output, they should be there because we don't provide a -s option in this test... Maybe the standard output pipe to file was closed too early?

@denismerigoux
Copy link
Contributor

@EmileRolley
Copy link
Collaborator Author

Maybe try this https://gist.github.com/denismerigoux/b07dde85b34cffb7edb15e90446c60e3 ?

I tried, but the same problem occurred: for a same file, specifying the -o flag or not will produce different outputs...
More precisely, using Format.std_formatter or Format.formatter_of_out_channel Stdlib.stdout will not print the same result, which is not expected because the implementation of Format.std_formatter is exactly Format.formatter_of_out_channel Stdlib.stdout.
Could it be a version issue?

@denismerigoux
Copy link
Contributor

That's definitely weird. I'll take a deeper look at this on Monday and will debug it thoroughly. Meanwhile you can just ignore this error :)

@EmileRolley EmileRolley force-pushed the refactor-clerk-w-ninja branch 2 times, most recently from 1f6089e to 18e285e Compare February 24, 2022 21:17
	-> catch the Sys_error if the file can't be created.
@EmileRolley EmileRolley linked an issue Feb 28, 2022 that may be closed by this pull request
Changes in autoformatting should be made in a separate PR in a time where
there isn't too much pending PRs for the OCaml files
Copy link
Contributor

@denismerigoux denismerigoux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I have two questions before merging:

  1. Why all the empty files in build_system/tests/catala_files ? Can't we delete them if they are empty?

  2. When I run make tests on my machine I get the following error:

cd build_system && dune test
Entering directory '/home/demerigo/catala'
test_clerk_driver alias build_system/tests/runtest (exit 1)
(cd _build/default/build_system/tests && ./test_clerk_driver.exe)
Testing `Clerk_driver'.
This run has ID `QAIQYRY7'.

  [OK]          Test ninja_start              0   initial ninja rules should be present....
  [OK]          Test add_test_builds          0   an untested file.
  [OK]          Test add_test_builds          1   a simple Interpret scope....
> [FAIL]        Test add_test_builds          2   a simple folder....

┌──────────────────────────────────────────────────────────────────────────────┐
│ [FAIL]        Test add_test_builds          2   a simple folder.             │
└──────────────────────────────────────────────────────────────────────────────┘
ASSERT a test case should be found
ASSERT both formated strings should equal
FAIL both formated strings should equal

   Expected: `"build test_A_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en: test_with_scope\n  scope = A\n  catala_cmd = Interpret\n  tested_file = ../../../../build_system/tests/catala_files/folder/file1.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file1.catala_en.A.Interpret\nbuild test_B_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en: test_with_scope\n  scope = B\n  catala_cmd = Interpret\n  tested_file = ../../../../build_system/tests/catala_files/folder/file1.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file1.catala_en.B.Interpret\nbuild test_Proof_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en: test_without_scope\n  extra_flags = --disable_counterexamples\n  catala_cmd = Proof\n  tested_file = ../../../../build_system/tests/catala_files/folder/file3.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file3.catala_en.Proof\nbuild test_Typecheck_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en: test_without_scope\n  catala_cmd = Typecheck\n  tested_file = ../../../../build_system/tests/catala_files/folder/file2.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file2.catala_en.Typecheck\nbuild test_dir_..-..-..-..-build_system-tests-catala_files-folder: run_and_display_final_message  $\n  test_file_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en $\n  test_file_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en $\n  test_file_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en\n  test_file_or_folder = in folder '../../../../build_system/tests/catala_files/folder'\nbuild test_file_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en: phony  $\n  test_B_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en $\n  test_A_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en\nbuild test_file_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en: phony  $\n  test_Typecheck_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en\nbuild test_file_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en: phony  $\n  test_Proof_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en\n"'

   Received: `"build test_A_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en: test_with_scope\n  scope = A\n  catala_cmd = Interpret\n  tested_file = ../../../../build_system/tests/catala_files/folder/file1.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file1.catala_en.A.Interpret\nbuild test_B_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en: test_with_scope\n  scope = B\n  catala_cmd = Interpret\n  tested_file = ../../../../build_system/tests/catala_files/folder/file1.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file1.catala_en.B.Interpret\nbuild test_Proof_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en: test_without_scope\n  extra_flags = --disable_counterexamples\n  catala_cmd = Proof\n  tested_file = ../../../../build_system/tests/catala_files/folder/file3.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file3.catala_en.Proof\nbuild test_Typecheck_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en: test_without_scope\n  catala_cmd = Typecheck\n  tested_file = ../../../../build_system/tests/catala_files/folder/file2.catala_en\n  expected_output = ../../../../build_system/tests/catala_files/folder/output/file2.catala_en.Typecheck\nbuild test_dir_..-..-..-..-build_system-tests-catala_files-folder: run_and_display_final_message  $\n  test_file_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en $\n  test_file_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en $\n  test_file_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en\n  test_file_or_folder = in folder '../../../../build_system/tests/catala_files/folder'\nbuild test_file_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en: phony  $\n  test_A_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en $\n  test_B_Interpret_..-..-..-..-build_system-tests-catala_files-folder-file1.catala_en\nbuild test_file_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en: phony  $\n  test_Typecheck_..-..-..-..-build_system-tests-catala_files-folder-file2.catala_en\nbuild test_file_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en: phony  $\n  test_Proof_..-..-..-..-build_system-tests-catala_files-folder-file3.catala_en\n"'

Raised at Alcotest_engine__Test.check in file "src/alcotest-engine/test.ml", line 196, characters 4-261
Called from Alcotest_engine__Core.Make.protect_test.(fun) in file "src/alcotest-engine/core.ml", line 180, characters 17-23
Called from Alcotest_engine__Monad.Identity.catch in file "src/alcotest-engine/monad.ml", line 24, characters 31-35

Logs saved to `~/catala/_build/default/build_system/tests/_build/_tests/Clerk_driver/Test add_test_builds.002.output'.
 ──────────────────────────────────────────────────────────────────────────────

Full test results in `~/catala/_build/default/build_system/tests/_build/_tests/Clerk_driver'.
1 failure! in 0.001s. 4 tests run.

However the CI is green; do you know what is happening?

@EmileRolley
Copy link
Collaborator Author

EmileRolley commented Mar 7, 2022

  1. Why all the empty files in build_system/tests/catala_files ? Can't we delete them if they are empty?

They are used in tests to verify that Clerk correctly founds all Catala scopes and backends from filenames.

  1. When I run make tests on my machine I get the following error:

It's really weird because both strings seem to be equal, and the test pass on my machine 🤔

@denismerigoux denismerigoux merged commit 9d5e8e4 into CatalaLang:master Mar 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏗️ build system Build system or Makefile ✨ enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Base the Clerk build system on Ninja
2 participants