From 6a205bc949273ffb417915228f7ae8f373b87803 Mon Sep 17 00:00:00 2001 From: Romain Bardou Date: Thu, 2 Jun 2022 14:15:02 +0200 Subject: [PATCH 1/8] Manifest: fix comment --- manifest/manifest.mli | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manifest/manifest.mli b/manifest/manifest.mli index 23c19b16e73e..d457b1e16634 100644 --- a/manifest/manifest.mli +++ b/manifest/manifest.mli @@ -796,9 +796,9 @@ val tests : [npm_deps]: npm dependencies used when targeting JavaScript. - [released_on_opam]: whether the library is available on the upstream opam-repository (default true). - In case the lib is not available on opam, tezos packages depending on it won't be installable on opam. - *) + [released_on_opam]: whether the library is available on the upstream opam-repository + (default true). In case the lib is not available on opam, tezos packages depending + on it won't be installable on opam. *) val vendored_lib : ?released_on_opam:bool -> ?main_module:string -> -- GitLab From 602978b427956e657015fbb79db8b3debc11f768 Mon Sep 17 00:00:00 2001 From: Romain Bardou Date: Thu, 2 Jun 2022 17:50:07 +0200 Subject: [PATCH 2/8] Scripts: fix snapshot_alpha.sh for files with spaces --- scripts/snapshot_alpha.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/snapshot_alpha.sh b/scripts/snapshot_alpha.sh index 697fedf9cd03..d8c60df68923 100755 --- a/scripts/snapshot_alpha.sh +++ b/scripts/snapshot_alpha.sh @@ -211,10 +211,13 @@ cd lib_protocol sed -i.old -e 's/"hash": "[^"]*",/"hash": "'$long_hash'",/' \ TEZOS_PROTOCOL -sed -i.old -e s/protocol_alpha/protocol_${version}_${short_hash}/ \ - -e s/protocol-alpha/protocol-${version}-${short_hash}/ \ - -e s/protocol-functor-alpha/protocol-functor-${version}-${short_hash}/ \ - $(find . -type f) +# We use -exec instead of just passing the result of find to sed in order +# to support spaces in filenames. +find . -type f -exec \ + sed -i.old -e s/protocol_alpha/protocol_${version}_${short_hash}/ \ + -e s/protocol-alpha/protocol-${version}-${short_hash}/ \ + -e s/protocol-functor-alpha/protocol-functor-${version}-${short_hash}/ \ + {} \; # add this protocol to the immutable list printf \\n$long_hash >> ../../lib_protocol_compiler/final_protocol_versions -- GitLab From 37d3122ad6d668ea92f5e030b552259d1d9e10f6 Mon Sep 17 00:00:00 2001 From: Romain Bardou Date: Fri, 3 Jun 2022 15:07:24 +0200 Subject: [PATCH 3/8] Tezt: add ?file to Regression.register --- tezt/lib/regression.ml | 35 +++++++++++++++++++---------------- tezt/lib/regression.mli | 6 ++++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/tezt/lib/regression.ml b/tezt/lib/regression.ml index 93483bd1d4ab..c257153d6082 100644 --- a/tezt/lib/regression.ml +++ b/tezt/lib/regression.ml @@ -88,7 +88,7 @@ let log_regression_diff diff = In the map, output files can be in subdirectories (i.e. they can contain '/'). *) let output_dirs_and_files : String_set.t String_map.t ref = ref String_map.empty -let register ~__FILE__ ~title ~tags f = +let register ~__FILE__ ~title ~tags ?file f = let tags = "regression" :: tags in let output_dir = let project_root = @@ -107,22 +107,25 @@ let register ~__FILE__ ~title ~tags f = project_root // Filename.dirname __FILE__ // "expected" in let relative_output_file = - let sanitized_title = - (* We exclude ':' because of Windows. *) - let sanitize_char = function - | ( 'a' .. 'z' - | 'A' .. 'Z' - | '0' .. '9' - | '_' | '-' | '.' | ' ' | '(' | ')' ) as x -> - x - | _ -> '-' - in - let full = String.map sanitize_char title in - let max_length = 80 in - if String.length full > max_length then String.sub full 0 max_length - else full + let file = + match file with + | Some file -> file + | None -> + (* Sanitize title. We exclude ':' because of Windows. *) + let sanitize_char = function + | ( 'a' .. 'z' + | 'A' .. 'Z' + | '0' .. '9' + | '_' | '-' | '.' | ' ' | '(' | ')' ) as x -> + x + | _ -> '-' + in + let full = String.map sanitize_char title in + let max_length = 80 in + if String.length full > max_length then String.sub full 0 max_length + else full in - Filename.basename __FILE__ // (sanitized_title ^ ".out") + Filename.basename __FILE__ // (file ^ ".out") in let old_relative_output_files = String_map.find_opt output_dir !output_dirs_and_files diff --git a/tezt/lib/regression.mli b/tezt/lib/regression.mli index 1b1800e2b809..f39c2d9995d0 100644 --- a/tezt/lib/regression.mli +++ b/tezt/lib/regression.mli @@ -36,16 +36,18 @@ to the [tags] list provided by the argument. Output which is captured (with {!capture}) is recorded in a file named - [//expected//.out] where: + [<ROOT>/<DIR>/expected/<BASE>/<FILE>.out] where: - [<ROOT>] is the root directory of the project, read from environment variable [DUNE_SOURCEROOT] if available, else [PWD] if available, else using [Sys.getcwd]; - [<DIR>] is [Filename.dirname __FILE__]; - [<BASE>] is [Filename.basename __FILE__]; - - [<TITLE>] is a sanitized and possibly truncated version of [~title]. *) + - [<FILE>] is [~file], which defaults to a sanitized and possibly truncated + version of [~title]. *) val register : __FILE__:string -> title:string -> tags:string list -> + ?file:string -> (unit -> unit Lwt.t) -> unit -- GitLab From e5e807b8e6abee0430ba087f43c6908b82d48de3 Mon Sep 17 00:00:00 2001 From: Romain Bardou <romain@nomadic-labs.com> Date: Thu, 2 Jun 2022 15:00:42 +0200 Subject: [PATCH 4/8] Tezt: expose Base.project_root --- tezt/lib/base.ml | 13 +++++++++++++ tezt/lib/base.mli | 7 +++++++ tezt/lib/regression.ml | 17 +---------------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/tezt/lib/base.ml b/tezt/lib/base.ml index b0f701215076..aa81dfac2392 100644 --- a/tezt/lib/base.ml +++ b/tezt/lib/base.ml @@ -207,3 +207,16 @@ module String_set = struct (fun fmt -> Format.fprintf fmt "%S")) (elements set) end + +let project_root = + match Sys.getenv_opt "DUNE_SOURCEROOT" with + | Some x -> x + | None -> ( + match Sys.getenv_opt "PWD" with + | Some x -> x + | None -> + (* For some reason, under [dune runtest], [PWD] and + [getcwd] have different values. [getcwd] is in + [_build/default], and [PWD] is where [dune runtest] was + executed, which is closer to what we want. *) + Sys.getcwd ()) diff --git a/tezt/lib/base.mli b/tezt/lib/base.mli index 70584eff245e..9df58e82380d 100644 --- a/tezt/lib/base.mli +++ b/tezt/lib/base.mli @@ -176,3 +176,10 @@ module String_set : sig and the result is surrounded by braces. *) val pp : Format.formatter -> t -> unit end + +(** {2 Environment} *) + +(** Path to the root of the project. + + This is [DUNE_SOURCEROOT] is defined, [PWD] otherwise. *) +val project_root : string diff --git a/tezt/lib/regression.ml b/tezt/lib/regression.ml index c257153d6082..2ca0d4fb4512 100644 --- a/tezt/lib/regression.ml +++ b/tezt/lib/regression.ml @@ -90,22 +90,7 @@ let output_dirs_and_files : String_set.t String_map.t ref = ref String_map.empty let register ~__FILE__ ~title ~tags ?file f = let tags = "regression" :: tags in - let output_dir = - let project_root = - match Sys.getenv_opt "DUNE_SOURCEROOT" with - | Some x -> x - | None -> ( - match Sys.getenv_opt "PWD" with - | Some x -> x - | None -> - (* For some reason, under [dune runtest], [PWD] and - [getcwd] have different values. [getcwd] is in - [_build/default], and [PWD] is where [dune runtest] was - executed, which is closer to what we want. *) - Sys.getcwd ()) - in - project_root // Filename.dirname __FILE__ // "expected" - in + let output_dir = project_root // Filename.dirname __FILE__ // "expected" in let relative_output_file = let file = match file with -- GitLab From fdaebbd7fe1df39a98ddf390aa1225fe291033cd Mon Sep 17 00:00:00 2001 From: Romain Bardou <romain@nomadic-labs.com> Date: Thu, 28 Apr 2022 15:46:07 +0200 Subject: [PATCH 5/8] Manifest: rename tezt into tezt_lib --- manifest/main.ml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/manifest/main.ml b/manifest/main.ml index e98ff1075674..68a490c7043f 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -2645,7 +2645,7 @@ let tezos_shell_benchmarks = ] ~linkall:true -let tezt = +let tezt_lib = public_lib "tezt" ~path:"tezt/lib" @@ -2661,7 +2661,7 @@ let tezt_performance_regression = ~path:"tezt/lib_performance_regression" ~synopsis:"Performance regression test framework based on Tezt" ~bisect_ppx:false - ~deps:[tezt |> open_ |> open_ ~m:"Base"; uri; cohttp_lwt_unix] + ~deps:[tezt_lib |> open_ |> open_ ~m:"Base"; uri; cohttp_lwt_unix] let tezt_tezos = public_lib @@ -2671,7 +2671,7 @@ let tezt_tezos = ~bisect_ppx:false ~deps: [ - tezt |> open_ |> open_ ~m:"Base"; + tezt_lib |> open_ |> open_ ~m:"Base"; tezt_performance_regression |> open_; uri; hex; @@ -2689,7 +2689,7 @@ let _tezt_self_tests = ~synopsis:"Tests for the Tezos test framework based on Tezt" ~bisect_ppx:false ~static:false - ~deps:[tezt |> open_ |> open_ ~m:"Base"; tezt_tezos |> open_] + ~deps:[tezt_lib |> open_ |> open_ ~m:"Base"; tezt_tezos |> open_] ~cram:true ~dune: Dune. @@ -2708,7 +2708,7 @@ let tezos_openapi = ~synopsis: "Tezos: a library for querying RPCs and converting into the OpenAPI \ format" - ~deps:[ezjsonm; json_data_encoding; tezt] + ~deps:[ezjsonm; json_data_encoding; tezt_lib] let _tezos_protocol_compiler_bin = public_exe @@ -3203,7 +3203,7 @@ end = struct ~opam:(sf "tezos-protocol-%s-tests" name_dash) ~deps: [ - tezt; + tezt_lib; tezos_base |> open_ ~m:"TzPervasives"; main |> open_; client |> if_some |> open_; @@ -4990,7 +4990,7 @@ let _tezos_tps_evaluation = Protocol.(client_commands_exn alpha); tezos_client_base_unix; Protocol.(main alpha); - tezt |> open_ |> open_ ~m:"Base"; + tezt_lib |> open_ |> open_ ~m:"Base"; tezt_tezos |> open_; tezt_performance_regression |> open_; uri; -- GitLab From 512a5c17b692ec29bd57eb733fc281a9ecd3d95d Mon Sep 17 00:00:00 2001 From: Romain Bardou <romain@nomadic-labs.com> Date: Fri, 13 May 2022 14:28:23 +0200 Subject: [PATCH 6/8] Manifest: be able to specify runtest alias --- manifest/main.ml | 12 ++--- manifest/manifest.ml | 115 +++++++++++++++++++++++++++++------------- manifest/manifest.mli | 8 +-- 3 files changed, 89 insertions(+), 46 deletions(-) diff --git a/manifest/main.ml b/manifest/main.ml index 68a490c7043f..ad31bfca2d73 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1276,7 +1276,7 @@ let _tezos_tooling_opam_file_format = let _tezos_tooling_opam_lint = test "opam_lint" - ~runtest:false + ~alias:"" ~path:"src/tooling/opam-lint" ~opam:"tezos-tooling" ~deps:[_tezos_tooling_opam_file_format; unix] @@ -1332,7 +1332,7 @@ let _tezos_p2p_tests = astring; ] ~linkall:true - ~runtest:false + ~alias:"" ~dune: Dune.( (* At the termination of the tests, or if an unexpected @@ -3167,7 +3167,7 @@ end = struct "main" ~path:(path // "lib_protocol/test/unit") ~opam:(sf "tezos-protocol-%s-tests" name_dash) - ~runtest:false + ~alias:"" ~deps: [ tezos_base |> open_ ~m:"TzPervasives" @@ -3936,7 +3936,7 @@ include Tezos_raw_protocol_%s.Main some_if (active && N.(number >= 013)) @@ fun () -> test "tenderbrute_main" - ~runtest:false + ~alias:"" ~path:(path // "lib_delegate/test/tenderbrute") ~opam:(sf "tezos-baking-%s" name_dash) ~deps: @@ -4347,7 +4347,7 @@ include Tezos_raw_protocol_%s.Main alcotest_lwt; prbnmcn_stats; ] - ~runtest:false + ~alias:"" ~dune: Dune. [ @@ -4519,7 +4519,7 @@ let _tezos_store_tests = tezos_test_helpers; tezos_test_helpers_extra; ] - ~runtest:false + ~alias:"" ~dune: (* [test_slow_manual] is a very long test, running a huge combination of tests that are useful for local testing for a diff --git a/manifest/manifest.ml b/manifest/manifest.ml index 4429e702181c..b773c6e77337 100644 --- a/manifest/manifest.ml +++ b/manifest/manifest.ml @@ -315,10 +315,10 @@ module Dune = struct let run_exe exe_name args = run ("%{exe:" ^ exe_name ^ ".exe}") args - let runtest_js ~package ~dep_files name = + let runtest_js ?(alias = "runtest_js") ?package ~dep_files name = alias_rule - "runtest_js" - ~package + alias + ?package ~deps:dep_files ~action:[S "run"; S "node"; S ("%{dep:./" ^ name ^ ".bc.js}")] @@ -326,15 +326,15 @@ module Dune = struct let glob_files expr = [S "glob_files"; S expr] - let runtest ~package ~dep_files ~dep_globs name = + let runtest ?(alias = "runtest") ?package ~dep_files ~dep_globs name = let deps_dune = let files = List.map (fun s -> S s) dep_files in let globs = List.map glob_files dep_globs in match files @ globs with [] -> None | deps -> Some (of_list deps) in alias_rule - "runtest" - ~package + alias + ?package ?deps_dune ~action:[S "run"; S ("%{dep:./" ^ name ^ ".exe}")] @@ -875,7 +875,10 @@ module Target = struct | Private_library of string | Public_executable of full_name Ne_list.t | Private_executable of string Ne_list.t - | Test_executable of {names : string Ne_list.t; run : bool} + | Test_executable of { + names : string Ne_list.t; + runtest_alias : string option; + } type preprocessor_dep = File of string @@ -1150,7 +1153,7 @@ module Target = struct match opam with | Some "" -> ( match kind with - | Test_executable {names = name, _; run = true; _} -> + | Test_executable {names = name, _; runtest_alias = Some _; _} -> invalid_argf "for targets which provide test executables such as %S, you \ must specify a non-empty ~opam or have it not run by default \ @@ -1165,7 +1168,7 @@ module Target = struct "for targets which provide public executables such as %S, you \ cannot have ~opam set to empty string (\"\")" public_name - | Test_executable {run = false; _} + | Test_executable {runtest_alias = None; _} | Private_library _ | Private_executable _ -> None) | Some opam as x -> @@ -1287,27 +1290,33 @@ module Target = struct | Some modes -> List.mem Dune.Native modes in match (kind, opam, dep_files) with - | Test_executable {names; run = true}, Some package, _ -> + | Test_executable {names; runtest_alias = Some alias}, package, _ -> let runtest_js_rules = if run_js then List.map - (fun name -> Dune.(runtest_js ~dep_files ~package name)) + (fun name -> + Dune.runtest_js + ~alias:(alias ^ "_js") + ~dep_files + ?package + name) (Ne_list.to_list names) else [] in let runtest_rules = if run_native then List.map - (fun name -> Dune.(runtest ~dep_files ~dep_globs ~package name)) + (fun name -> + Dune.runtest ~alias ~dep_files ~dep_globs ?package name) (Ne_list.to_list names) else [] in runtest_rules @ runtest_js_rules - | Test_executable {names = name, _; run = false; _}, _, _ :: _ -> + | Test_executable {names = name, _; runtest_alias = None}, _, _ :: _ -> invalid_argf - "for targets which provide test executables such as %S, \ - [~dep_files] is only meaningful for runtest alias. It cannot be \ - used together with [runtest:false]" + "for targets which provide test executables such as %S, ~dep_files \ + is only meaningful for the runtest alias. It cannot be used with \ + no alias, i.e. ~alias:\"\"." name | _, _, _ :: _ -> assert false | _ -> [] @@ -1406,15 +1415,17 @@ module Target = struct | [] -> invalid_argf "Target.private_exes: at least one name must be given" | head :: tail -> Private_executable (head, tail) - let test ?dep_files ?dep_globs ?(runtest = true) = + let test ?(alias = "runtest") ?dep_files ?dep_globs = + let runtest_alias = if alias = "" then None else Some alias in internal ?dep_files ?dep_globs @@ fun test_name -> - Test_executable {names = (test_name, []); run = runtest} + Test_executable {names = (test_name, []); runtest_alias} - let tests ?dep_files ?dep_globs ?(runtest = true) = + let tests ?(alias = "runtest") ?dep_files ?dep_globs = + let runtest_alias = if alias = "" then None else Some alias in internal ?dep_files ?dep_globs @@ fun test_names -> match test_names with | [] -> invalid_arg "Target.tests: at least one name must be given" - | head :: tail -> Test_executable {names = (head, tail); run = runtest} + | head :: tail -> Test_executable {names = (head, tail); runtest_alias} let vendored_lib ?(released_on_opam = true) ?main_module ?(js_compatible = false) ?(npm_deps = []) name = @@ -1720,8 +1731,8 @@ let generate_dune ~dune_file_has_static_profile (internal : Target.internal) = | Test_executable _, Some _ -> (* private executable can't have a package stanza, but we still want the manifest to know about the package *) None - | Test_executable {run = false; _}, None -> None - | Test_executable {run = true; _}, None -> + | Test_executable {runtest_alias = None; _}, None -> None + | Test_executable {runtest_alias = Some _; _}, None -> (* Prevented by [Target.internal]. *) assert false in @@ -2033,23 +2044,55 @@ let generate_opam ?release for_package (internals : Target.internal list) : with_test = Never; } in - let runtest with_test : Opam.build_instruction list = - match with_test with - | Never -> [] - | _ -> - [ - { - command = - [S "dune"; S "runtest"; S "-p"; A "name"; S "-j"; A "jobs"]; - with_test; - }; - ] - in let with_test = match internals with [] -> Never | head :: _ -> head.opam_with_test in - [{Opam.command = [S "rm"; S "-r"; S "vendors"]; with_test = Never}; build] - @ runtest with_test + let runtests = + let get_alias (internal : Target.internal) = + match internal.kind with + | Test_executable {runtest_alias; _} -> runtest_alias + | Public_library _ | Private_library _ | Public_executable _ + | Private_executable _ -> + None + in + let make_runtest alias : Opam.build_instruction list = + match (with_test, alias) with + | Never, _ -> [] + | _, "runtest" -> + (* Special case: Dune has a special command to run this alias. *) + [ + { + command = + [S "dune"; S "runtest"; S "-p"; A "name"; S "-j"; A "jobs"]; + with_test; + }; + ] + | _ -> + [ + { + command = + [ + S "dune"; + S "build"; + S ("@" ^ alias); + S "-p"; + A "name"; + S "-j"; + A "jobs"; + ]; + with_test; + }; + ] + in + internals |> List.filter_map get_alias + (* We have to add [runtest] because some targets define the [runtest] + alias manually and use [~alias:""]. *) + |> (fun l -> "runtest" :: l) + |> String_set.of_list |> String_set.elements + |> List.concat_map make_runtest + in + {Opam.command = [S "rm"; S "-r"; S "vendors"]; with_test = Never} + :: build :: runtests in let licenses = match diff --git a/manifest/manifest.mli b/manifest/manifest.mli index d457b1e16634..74cc09d27971 100644 --- a/manifest/manifest.mli +++ b/manifest/manifest.mli @@ -763,8 +763,8 @@ val private_exes : string list maker (** Register and return an internal test. - - [runtest]: if true, setup runtest aliases for the given - test. If unspecified, [runtest] is set true. + - [alias]: if non-empty, an alias is set up for the given test, named [alias]. + Default is ["runtest"]. Note that for JS tests, ["_js"] is appended to this alias. - [dep_files]: a list of files to add as dependencies using [(deps (file ...))] in the [runtest] alias. @@ -775,16 +775,16 @@ val private_exes : string list maker Since tests are private, they have no public name: the ['a] argument of [maker] is the internal name. *) val test : + ?alias:string -> ?dep_files:string list -> ?dep_globs:string list -> - ?runtest:bool -> string maker (** Same as {!test} but with several names, to define multiple tests at once. *) val tests : + ?alias:string -> ?dep_files:string list -> ?dep_globs:string list -> - ?runtest:bool -> string list maker (** Make an external vendored library, for use in internal target dependencies. -- GitLab From 4547f655ffbaf6b037db44d37581b4d6ff566b5e Mon Sep 17 00:00:00 2001 From: Romain Bardou <romain@nomadic-labs.com> Date: Fri, 13 May 2022 14:34:06 +0200 Subject: [PATCH 7/8] Manifest: be able to declare local Tezt tests --- manifest/main.ml | 38 ++++++++++++++++++++++-- manifest/manifest.ml | 68 ++++++++++++++++++++++++++++++++++++++++++- manifest/manifest.mli | 34 ++++++++++++++++++++-- tezt/tests/dune | 29 ++++++++++-------- 4 files changed, 151 insertions(+), 18 deletions(-) diff --git a/manifest/main.ml b/manifest/main.ml index ad31bfca2d73..04e20c783f4f 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -24,6 +24,12 @@ (*****************************************************************************) open Manifest + +let tezt_without_tezt_lib_dependency = tezt + +(* Prevent using [tezt] until we define [tezt_lib]. *) +let tezt = () [@@warning "-unused-value-declaration"] + module V = Version let sf = Printf.sprintf @@ -2655,6 +2661,15 @@ let tezt_lib = ~bisect_ppx:false ~deps:[re; lwt_unix; ezjsonm] +let tezt ~opam ~path ?(deps = []) ?dep_globs l = + tezt_without_tezt_lib_dependency + ~opam + ~path + ~deps:((tezt_lib |> open_ |> open_ ~m:"Base") :: deps) + ?dep_globs + l + [@@warning "-unused-value-declaration"] + let tezt_performance_regression = public_lib "tezt-performance-regression" @@ -5056,12 +5071,29 @@ let exclude filename = | "tezt" :: "records" :: _ -> true | "tezt" :: "remote_tests" :: _ -> true | "tezt" :: "snoop" :: _ -> true - | "tezt" :: "tests" :: _ -> true | "tezt" :: "vesting_contract_test" :: _ -> true | _ -> false -(* Generate dune and opam files. *) -let () = generate () +let () = + (* [make_tezt_exe] makes the global executable that contains all tests. + [generate] gives it the list of libraries that register Tezt tests + so that it can link all of them. *) + let make_tezt_exe test_libs = + let deps = + [ + tezt_lib |> open_ |> open_ ~m:"Base"; + str; + tezt_tezos |> open_ |> open_ ~m:"Runnable.Syntax"; + data_encoding; + tezos_base; + tezos_base_unix; + tezos_stdlib_unix; + Protocol.(main alpha); + ] + in + test "main" ~alias:"" ~path:"tezt/tests" ~opam:"" ~deps:(deps @ test_libs) + in + generate ~make_tezt_exe (* Generate a dunw-workspace file at the root of the repo *) let () = diff --git a/manifest/manifest.ml b/manifest/manifest.ml index b773c6e77337..ac4033e342ba 100644 --- a/manifest/manifest.ml +++ b/manifest/manifest.ml @@ -1536,6 +1536,71 @@ let if_ condition target = if condition then target else None type release = {version : string; url : Opam.url} +type tezt_target = { + opam : string; + deps : target list; + dep_globs : string list; + modules : string list; +} + +let tezt_targets_by_path : tezt_target String_map.t ref = ref String_map.empty + +let tezt ~opam ~path ?(deps = []) ?(dep_globs = []) modules = + if String_map.mem path !tezt_targets_by_path then + invalid_arg + ("cannot call Manifest.tezt twice for the same directory: " ^ path) ; + let tezt_target = {opam; deps; dep_globs; modules} in + tezt_targets_by_path := String_map.add path tezt_target !tezt_targets_by_path + +let register_tezt_targets ~make_tezt_exe = + let tezt_test_libs = ref [] in + let register_path path {opam; deps; dep_globs; modules} = + let path_with_underscores = + String.map (function '-' | '/' -> '_' | c -> c) path + in + let lib = + (* [linkall] is used to ensure that the test executable is linked with + [module_name] and [tezt]. *) + Target.private_lib + (path_with_underscores ^ "_tezt_lib") + ~path + ~opam:"" + ~deps + ~modules + ~linkall:true + in + tezt_test_libs := lib :: !tezt_test_libs ; + let exe_name = "main" in + let _exe = + (* Alias is "runtezt" and not "runtest" to make sure that the test is + not run in the CI twice (once with [dune @src/.../runtest] and once + with [dune exec tezt/tests/main.exe]). *) + Target.test + exe_name + ~alias:"runtezt" + ~path + ~opam + ~deps:[lib] + ~dep_globs + ~modules:[exe_name] + ~dune: + Dune. + [ + targets_rule + [exe_name ^ ".ml"] + ~action: + [ + S "with-stdout-to"; + S "%{targets}"; + [S "echo"; S "let () = Tezt.Test.run ()"]; + ]; + ] + in + () + in + String_map.iter register_path !tezt_targets_by_path ; + make_tezt_exe !tezt_test_libs + (*****************************************************************************) (* GENERATOR *) (*****************************************************************************) @@ -2721,9 +2786,10 @@ let generate_opam_ci () = delayed_by package_name) -let generate () = +let generate ~make_tezt_exe = Printexc.record_backtrace true ; try + register_tezt_targets ~make_tezt_exe ; generate_dune_files () ; generate_opam_files () ; generate_dune_project_files () ; diff --git a/manifest/manifest.mli b/manifest/manifest.mli index 74cc09d27971..5a6cf492bdde 100644 --- a/manifest/manifest.mli +++ b/manifest/manifest.mli @@ -787,6 +787,33 @@ val tests : ?dep_globs:string list -> string list maker +(** Register a Tezt test. + + Usage: [tezt module_names] + + This declares: + - a library [PACKAGE_tezt_lib] in [path] where [PACKAGE] is the name of the + opam package denoted by [opam]; + - an executable [main] in [path] that links with [PACKAGE_tezt_lib] + and runs [Tezt.Test.run]. + + [module_names] is the list of modules to link in [PACKAGE_tezt_lib]. + Those should be files in [path] that call [Tezt.Test.register]. + + Note that a wrapper in [main.ml] adds a dependency to the [tezt] library + and [-open]s modules [Tezt] and [Tezt.Base] when compiling [module_names]. + + Additionally, the library [PACKAGE_tezt_lib] is also linked in [tezt/tests/main.exe] + so that this executable can be used to run all tests with auto-balancing + and other Tezt features. *) +val tezt : + opam:string -> + path:string -> + ?deps:target list -> + ?dep_globs:string list -> + string list -> + unit + (** Make an external vendored library, for use in internal target dependencies. [main_module] is the name of the main module provided by the library (see [open_]). @@ -952,8 +979,11 @@ val name_for_errors : target -> string (** Generate dune and opam files. Call this after you declared all your targets with functions such as - [public_lib], [test], etc. *) -val generate : unit -> unit + [public_lib], [test], etc. + + [make_tezt_exe] is given the list of libraries that register Tezt tests + and shall create a test executable that links all of them. *) +val generate : make_tezt_exe:(target list -> target) -> unit (** Run various checks. diff --git a/tezt/tests/dune b/tezt/tests/dune index 62f43d97f7f2..f99d8c70ea48 100644 --- a/tezt/tests/dune +++ b/tezt/tests/dune @@ -1,15 +1,20 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + (executable (name main) - (libraries str - tezt-tezos - data-encoding - tezos-base - tezos-base.unix - tezos-stdlib-unix - tezos-protocol-alpha) + (libraries + tezt + str + tezt-tezos + data-encoding + tezos-base + tezos-base.unix + tezos-stdlib-unix + tezos-protocol-alpha) (flags - (:standard - -open Tezt - -open Tezt_tezos - -open Tezt_tezos.Runnable.Syntax - -open Tezt.Base))) + (:standard) + -open Tezt + -open Tezt.Base + -open Tezt_tezos + -open Tezt_tezos.Runnable.Syntax)) -- GitLab From fb09026127049a5c11efc47d9bcbddbb1da0c74b Mon Sep 17 00:00:00 2001 From: Romain Bardou <romain@nomadic-labs.com> Date: Thu, 2 Jun 2022 15:01:35 +0200 Subject: [PATCH 8/8] Alpha/test: migrate regression tests to manifest+tezt --- .gitlab/ci/test/unit.yml | 1 - manifest/main.ml | 40 ++++++++++--------- opam/tezos-protocol-alpha-tests.opam | 1 + .../lib_protocol/test/regression/dune | 27 ++++++++++--- .../lib_protocol/test/regression/main.ml | 39 ------------------ .../test/regression/test_logging.ml | 21 ++++++++-- tezt/tests/dune | 3 +- 7 files changed, 65 insertions(+), 67 deletions(-) delete mode 100644 src/proto_alpha/lib_protocol/test/regression/main.ml diff --git a/.gitlab/ci/test/unit.yml b/.gitlab/ci/test/unit.yml index 1d1f19b18042..2fd01ea00102 100644 --- a/.gitlab/ci/test/unit.yml +++ b/.gitlab/ci/test/unit.yml @@ -122,7 +122,6 @@ unit:alpha: proto_alpha__lib_protocol__3: > @src/proto_alpha/lib_protocol/test/pbt/runtest @src/proto_alpha/lib_protocol/test/unit/runtest - @src/proto_alpha/lib_protocol/test/regression/runtest proto_alpha: > @src/proto_alpha/lib_benchmark/runtest @src/proto_alpha/lib_client/runtest diff --git a/manifest/main.ml b/manifest/main.ml index 04e20c783f4f..218017133db4 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -2668,7 +2668,6 @@ let tezt ~opam ~path ?(deps = []) ?dep_globs l = ~deps:((tezt_lib |> open_ |> open_ ~m:"Base") :: deps) ?dep_globs l - [@@warning "-unused-value-declaration"] let tezt_performance_regression = public_lib @@ -3211,23 +3210,28 @@ end = struct in let _regresssion = if N.(number >= 014) then - Some - (test - "main" - ~path:(path // "lib_protocol/test/regression") - ~opam:(sf "tezos-protocol-%s-tests" name_dash) - ~deps: - [ - tezt_lib; - tezos_base |> open_ ~m:"TzPervasives"; - main |> open_; - client |> if_some |> open_; - plugin |> if_some |> open_; - test_helpers |> if_some |> open_; - tezos_micheline |> open_; - ] - ~dep_globs:["contracts/*"; "tezt/_regressions/*"]) - else None + (* About [~dep_globs]: this is only needed so that dune re-runs the tests + if those files are modified. Dune will also copy those files in [_build], + but the test uses absolute paths to find those files + (thanks to [DUNE_SOURCEROOT] and [Filename.dirname __FILE__]), + so those copies are not actually used. This is needed so that the test + can be run either with [dune build @runtezt], + with [dune exec src/proto_alpha/lib_protocol/test/regression/main.exe], + or with [dune exec tezt/tests/main.exe -- -f test_logging.ml]. *) + tezt + ["test_logging"] + ~path:(path // "lib_protocol/test/regression") + ~opam:(sf "tezos-protocol-%s-tests" name_dash) + ~deps: + [ + tezos_base |> open_ ~m:"TzPervasives"; + main |> open_; + client |> if_some |> open_; + plugin |> if_some |> open_; + test_helpers |> if_some |> open_; + tezos_micheline |> open_; + ] + ~dep_globs:["contracts/*.tz"; "expected/test_logging.ml/*.out"] in () diff --git a/opam/tezos-protocol-alpha-tests.opam b/opam/tezos-protocol-alpha-tests.opam index b28095948d25..576a88839805 100644 --- a/opam/tezos-protocol-alpha-tests.opam +++ b/opam/tezos-protocol-alpha-tests.opam @@ -34,5 +34,6 @@ build: [ ["rm" "-r" "vendors"] ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} + ["dune" "build" "@runtezt" "-p" name "-j" jobs] {with-test} ] synopsis: "Tezos/Protocol: tests for economic-protocol definition" diff --git a/src/proto_alpha/lib_protocol/test/regression/dune b/src/proto_alpha/lib_protocol/test/regression/dune index c87df26eba04..03d79cc3cb17 100644 --- a/src/proto_alpha/lib_protocol/test/regression/dune +++ b/src/proto_alpha/lib_protocol/test/regression/dune @@ -1,8 +1,9 @@ ; This file was automatically generated, do not edit. ; Edit file manifest/main.ml instead. -(executable - (name main) +(library + (name src_proto_alpha_lib_protocol_test_regression_tezt_lib) + (instrumentation (backend bisect_ppx)) (libraries tezt tezos-base @@ -11,17 +12,33 @@ tezos-protocol-plugin-alpha tezos-alpha-test-helpers tezos-micheline) + (library_flags (:standard -linkall)) (flags (:standard) + -open Tezt + -open Tezt.Base -open Tezos_base.TzPervasives -open Tezos_protocol_alpha -open Tezos_client_alpha -open Tezos_protocol_plugin_alpha -open Tezos_alpha_test_helpers - -open Tezos_micheline)) + -open Tezos_micheline) + (modules test_logging)) + +(executable + (name main) + (libraries + src_proto_alpha_lib_protocol_test_regression_tezt_lib) + (modules main)) (rule - (alias runtest) + (alias runtezt) (package tezos-protocol-alpha-tests) - (deps (glob_files contracts/*) (glob_files tezt/_regressions/*)) + (deps + (glob_files contracts/*.tz) + (glob_files expected/test_logging.ml/*.out)) (action (run %{dep:./main.exe}))) + +(rule + (targets main.ml) + (action (with-stdout-to %{targets} (echo "let () = Tezt.Test.run ()")))) diff --git a/src/proto_alpha/lib_protocol/test/regression/main.ml b/src/proto_alpha/lib_protocol/test/regression/main.ml deleted file mode 100644 index 055d1d7ba7c9..000000000000 --- a/src/proto_alpha/lib_protocol/test/regression/main.ml +++ /dev/null @@ -1,39 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs <contact@nomadic-labs.com> *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol - Invocation: cd src/proto_alpha/lib_protocol/test/regression && dune exec ./main.exe - Subject: Protocol Regressions - *) - -(* This module runs the tests implemented in all other modules of this directory. - Each module defines tests which are thematically related, - as functions to be called here. *) -let () = - Test_logging.register () ; - (* Test.run () should be the last statement, don't register afterwards! *) - Tezt.Test.run () diff --git a/src/proto_alpha/lib_protocol/test/regression/test_logging.ml b/src/proto_alpha/lib_protocol/test/regression/test_logging.ml index 0a5ea868c431..2a79d955f06b 100644 --- a/src/proto_alpha/lib_protocol/test/regression/test_logging.ml +++ b/src/proto_alpha/lib_protocol/test/regression/test_logging.ml @@ -158,7 +158,11 @@ let test_context () = let run_script {filename; amount; storage; parameter} () = let get_log, logger = logger () in let script = - Contract_helpers.read_file @@ Base.(("contracts" // filename) ^ ".tz") + let filename = + project_root // Filename.dirname __FILE__ // "contracts" + // (filename ^ ".tz") + in + Contract_helpers.read_file filename in let* ctxt = test_context () in let step_constants = @@ -195,11 +199,22 @@ let fail_on_error f () = | Ok () -> return () | Error e -> Test.fail "%a" Error_monad.pp_print_trace e +(* Make sure that after a snapshot the snapshotted version of the test + has a different [~title], because all tests are linked in [tezt/tests/main.exe]. *) +let protocol = + match __FILE__ =~* rex "^src/proto_([0-9a-zA-Z_]*)/" with + | None -> + Stdlib.failwith ("failed to extract protocol name from path: " ^ __FILE__) + | Some name -> name + let register_script contract = + (* [~title] must be unique across the codebase, so we prefix it with the protocol name. + [~file] however is better kept the same across protocols to simplify snapshotting. *) Regression.register ~__FILE__ - ~title:contract.filename + ~title:(protocol ^ ": " ^ contract.filename) ~tags:["protocol"; "regression"; "logging"] + ~file:contract.filename (fail_on_error @@ run_script contract) (* These tests should always cover: @@ -210,7 +225,7 @@ let register_script contract = what is being logged and what is not. We are not concerned with gas, because that's kept track of by regular regression tests. Actually, gas is unaccounted for in all the tests in this module. *) -let register () = +let () = Array.iter register_script [| diff --git a/tezt/tests/dune b/tezt/tests/dune index f99d8c70ea48..1e8e4a73009d 100644 --- a/tezt/tests/dune +++ b/tezt/tests/dune @@ -11,7 +11,8 @@ tezos-base tezos-base.unix tezos-stdlib-unix - tezos-protocol-alpha) + tezos-protocol-alpha + src_proto_alpha_lib_protocol_test_regression_tezt_lib) (flags (:standard) -open Tezt -- GitLab