From b398913dd39bf8a49949408e4d4d021d0286194c Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Wed, 6 May 2020 05:11:09 -0500 Subject: [PATCH] Add support for bisect_ppx (#3403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stephanie You Co-authored-by: Jérémie Dimino --- .travis-ci.sh | 3 +- CHANGES.md | 3 + doc/bisect.rst | 72 +++++++++++++ doc/index.rst | 1 + src/dune/context.ml | 15 ++- src/dune/dune_file.ml | 54 +++++++++- src/dune/dune_file.mli | 4 + src/dune/exe_rules.ml | 16 ++- src/dune/install_rules.ml | 12 ++- src/dune/lib_config.ml | 1 + src/dune/lib_config.mli | 1 + src/dune/lib_rules.ml | 7 +- src/dune/super_context.ml | 8 +- src/dune/virtual_rules.ml | 8 +- src/dune/workspace.ml | 8 ++ src/dune/workspace.mli | 1 + src/dune_lang/syntax.ml | 2 +- test/blackbox-tests/dune.inc | 9 ++ test/blackbox-tests/gen_tests.ml | 1 + .../test-cases/bisect-ppx/run.t | 101 ++++++++++++++++++ test/expect-tests/findlib_tests.ml | 1 + 21 files changed, 305 insertions(+), 23 deletions(-) create mode 100644 doc/bisect.rst create mode 100644 test/blackbox-tests/test-cases/bisect-ppx/run.t diff --git a/.travis-ci.sh b/.travis-ci.sh index abb799f130c..b815dc6ec3b 100755 --- a/.travis-ci.sh +++ b/.travis-ci.sh @@ -30,7 +30,8 @@ opam_install_test_deps () { ocaml-migrate-parsetree \ result.1.4 \ utop.2.4.2 \ - mdx.1.6.0 + mdx.1.6.0 \ + bisect_ppx # We install Coq separatedly as to be more resistant w.r.t. the 10 # minutes Travis timeout; the travis_wait hack doesn't work well # with Dune's current setup. Note that Travis caching should help diff --git a/CHANGES.md b/CHANGES.md index 01f51e60277..45ceef71a7a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,9 @@ next - Generate correct META files for sub-libraries (of the form `lib.foo`) that contain .js runtime files. (#3445, @hhugo) + +- Allow bisect_ppx to be enabled/disabled via dune-workspace. (#3404, + @stephanieyou) - Correctly infer targets for the `diff?` action. (#3457, fixes #2990, @greedy) diff --git a/doc/bisect.rst b/doc/bisect.rst new file mode 100644 index 00000000000..8bb9ed0de83 --- /dev/null +++ b/doc/bisect.rst @@ -0,0 +1,72 @@ +************************* +Code coverage with bisect +************************* + +In this section, we will explain how to set up code coverage with bisect_ppx_ so +that you can enable and disable coverage via ``dune-workspace`` files. This +setup avoids creating a hard dependency on ``bisect_ppx`` in your project. + +Specifying what to bisect +========================= + +First we must include ``(using bisect_ppx 1.0)`` in our ``dune-project`` file, +like so: + +.. code:: scheme + + (lang dune 2.6) + (using bisect_ppx 1.0) + +Then, we should use the ``(bisect_ppx)`` field. The dune file may look like +this: + +.. code:: scheme + + (library + (name foo) + (modules foo) + (bisect_ppx)) + + (executable + (name test) + (modules test) + (libraries foo)) + +The ``(bisect_ppx)`` field can be specified in library and executable stanzas. +Libraries/executables that do not use ``(bisect_ppx)`` will not be instrumented +for code coverage. + +Enabling/disabling code coverage +================================ + +By default, ``bisect_ppx`` is not compiled and linked with the program when +using ``(bisect_ppx)``. To enable code coverage, we can set the +``bisect_enabled`` flag in a ``dune-workspace`` file. For example, +``dune-workspace.dev`` may look like: + +.. code:: scheme + + (lang dune 2.6) + (context (default (bisect_enabled true))) + +Then, to build the project with code coverage, we can run: + +.. code:: bash + + $ dune exec ./test.exe --workspace dune-workspace.dev + +We can also define different contexts in the ``dune-workspace`` file as follows: + +.. code:: scheme + + (lang dune 2.6) + (context default) + (context (default (name coverage) (bisect_enabled true))) + +Running the following will enable coverage: + +.. code:: bash + + $ dune exec ./test.exe --context coverage + +.. _bisect_ppx: https://github.com/aantron/bisect_ppx diff --git a/doc/index.rst b/doc/index.rst index 0e05b91d024..4298663b098 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -15,6 +15,7 @@ Welcome to dune's documentation! dune-files concepts tests + bisect foreign-code documentation jsoo diff --git a/src/dune/context.ml b/src/dune/context.ml index 13959c7a9b5..ff83e0f9534 100644 --- a/src/dune/context.ml +++ b/src/dune/context.ml @@ -256,7 +256,7 @@ let write_dot_dune_dir ~build_dir ~ocamlc ~ocaml_config_vars = let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets ~host_context ~host_toolchain ~profile ~fdo_target_exe - ~dynamically_linked_foreign_archives = + ~dynamically_linked_foreign_archives ~bisect_enabled = let prog_not_found_in_path prog = Utils.program_not_found prog ~context:name ~loc:None in @@ -491,6 +491,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets ; ccomp_type = Ocaml_config.ccomp_type ocfg ; profile ; ocaml_version = Ocaml_config.version_string ocfg + ; bisect_enabled } in if Option.is_some fdo_target_exe then @@ -603,10 +604,10 @@ let extend_paths t ~env = Env.extend ~vars env let default ~merlin ~env_nodes ~env ~targets ~fdo_target_exe - ~dynamically_linked_foreign_archives = + ~dynamically_linked_foreign_archives ~bisect_enabled = let path = Env.path env in create ~kind:Default ~path ~env ~env_nodes ~merlin ~targets ~fdo_target_exe - ~dynamically_linked_foreign_archives + ~dynamically_linked_foreign_archives ~bisect_enabled let opam_version = let f opam = @@ -637,7 +638,7 @@ let opam_version = let create_for_opam ~root ~env ~env_nodes ~targets ~profile ~switch ~name ~merlin ~host_context ~host_toolchain ~fdo_target_exe - ~dynamically_linked_foreign_archives = + ~dynamically_linked_foreign_archives ~bisect_enabled = let opam = match Memo.Lazy.force opam with | None -> Utils.program_not_found "opam" ~loc:None @@ -688,6 +689,7 @@ let create_for_opam ~root ~env ~env_nodes ~targets ~profile ~switch ~name ~kind:(Opam { root; switch }) ~profile ~targets ~path ~env ~env_nodes ~name ~merlin ~host_context ~host_toolchain ~fdo_target_exe ~dynamically_linked_foreign_archives + ~bisect_enabled let instantiate_context env (workspace : Workspace.t) ~(context : Workspace.Context.t) ~host_context = @@ -707,6 +709,7 @@ let instantiate_context env (workspace : Workspace.t) ; loc = _ ; fdo_target_exe ; dynamically_linked_foreign_archives + ; bisect_enabled } -> let merlin = workspace.merlin_context = Some (Workspace.Context.name context) @@ -722,6 +725,7 @@ let instantiate_context env (workspace : Workspace.t) let env = extend_paths ~env paths in default ~env ~env_nodes ~profile ~targets ~name ~merlin ~host_context ~host_toolchain ~fdo_target_exe ~dynamically_linked_foreign_archives + ~bisect_enabled | Opam { base = { targets @@ -734,6 +738,7 @@ let instantiate_context env (workspace : Workspace.t) ; loc = _ ; fdo_target_exe ; dynamically_linked_foreign_archives + ; bisect_enabled } ; switch ; root @@ -742,7 +747,7 @@ let instantiate_context env (workspace : Workspace.t) let env = extend_paths ~env paths in create_for_opam ~root ~env_nodes ~env ~profile ~switch ~name ~merlin ~targets ~host_context ~host_toolchain:toolchain ~fdo_target_exe - ~dynamically_linked_foreign_archives + ~dynamically_linked_foreign_archives ~bisect_enabled module Create = struct module Output = struct diff --git a/src/dune/dune_file.ml b/src/dune/dune_file.ml index 48fa44b711a..7d2b0917298 100644 --- a/src/dune/dune_file.ml +++ b/src/dune/dune_file.ml @@ -35,6 +35,14 @@ let variants_field = (let* () = Dune_lang.Syntax.since library_variants (0, 1) in located (repeat Variant.decode >>| Variant.Set.of_list)) +let bisect_ppx_syntax = + Dune_lang.Syntax.create ~name:"bisect_ppx" ~desc:"the bisect_ppx extension" + [ ((1, 0), `Since (2, 6)) ] + +let () = + Dune_project.Extension.register_simple bisect_ppx_syntax + (Dune_lang.Decoder.return []) + module Pps_and_flags = struct let decode = let+ l, flags = @@ -214,6 +222,29 @@ module Preprocess_map = struct List.fold_left (Preprocess.pps pp) ~init:acc ~f:(fun acc (loc, pp) -> Lib_name.Map.set acc pp loc)) |> Lib_name.Map.foldi ~init:[] ~f:(fun pp loc acc -> (loc, pp) :: acc) + + let add_bisect t = + let bisect_ppx = + let bisect_name = Lib_name.parse_string_exn (Loc.none, "bisect_ppx") in + (Loc.none, bisect_name) + in + Per_module.map t ~f:(fun pp -> + match pp with + | Preprocess.No_preprocessing -> + let loc = Loc.none in + let pps = [ bisect_ppx ] in + let flags = [] in + let staged = false in + Preprocess.Pps { loc; pps; flags; staged } + | Preprocess.Pps { loc; pps; flags; staged } -> + let pps = bisect_ppx :: pps in + Preprocess.Pps { loc; pps; flags; staged } + | Action (loc, _) | Future_syntax loc -> + User_error.raise ~loc + [ Pp.text + "Preprocessing with actions and future syntax cannot be used \ + in conjunction with (bisect_ppx)" + ]) end module Lint = struct @@ -359,6 +390,7 @@ module Buildable = struct ; flags : Ocaml_flags.Spec.t ; js_of_ocaml : Js_of_ocaml.t ; allow_overlapping_dependencies : bool + ; bisect_ppx : bool } let decode ~in_library ~allow_re_export = @@ -424,6 +456,9 @@ module Buildable = struct field "js_of_ocaml" Js_of_ocaml.decode ~default:Js_of_ocaml.default and+ allow_overlapping_dependencies = field_b "allow_overlapping_dependencies" + and+ bisect_ppx = + field_b "bisect_ppx" + ~check:(Dune_lang.Syntax.since bisect_ppx_syntax (1, 0)) and+ version = Dune_lang.Syntax.get_exn Stanza.syntax in let foreign_stubs = foreign_stubs @@ -468,6 +503,7 @@ module Buildable = struct ; flags ; js_of_ocaml ; allow_overlapping_dependencies + ; bisect_ppx } let has_foreign t = @@ -481,6 +517,12 @@ module Buildable = struct Per_module.get t.preprocess dummy_name else Preprocess.No_preprocessing + + let preprocess t ~(lib_config: Lib_config.t) = + if t.bisect_ppx && lib_config.bisect_enabled then + Preprocess_map.add_bisect t.preprocess + else + t.preprocess end module Public_lib = struct @@ -1031,7 +1073,17 @@ module Library = struct let synopsis = conf.synopsis in let sub_systems = conf.sub_systems in let ppx_runtime_deps = conf.ppx_runtime_libraries in - let pps = Preprocess_map.pps conf.buildable.preprocess in + let pps = + let pps_without_bisect = Preprocess_map.pps conf.buildable.preprocess in + if lib_config.bisect_enabled && conf.buildable.bisect_ppx then + let bisect_ppx = + let bisect_name = Lib_name.parse_string_exn (Loc.none, "bisect_ppx") in + (Loc.none, bisect_name) + in + bisect_ppx :: pps_without_bisect + else + pps_without_bisect + in let virtual_deps = conf.virtual_deps in let dune_version = Some conf.dune_version in let implements = conf.implements in diff --git a/src/dune/dune_file.mli b/src/dune/dune_file.mli index c84e1ec132f..84fc8aec218 100644 --- a/src/dune/dune_file.mli +++ b/src/dune/dune_file.mli @@ -98,6 +98,7 @@ module Buildable : sig ; flags : Ocaml_flags.Spec.t ; js_of_ocaml : Js_of_ocaml.t ; allow_overlapping_dependencies : bool + ; bisect_ppx : bool } (** Check if the buildable has any foreign stubs or archives. *) @@ -105,6 +106,9 @@ module Buildable : sig (** Preprocessing specification used by all modules or [No_preprocessing] *) val single_preprocess : t -> Preprocess.t + + (** Includes bisect_ppx if specified by [lib_config] *) + val preprocess : t -> lib_config:Lib_config.t -> Preprocess_map.t end module Public_lib : sig diff --git a/src/dune/exe_rules.ml b/src/dune/exe_rules.ml index f2fa393d9d0..5f4b8588eaa 100644 --- a/src/dune/exe_rules.ml +++ b/src/dune/exe_rules.ml @@ -15,9 +15,13 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info let ml_sources = Dir_contents.ocaml dir_contents in Ml_sources.modules_of_executables ml_sources ~first_exe ~obj_dir in + let ctx = SC.context sctx in + let preprocess = + Dune_file.Buildable.preprocess exes.buildable ~lib_config:ctx.lib_config + in let pp = Preprocessing.make sctx ~dir ~dep_kind:Required ~scope ~expander - ~preprocess:exes.buildable.preprocess + ~preprocess ~preprocessor_deps:exes.buildable.preprocessor_deps ~lint:exes.buildable.lint ~lib_name:None in @@ -44,7 +48,6 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info (Module_name.to_string mod_name) ]) in - let ctx = SC.context sctx in let explicit_js_mode = Dune_project.explicit_js_mode (Scope.project scope) in let linkages = let module L = Dune_file.Executables.Link_mode in @@ -170,11 +173,14 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info let rules ~sctx ~dir ~dir_contents ~scope ~expander (exes : Dune_file.Executables.t) = let dune_version = Scope.project scope |> Dune_project.dune_version in + let ctx = SC.context sctx in + let pps = + Dune_file.Preprocess_map.pps + (Dune_file.Buildable.preprocess exes.buildable ~lib_config:ctx.lib_config) + in let compile_info = Lib.DB.resolve_user_written_deps_for_exes (Scope.libs scope) exes.names - exes.buildable.libraries - ~pps:(Dune_file.Preprocess_map.pps exes.buildable.preprocess) - ~dune_version + exes.buildable.libraries ~pps ~dune_version ~allow_overlaps:exes.buildable.allow_overlapping_dependencies ~variants:exes.variants ~optional:exes.optional ~forbidden_libraries:exes.forbidden_libraries diff --git a/src/dune/install_rules.ml b/src/dune/install_rules.ml index e20e49ba13d..d07f05e8c18 100644 --- a/src/dune/install_rules.ml +++ b/src/dune/install_rules.ml @@ -133,7 +133,7 @@ end = struct (Some loc, Install.Entry.make Stublibs a)) ] - let keep_if ~external_lib_deps_mode expander = + let keep_if ~(ctx : Context.t) ~external_lib_deps_mode expander = if external_lib_deps_mode then fun ~scope:_ -> Option.some @@ -155,10 +155,14 @@ end = struct let dune_version = Scope.project scope |> Dune_project.dune_version in + let pps = + Dune_file.Preprocess_map.pps + (Dune_file.Buildable.preprocess exes.buildable + ~lib_config:ctx.lib_config) + in Lib.DB.resolve_user_written_deps_for_exes (Scope.libs scope) exes.names exes.buildable.libraries - ~pps:(Dune_file.Preprocess_map.pps exes.buildable.preprocess) - ~dune_version + ~pps ~dune_version ~allow_overlaps:exes.buildable.allow_overlapping_dependencies ~variants:exes.variants ~optional:exes.optional in @@ -231,7 +235,7 @@ end = struct in let keep_if = let external_lib_deps_mode = !Clflags.external_lib_deps_mode in - keep_if ~external_lib_deps_mode + keep_if ~ctx ~external_lib_deps_mode in Dir_with_dune.deep_fold stanzas ~init ~f:(fun d stanza acc -> let { Dir_with_dune.ctx_dir = dir; scope; _ } = d in diff --git a/src/dune/lib_config.ml b/src/dune/lib_config.ml index 9dc9f3934c2..8d304376f79 100644 --- a/src/dune/lib_config.ml +++ b/src/dune/lib_config.ml @@ -14,6 +14,7 @@ type t = ; ccomp_type : Ocaml_config.Ccomp_type.t ; profile : Profile.t ; ocaml_version : string + ; bisect_enabled : bool } let var_map = diff --git a/src/dune/lib_config.mli b/src/dune/lib_config.mli index 9f17fd42124..a15f2564e2e 100644 --- a/src/dune/lib_config.mli +++ b/src/dune/lib_config.mli @@ -14,6 +14,7 @@ type t = ; ccomp_type : Ocaml_config.Ccomp_type.t ; profile : Profile.t ; ocaml_version : string + ; bisect_enabled : bool } val allowed_in_enabled_if : (string * Dune_lang.Syntax.Version.t) list diff --git a/src/dune/lib_rules.ml b/src/dune/lib_rules.ml index e2cabba3e07..416532ce28a 100644 --- a/src/dune/lib_rules.ml +++ b/src/dune/lib_rules.ml @@ -340,10 +340,14 @@ let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope let flags = Super_context.ocaml_flags sctx ~dir lib.buildable in let obj_dir = Library.obj_dir ~dir lib in let vimpl = Virtual_rules.impl sctx ~lib ~scope in + let ctx = Super_context.context sctx in + let preprocess = + Dune_file.Buildable.preprocess lib.buildable ~lib_config:ctx.lib_config + in (* Preprocess before adding the alias module as it doesn't need preprocessing *) let pp = Preprocessing.make sctx ~dir ~dep_kind ~scope - ~preprocess:lib.buildable.preprocess ~expander + ~preprocess ~expander ~preprocessor_deps:lib.buildable.preprocessor_deps ~lint:lib.buildable.lint ~lib_name:(Some (snd lib.name)) @@ -354,7 +358,6 @@ let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope let modules = Vimpl.impl_modules vimpl modules in let requires_compile = Lib.Compile.direct_requires compile_info in let requires_link = Lib.Compile.requires_link compile_info in - let ctx = Super_context.context sctx in let dynlink = Dynlink_supported.get lib.dynlink ctx.supports_shared_libraries in diff --git a/src/dune/super_context.ml b/src/dune/super_context.ml index e1623eed7f3..8a6a1201cc1 100644 --- a/src/dune/super_context.ml +++ b/src/dune/super_context.ml @@ -396,10 +396,14 @@ let get_installed_binaries stanzas ~(context : Context.t) = let compile_info = let project = Scope.project d.scope in let dune_version = Dune_project.dune_version project in + let pps = + Dune_file.Preprocess_map.pps + (Dune_file.Buildable.preprocess exes.buildable + ~lib_config:context.lib_config) + in Lib.DB.resolve_user_written_deps_for_exes (Scope.libs d.scope) exes.names exes.buildable.libraries - ~pps:(Dune_file.Preprocess_map.pps exes.buildable.preprocess) - ~dune_version + ~pps ~dune_version ~allow_overlaps:exes.buildable.allow_overlapping_dependencies ~variants:exes.variants ~optional:exes.optional in diff --git a/src/dune/virtual_rules.ml b/src/dune/virtual_rules.ml index bdca93fcc3c..e0aac4437ad 100644 --- a/src/dune/virtual_rules.ml +++ b/src/dune/virtual_rules.ml @@ -74,6 +74,7 @@ let setup_copy_rules_for_impl ~sctx ~dir vimpl = Modules.iter_no_vlib vlib_modules ~f:(fun m -> copy_objs m) let impl sctx ~(lib : Dune_file.Library.t) ~scope = + let ctx = Super_context.context sctx in Option.map lib.implements ~f:(fun (loc, implements) -> match Lib.DB.find (Scope.libs scope) implements with | None -> @@ -108,10 +109,13 @@ let impl sctx ~(lib : Dune_file.Library.t) ~scope = let dir = Lib_info.src_dir info in Dir_contents.get sctx ~dir in + let preprocess = + Dune_file.Buildable.preprocess lib.buildable + ~lib_config:ctx.lib_config + in let modules = let pp_spec = - Pp_spec.make lib.buildable.preprocess - (Super_context.context sctx).version + Pp_spec.make preprocess (Super_context.context sctx).version in Dir_contents.ocaml dir_contents |> Ml_sources.modules_of_library ~name diff --git a/src/dune/workspace.ml b/src/dune/workspace.ml index a1221b470bd..35aa562d2e4 100644 --- a/src/dune/workspace.ml +++ b/src/dune/workspace.ml @@ -49,6 +49,7 @@ module Context = struct ; paths : (string * Ordered_set_lang.t) list ; fdo_target_exe : Path.t option ; dynamically_linked_foreign_archives : bool + ; bisect_enabled : bool } let to_dyn = Dyn.Encoder.opaque @@ -64,6 +65,7 @@ module Context = struct ; paths ; fdo_target_exe ; dynamically_linked_foreign_archives + ; bisect_enabled } t = Profile.equal profile t.profile && List.equal Target.equal targets t.targets @@ -77,6 +79,7 @@ module Context = struct && Option.equal Path.equal fdo_target_exe t.fdo_target_exe && Bool.equal dynamically_linked_foreign_archives t.dynamically_linked_foreign_archives + && Bool.equal bisect_enabled t.bisect_enabled let fdo_suffix t = match t.fdo_target_exe with @@ -133,6 +136,9 @@ module Context = struct field "paths" ~default:[] ( Dune_lang.Syntax.since Stanza.syntax (1, 12) >>> map ~f (repeat (pair (located string) Ordered_set_lang.decode)) ) + and+ bisect_enabled = + field ~default:false "bisect_enabled" + (Dune_lang.Syntax.since syntax (2, 6) >>> bool) and+ loc = loc in Option.iter host_context ~f:(fun _ -> match targets with @@ -153,6 +159,7 @@ module Context = struct ; paths ; fdo_target_exe ; dynamically_linked_foreign_archives + ; bisect_enabled } end @@ -293,6 +300,7 @@ module Context = struct ; paths = [] ; fdo_target_exe = None ; dynamically_linked_foreign_archives = true + ; bisect_enabled = false } end diff --git a/src/dune/workspace.mli b/src/dune/workspace.mli index 0d08a2171eb..f57d7010c09 100644 --- a/src/dune/workspace.mli +++ b/src/dune/workspace.mli @@ -28,6 +28,7 @@ module Context : sig will be built with all foreign archives statically linked into the runtime system. *) ; dynamically_linked_foreign_archives : bool + ; bisect_enabled : bool } end diff --git a/src/dune_lang/syntax.ml b/src/dune_lang/syntax.ml index 4de75f9970b..ca3c70c0d0c 100644 --- a/src/dune_lang/syntax.ml +++ b/src/dune_lang/syntax.ml @@ -232,7 +232,7 @@ let check_supported ~dune_lang_ver t (loc, ver) = Pp.textf "%s to %s" (Version.to_string a) (Version.to_string b)) ] in - let is_error = String.is_empty until || dune_lang_ver >= (2, 5) in + let is_error = String.is_empty until || dune_lang_ver >= (2, 6) in User_warning.emit ~is_error ~loc message let greatest_supported_version ?dune_lang_ver t = diff --git a/test/blackbox-tests/dune.inc b/test/blackbox-tests/dune.inc index 2e367fcc362..6432d77150d 100644 --- a/test/blackbox-tests/dune.inc +++ b/test/blackbox-tests/dune.inc @@ -46,6 +46,14 @@ test-cases/bin-eager-deps (progn (run dune-cram run run.t) (diff? run.t run.t.corrected))))) +(rule + (alias bisect-ppx) + (deps (package dune) (source_tree test-cases/bisect-ppx)) + (action + (chdir + test-cases/bisect-ppx + (progn (run dune-cram run run.t) (diff? run.t run.t.corrected))))) + (rule (alias block-strings) (deps (package dune) (source_tree test-cases/block-strings)) @@ -2476,6 +2484,7 @@ (alias all-promotions) (alias bad-alias-error) (alias bin-eager-deps) + (alias bisect-ppx) (alias block-strings) (alias byte-code-only) (alias byte_complete) diff --git a/test/blackbox-tests/gen_tests.ml b/test/blackbox-tests/gen_tests.ml index a7af08a0275..81d901d492b 100644 --- a/test/blackbox-tests/gen_tests.ml +++ b/test/blackbox-tests/gen_tests.ml @@ -255,6 +255,7 @@ let exclusions = ~additional_deps:[ Sexp.strings [ "package"; "dune-configurator" ] ] ; make "mdx-stanza" ~external_deps:true ; make "toplevel-integration" ~external_deps:true + ; make "bisect-ppx" ~external_deps:true ] |> String_map.of_list_map_exn ~f:(fun (test : Test.t) -> (test.path, test)) diff --git a/test/blackbox-tests/test-cases/bisect-ppx/run.t b/test/blackbox-tests/test-cases/bisect-ppx/run.t new file mode 100644 index 00000000000..8a7654ef925 --- /dev/null +++ b/test/blackbox-tests/test-cases/bisect-ppx/run.t @@ -0,0 +1,101 @@ +---------------------------------------------------------------------------------- +Testsuite for (bisect_ppx) field for libraries/executables. + + $ cat >dune-project < (lang dune 2.6) + > (using bisect_ppx 1.0) + > EOF + + + $ cat >dune-workspace.dev < (lang dune 2.6) + > (context (default (bisect_enabled true))) + > EOF + + $ echo "let run () = print_endline \"Hello, world!\"" > hello.ml + $ echo "let () = Hello.run ()" > test.ml + +---------------------------------------------------------------------------------- +* (preprocess (pps bisect_ppx)) produces the correct coverage files. + + $ cat >dune < (executable + > (name test) + > (preprocess (per_module + > ((pps bisect_ppx) hello)))) + > EOF + + $ dune exec ./test.exe + Hello, world! + + $ dune exec bisect-ppx-report -- html + Info: found coverage files in './' + + $ find . -name "hello.ml.html" + ./_coverage/hello.ml.html + + $ find . -name "test.ml.html" + $ rm *.coverage + $ rm -rf _coverage + +---------------------------------------------------------------------------------- +Test that bisect_ppx is enabled and produces *.coverage file for libraries. + + $ cat >dune < (library + > (name hello) + > (modules hello) + > (bisect_ppx)) + > + > (executable + > (name test) + > (modules test) + > (libraries hello)) + + $ dune exec ./test.exe + Hello, world! + + $ dune exec bisect-ppx-report -- html + Error: no coverage files given on command line or found + [1] + + $ dune exec ./test.exe --workspace dune-workspace.dev + Hello, world! + + $ dune exec bisect-ppx-report -- html + Info: found coverage files in './' + + $ find . -name "hello.ml.html" + ./_coverage/hello.ml.html + $ rm *.coverage + $ rm -rf _coverage + +Test that bisect_ppx is enabled and produces *.coverage file for executables. + $ cat >dune < (library + > (name hello) + > (modules hello)) + > + > (executable + > (name test) + > (modules test) + > (bisect_ppx) + > (libraries hello)) + + $ dune exec ./test.exe + Hello, world! + + $ dune exec bisect-ppx-report -- html + Error: no coverage files given on command line or found + [1] + + $ dune exec ./test.exe --workspace dune-workspace.dev + Hello, world! + + $ dune exec bisect-ppx-report -- html + Info: found coverage files in './' + + $ find . -name "test.ml.html" + ./_coverage/test.ml.html + $ rm *.coverage + $ rm -rf _coverage diff --git a/test/expect-tests/findlib_tests.ml b/test/expect-tests/findlib_tests.ml index 6145c9619e7..12fb42f2758 100644 --- a/test/expect-tests/findlib_tests.ml +++ b/test/expect-tests/findlib_tests.ml @@ -28,6 +28,7 @@ let findlib = ; ccomp_type = Other "gcc" ; profile = Profile.Dev ; ocaml_version = "4.02.3" + ; bisect_enabled = false } in Findlib.create ~stdlib_dir:cwd ~paths:[ db_path ]