From d922b37ab84c2e60916e80ab8d23ce454e759da3 Mon Sep 17 00:00:00 2001 From: Dino Distefano Date: Mon, 21 May 2018 06:08:31 -0700 Subject: [PATCH] Making Test Determinator parametric to Java and Clang Reviewed By: martinoluca Differential Revision: D8010835 fbshipit-source-id: 3182c79 --- infer/src/base/Config.ml | 33 ++- infer/src/base/Config.mli | 6 +- infer/src/infer.ml | 107 ++++----- infer/src/java/JavaProfilerSamples.ml | 10 +- infer/src/java/JavaProfilerSamples.mli | 2 + infer/src/java/jMain.ml | 2 - infer/src/java/testDeterminator.ml | 288 +++++++++++++++++++------ infer/src/java/testDeterminator.mli | 9 +- 8 files changed, 316 insertions(+), 141 deletions(-) diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index aaaeba5eb..400a9c93e 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1544,6 +1544,14 @@ and max_nesting = skipped. If omitted, all levels are shown." +and method_decls_info = + CLOpt.mk_string_opt ~long:"method-decls-info" + "Specifies the file containing the method declarations info (eg. start line, end line, \ + class, method name, etc.) when Infer is run Test Determinator mode. Used in combination with \ + other options as follows: $(b,--test-determinator --modified-lines modified_line_file \ + --profiler-sample profiler_sample_file --method-decls-info minfo.json)" + + and merge = CLOpt.mk_bool ~deprecated:["merge"] ~long:"merge" ~in_help:InferCommand.[(Analyze, manual_buck_flavors)] @@ -1561,10 +1569,11 @@ and ml_buckets = and modified_lines = - CLOpt.mk_string ~long:"modified-lines" ~default:"" + CLOpt.mk_string_opt ~long:"modified-lines" "Specifies the file containing the modified lines when Infer is run Test Determinator mode. \ - --test-determinator --modified-lines modified_lines_file --profiler-sample \ - profiler_sample_file" + Used in combination with other options as follows:\n \ + $(b, --test-determinator --modified-lines modified_lines_file --profiler-sample \ + profiler_sample_file)" and modified_targets = @@ -2031,9 +2040,8 @@ and symops_per_iteration = and test_determinator = CLOpt.mk_bool ~long:"test-determinator" ~default:false "Run infer in Test Determinator mode. It is used together with the --modified-lines and \ - --test-profiler flags \n \ - which speficy the relevant arguments. E.g. --test-determinator --modified-lines \ - modified_line_file --profiler-sample profiler_sample_file" + --test-profiler flags which speficy the relevant arguments. E.g. $(b, --test-determinator \ + --modified-lines modified_line_file --profiler-sample profiler_sample_file)" and test_filtering = @@ -2041,11 +2049,12 @@ and test_filtering = "List all the files Infer can report on (should be called from the root of the project)" -and profiler_sample = - CLOpt.mk_string ~long:"profiler-sample" ~default:"" +and profiler_samples = + CLOpt.mk_string_opt ~long:"profiler-samples" "Specifies the file containing the profiler samples when Infer is run Test Determinator mode. \ - --test-determinator --modified-lines modified_line_file --profiler-sample \ - profiler_samples_file" + Used in combination with other options as follows:\n \ + $(b,--test-determinator --modified-lines modified_line_file --profiler-samples \ + profiler_samples_file)" and testing_mode = @@ -2650,6 +2659,8 @@ and log_file = !log_file and max_nesting = !max_nesting +and method_decls_info = !method_decls_info + and merge = !merge and ml_buckets = !ml_buckets @@ -2824,7 +2835,7 @@ and test_determinator = !test_determinator and test_filtering = !test_filtering -and profiler_sample = !profiler_sample +and profiler_samples = !profiler_samples and testing_mode = !testing_mode diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 1a6c665a8..a63c09038 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -493,6 +493,8 @@ val log_file : string val max_nesting : int option +val method_decls_info : string option + val merge : bool val ml_buckets : @@ -500,7 +502,7 @@ val ml_buckets : val models_mode : bool -val modified_lines : string +val modified_lines : string option val modified_targets : string option @@ -626,7 +628,7 @@ val test_determinator : bool val test_filtering : bool -val profiler_sample : string +val profiler_samples : string option val testing_mode : bool diff --git a/infer/src/infer.ml b/infer/src/infer.ml index 70df0b5d0..79a96a7d2 100644 --- a/infer/src/infer.ml +++ b/infer/src/infer.ml @@ -120,56 +120,61 @@ let () = prepare_events_logging () ; if Config.debug_mode && CLOpt.is_originator then L.progress "Logs in %s@." (Config.results_dir ^/ Config.log_file) ; - ( match Config.command with - | Analyze -> - run Driver.Analyze - | Capture | Compile | Run -> - run (Lazy.force Driver.mode_from_command_line) - | Report -> - InferPrint.main ~report_json:None - | ReportDiff -> - (* at least one report must be passed in input to compute differential *) - ( match (Config.report_current, Config.report_previous) with - | None, None -> - L.(die UserError) - "Expected at least one argument among '--report-current' and '--report-previous'" - | _ -> - () ) ; - ReportDiff.reportdiff ~current_report:Config.report_current - ~previous_report:Config.report_previous - | Diff -> - Diff.diff (Lazy.force Driver.mode_from_command_line) - | Explore when Config.procedures -> - L.result "%a" - Config.( - Procedures.pp_all ?filter:procedures_filter ~proc_name:procedures_name - ~attr_kind:procedures_definedness ~source_file:procedures_source_file - ~proc_attributes:procedures_attributes) - () - | Explore when Config.source_files -> - L.result "%a" - (SourceFiles.pp_all ?filter:Config.source_files_filter ~cfgs:Config.source_files_cfgs - ~type_environment:Config.source_files_type_environment - ~procedure_names:Config.source_files_procedure_names - ~freshly_captured:Config.source_files_freshly_captured) - () - | Explore -> - let if_some key opt args = - match opt with None -> args | Some arg -> key :: string_of_int arg :: args - in - let if_true key opt args = if not opt then args else key :: args in - let if_false key opt args = if opt then args else key :: args in - let args = - if_some "--max-level" Config.max_nesting @@ if_true "--only-show" Config.only_show - @@ if_false "--no-source" Config.source_preview @@ if_true "--html" Config.html - @@ if_some "--select" Config.select ["-o"; Config.results_dir] - in - let prog = Config.lib_dir ^/ "python" ^/ "inferTraceBugs" in - if is_error (Unix.waitpid (Unix.fork_exec ~prog ~argv:(prog :: args) ())) then - L.external_error - "** Error running the reporting script:@\n** %s %s@\n** See error above@." prog - (String.concat ~sep:" " args) - | Events -> - EventLogger.dump () ) ; + ( if Config.test_determinator then ( + TestDeterminator.test_to_run_java Config.modified_lines Config.profiler_samples + Config.method_decls_info ; + TestDeterminator.print_test_to_run () ) + else + match Config.command with + | Analyze -> + run Driver.Analyze + | Capture | Compile | Run -> + run (Lazy.force Driver.mode_from_command_line) + | Report -> + InferPrint.main ~report_json:None + | ReportDiff -> + (* at least one report must be passed in input to compute differential *) + ( match (Config.report_current, Config.report_previous) with + | None, None -> + L.(die UserError) + "Expected at least one argument among '--report-current' and '--report-previous'" + | _ -> + () ) ; + ReportDiff.reportdiff ~current_report:Config.report_current + ~previous_report:Config.report_previous + | Diff -> + Diff.diff (Lazy.force Driver.mode_from_command_line) + | Explore when Config.procedures -> + L.result "%a" + Config.( + Procedures.pp_all ?filter:procedures_filter ~proc_name:procedures_name + ~attr_kind:procedures_definedness ~source_file:procedures_source_file + ~proc_attributes:procedures_attributes) + () + | Explore when Config.source_files -> + L.result "%a" + (SourceFiles.pp_all ?filter:Config.source_files_filter ~cfgs:Config.source_files_cfgs + ~type_environment:Config.source_files_type_environment + ~procedure_names:Config.source_files_procedure_names + ~freshly_captured:Config.source_files_freshly_captured) + () + | Explore -> + let if_some key opt args = + match opt with None -> args | Some arg -> key :: string_of_int arg :: args + in + let if_true key opt args = if not opt then args else key :: args in + let if_false key opt args = if opt then args else key :: args in + let args = + if_some "--max-level" Config.max_nesting @@ if_true "--only-show" Config.only_show + @@ if_false "--no-source" Config.source_preview @@ if_true "--html" Config.html + @@ if_some "--select" Config.select ["-o"; Config.results_dir] + in + let prog = Config.lib_dir ^/ "python" ^/ "inferTraceBugs" in + if is_error (Unix.waitpid (Unix.fork_exec ~prog ~argv:(prog :: args) ())) then + L.external_error + "** Error running the reporting script:@\n** %s %s@\n** See error above@." prog + (String.concat ~sep:" " args) + | Events -> + EventLogger.dump () ) ; (* to make sure the exitcode=0 case is logged, explicitly invoke exit *) L.exit 0 diff --git a/infer/src/java/JavaProfilerSamples.ml b/infer/src/java/JavaProfilerSamples.ml index be3688036..77bb13598 100644 --- a/infer/src/java/JavaProfilerSamples.ml +++ b/infer/src/java/JavaProfilerSamples.ml @@ -264,7 +264,7 @@ module JNI = struct end end -let create ~classname ~methodname ~signature ~kind = +let create ~classname ~methodname ~signature = let name = Typ.Name.Java.from_string classname in let args, ret_typ = JNI.parse_method_str signature in let java_type_args = List.map ~f:JNI.to_java_type args in @@ -275,7 +275,9 @@ let create ~classname ~methodname ~signature ~kind = then None else Some (JNI.to_java_type ret_typ) in - Typ.Procname.Java (Typ.Procname.Java.make name java_type_ret_typ methodname java_type_args kind) + Typ.Procname.Java + (Typ.Procname.Java.make name java_type_ret_typ methodname java_type_args + Typ.Procname.Java.Non_Static) type labeled_profiler_sample = string * ProfilerSample.t [@@deriving compare] @@ -300,9 +302,7 @@ let from_json j = ; ("signature", `String signature) ; _ ] :: tl -> - let procname = - create ~kind:Typ.Procname.Java.Non_Static ~classname ~methodname ~signature - in + let procname = create ~classname ~methodname ~signature in parse_json tl (procname :: acc) | [] -> acc diff --git a/infer/src/java/JavaProfilerSamples.mli b/infer/src/java/JavaProfilerSamples.mli index bf605c882..bfb11abd4 100644 --- a/infer/src/java/JavaProfilerSamples.mli +++ b/infer/src/java/JavaProfilerSamples.mli @@ -48,3 +48,5 @@ val equal_labeled_profiler_sample : labeled_profiler_sample -> labeled_profiler_ val from_json_string : string -> labeled_profiler_sample list val from_json_file : string -> labeled_profiler_sample list + +val create : classname:string -> methodname:string -> signature:string -> ProfilerSample.elt diff --git a/infer/src/java/jMain.ml b/infer/src/java/jMain.ml index 750d8b7ca..a84668dd7 100644 --- a/infer/src/java/jMain.ml +++ b/infer/src/java/jMain.ml @@ -36,8 +36,6 @@ let do_source_file linereader classes program tenv source_basename package_opt s JFrontend.compute_source_icfg linereader classes program tenv source_basename package_opt source_file in - if Config.test_determinator then - TestDeterminator.test_to_run source_file cfg Config.modified_lines Config.profiler_sample ; store_icfg source_file cfg diff --git a/infer/src/java/testDeterminator.ml b/infer/src/java/testDeterminator.ml index 1ff77d9d9..b48565a59 100644 --- a/infer/src/java/testDeterminator.ml +++ b/infer/src/java/testDeterminator.ml @@ -7,103 +7,253 @@ * of patent rights can be found in the PATENTS file in the same directory. *) module L = Logging +module F = Format open JavaProfilerSamples open! IStd -module LineRangeMap = Caml.Map.Make (struct +module RangeMap = Caml.Map.Make (struct type t = Typ.Procname.t let compare = Typ.Procname.compare end) -let update_line_range_map pdesc map = - let start_node = Procdesc.get_start_node pdesc in - let exit_node = Procdesc.get_exit_node pdesc in - let range = (Procdesc.Node.get_loc start_node, Procdesc.Node.get_loc exit_node) in - let key = Procdesc.get_proc_name pdesc in - LineRangeMap.add key range map +let initialized_test_determinator = ref false +let is_test_determinator_init () = !initialized_test_determinator + +module MethodRangeMap = struct + let map : (Location.t * Location.t) RangeMap.t ref = ref RangeMap.empty + + let method_range_map () = !map + + let split_class_method_name qualified_method_name = + String.rsplit2_exn qualified_method_name ~on:'.' + + + let create_java_method_range_map code_graph_file' = + match code_graph_file' with + | Some code_graph_file -> + let open Java_method_decl_j in + let json_string = + match Utils.read_file code_graph_file with + | Ok cl_list -> + let json = List.fold cl_list ~init:"" ~f:(fun acc s -> acc ^ s) in + json + | Error _ -> + L.die UserError "Could not read file %s" code_graph_file + in + let method_decls = java_method_decls_of_string json_string in + let map' = + List.fold method_decls ~init:RangeMap.empty ~f:(fun acc decl -> + let start_location = + { Location.line= decl.start_line + ; col= -1 + ; file= SourceFile.create ~warn_on_error:false decl.source_file } + in + let end_location = + { Location.line= decl.end_line + ; col= -1 + ; file= SourceFile.create ~warn_on_error:false decl.source_file } + in + let range = (start_location, end_location) in + let classname, methodname = split_class_method_name decl.method_name in + let signature = match decl.signature with Some s -> s | _ -> "" in + let key = JavaProfilerSamples.create ~classname ~methodname ~signature in + RangeMap.add key range acc ) + in + map := map' + | _ -> + L.die UserError "Missing method declaration info argument" + + + let create_clang_method_range_map cfg = + let update_method_range_map pdesc = + let start_node = Procdesc.get_start_node pdesc in + let exit_node = Procdesc.get_exit_node pdesc in + let range = (Procdesc.Node.get_loc start_node, Procdesc.Node.get_loc exit_node) in + let key = Procdesc.get_proc_name pdesc in + map := RangeMap.add key range !map + in + Typ.Procname.Hash.iter (fun _ pdesc -> update_method_range_map pdesc) cfg + + + let pp_map fmt () = + let pp_map' fmt m = + RangeMap.iter + (fun key range -> + F.fprintf fmt "@\n %a --> (%a,%a)" Typ.Procname.pp key Location.pp (fst range) + Location.pp (snd range) ) + m + in + F.fprintf fmt "@\n--- Method Range Map ---%a@\n--- End Method Range Map --- @\n" pp_map' !map +end + +module DiffLines = struct + (* This is a map + file name |--> {set of changed line } + *) + let map : int list String.Map.t ref = ref String.Map.empty + + let changed_lines_map () = !map + + (* Read the file containing info on changed lines and populate the map *) + let init_changed_lines_map changed_lines_file' = + match changed_lines_file' with + | Some changed_lines_file + -> ( + L.progress "@\n Initializing modified lines map from file '%s'... " changed_lines_file ; + match Utils.read_file changed_lines_file with + | Ok cl_list -> + let changed_lines = + List.fold cl_list ~init:String.Map.empty ~f:(fun acc cl_item -> + let fname, cl = String.rsplit2_exn ~on:':' cl_item in + String.Map.set acc ~key:fname ~data:(FileDiff.parse_unix_diff cl) ) + in + L.progress " done! @\n" ; + map := changed_lines + | Error _ -> + L.die UserError "Could not read file %s" changed_lines_file ) + | _ -> + L.die UserError "Missing modified lines argument" + + + let print_changed_lines () = + L.(debug Analysis Medium) "@\n--- Changed Lines Map --- " ; + String.Map.iteri !map ~f:(fun ~key:k ~data:d -> + L.(debug Analysis Medium) "\n %s --> [" k ; + List.iter d ~f:(L.(debug Analysis Medium) " %i ") ; + L.(debug Analysis Medium) " ] " ) ; + L.(debug Analysis Medium) "@\n--- End Changed Lines Map --- @\n" +end + +let pp_profiler_sample_set fmt s = + F.fprintf fmt "size = %i" (ProfilerSample.cardinal s) ; + ProfilerSample.iter (fun m -> F.fprintf fmt "@\n > %a " Typ.Procname.pp m) s + + +module TestSample = struct + let labeled_test_samples = ref [] + + let test_sample () = !labeled_test_samples + + let init_test_sample test_samples_file' = + match test_samples_file' with + | Some test_samples_file -> + L.progress "@\nReading Profiler Samples File '%s'...." test_samples_file ; + let ts = JavaProfilerSamples.from_json_file test_samples_file in + labeled_test_samples := ts + | _ -> + L.die UserError "Missing profiler samples argument" + + + let pp_map fmt () = + List.iter !labeled_test_samples ~f:(fun (label, profiler_samples) -> + F.fprintf fmt "=== Samples for %s ===@\n%a@\n=== End Samples for %s ===@\n" label + pp_profiler_sample_set profiler_samples label ) +end let in_range l range = l >= (fst range).Location.line && l <= (snd range).Location.line -let affected_methods line_range_map changed_lines = - LineRangeMap.fold +let affected_methods method_range_map changed_lines = + RangeMap.fold (fun key range acc -> - if List.exists ~f:(fun l -> in_range l range) changed_lines then ProfilerSample.add key acc + if List.exists ~f:(fun l -> in_range l range) changed_lines then + (*L.progress "@\n ADDING '%a' in affected methods..." Typ.Procname.pp key ; *) + ProfilerSample.add key acc else acc ) - line_range_map ProfilerSample.empty + method_range_map ProfilerSample.empty -let compute_affected_methods fname cfg files_changed_lines_map = - L.(debug Capture Verbose) "@\n Looking for file %s in files_changed_line_map @\n" fname ; - match String.Map.find files_changed_lines_map fname with +let compute_affected_methods_java changed_lines_map method_range_map = + let affected_methods = + String.Map.fold changed_lines_map ~init:ProfilerSample.empty ~f:(fun ~key:_ ~data acc -> + let am = affected_methods method_range_map data in + ProfilerSample.union am acc ) + in + L.progress "== Resulting Affected Methods ==@\n%a@\n== End Affected Methods ==@\n" + pp_profiler_sample_set affected_methods ; + affected_methods + + +let compute_affected_methods_clang source_file changed_lines_map method_range_map = + let fname = SourceFile.to_rel_path source_file in + L.progress "@\n Looking for file %s in changed-line map..." fname ; + match String.Map.find changed_lines_map fname with | Some changed_lines -> - let line_range_map : (Location.t * Location.t) LineRangeMap.t = LineRangeMap.empty in - let line_range_map' = - Typ.Procname.Hash.fold - (fun _ pdesc acc -> update_line_range_map pdesc acc) - cfg line_range_map - in - L.(debug Capture Verbose) "@\n Line Range Map" ; - LineRangeMap.iter - (fun key range -> - L.(debug Capture Verbose) - "@\n %a --> (%a,%a)" Typ.Procname.pp key Location.pp (fst range) Location.pp - (snd range) ) - line_range_map' ; - L.(debug Capture Verbose) "@\n End Line Range Map @\n" ; - let affected_methods = affected_methods line_range_map' changed_lines in - L.(debug Capture Verbose) "@\n == Start Printing Affected Methods == " ; - ProfilerSample.iter - (fun m -> L.(debug Capture Verbose) "@\n METHOD> %a " Typ.Procname.pp m) - affected_methods ; - L.(debug Capture Verbose) "@\n == End Printing Affected Methods == @\n" ; + L.progress " found!@\n" ; + let affected_methods = affected_methods method_range_map changed_lines in + L.progress "== Resulting Affected Methods ==@\n%a@\n== End Affected Methods ==@\n" + pp_profiler_sample_set affected_methods ; affected_methods | None -> - L.(debug Capture Verbose) - "@\n File name %s was not found in files_changed_line_map @\n" fname ; + L.progress "@\n%s not found in changed-line map. Nothing else to do for it.@\n" fname ; ProfilerSample.empty -let read_changed_lines_file changed_lines_file = - match Utils.read_file changed_lines_file with - | Ok cl_list -> - let changed_lines = - List.fold cl_list ~init:String.Map.empty ~f:(fun acc cl_item -> - let fname, cl = String.rsplit2_exn ~on:':' cl_item in - String.Map.set acc ~key:fname ~data:(FileDiff.parse_unix_diff cl) ) - in - changed_lines - | Error _ -> - String.Map.empty +let relevant_tests = ref [] +let _get_relevant_test_to_run () = !relevant_tests -let print_test_to_run test_to_run = - L.result "@\n [Result Test Determinator:] Test to run = [" ; - List.iter ~f:(L.result " %s ") test_to_run ; - L.result " ] @\n" +let print_test_to_run () = + L.progress "@\n [TEST DETERMINATOR] Relevant Tests to run = [" ; + List.iter ~f:(L.progress " %s ") !relevant_tests ; + L.progress " ] @\n" ; + let json = `List (List.map ~f:(fun t -> `String t) !relevant_tests) in + Yojson.Basic.to_file (Config.results_dir ^/ "test_determinator.json") json -let print_changed_lines changed_lines = - L.(debug Capture Verbose) "@\n Changed lines = {" ; - String.Map.iteri changed_lines ~f:(fun ~key:k ~data:d -> - L.(debug Capture Verbose) "\n %s --> [" k ; - List.iter d ~f:(L.(debug Capture Verbose) " %i ") ; - L.(debug Capture Verbose) " ] " ) ; - L.(debug Capture Verbose) "@\n } @\n" +let init_clang cfg changed_lines_file test_samples_file = + DiffLines.init_changed_lines_map changed_lines_file ; + DiffLines.print_changed_lines () ; + MethodRangeMap.create_clang_method_range_map cfg ; + L.(debug Analysis Medium) "%a@\n" MethodRangeMap.pp_map () ; + TestSample.init_test_sample test_samples_file ; + L.(debug Analysis Medium) "%a@\n" TestSample.pp_map () ; + initialized_test_determinator := true + + +let init_java changed_lines_file test_samples_file code_graph_file = + DiffLines.init_changed_lines_map changed_lines_file ; + DiffLines.print_changed_lines () ; + MethodRangeMap.create_java_method_range_map code_graph_file ; + L.(debug Analysis Medium) "%a@\n" MethodRangeMap.pp_map () ; + TestSample.init_test_sample test_samples_file ; + L.(debug Analysis Medium) "%a@\n" TestSample.pp_map () ; + initialized_test_determinator := true (* test_to_run = { n | Affected_Method /\ ts_n != 0 } *) -let test_to_run source_file cfg changed_lines_file test_samples_file = - L.(debug Capture Verbose) "@\n ***** Start Test Determinator ***** @\n" ; - let fname = SourceFile.to_rel_path source_file in - let changed_lines = read_changed_lines_file changed_lines_file in - print_changed_lines changed_lines ; - let test_samples = JavaProfilerSamples.from_json_file test_samples_file in - let affected_methods = compute_affected_methods fname cfg changed_lines in +let _test_to_run_clang source_file cfg changed_lines_file test_samples_file = + L.progress "@\n ***** Start Test Determinator for %s ***** @\n" + (SourceFile.to_string source_file) ; + if is_test_determinator_init () then () else init_clang cfg changed_lines_file test_samples_file ; + let affected_methods = + compute_affected_methods_clang source_file (DiffLines.changed_lines_map ()) + (MethodRangeMap.method_range_map ()) + in + let test_to_run = + if ProfilerSample.is_empty affected_methods then [] + else + List.fold (TestSample.test_sample ()) ~init:[] ~f:(fun acc (label, profiler_samples) -> + let intersection = ProfilerSample.inter affected_methods profiler_samples in + if ProfilerSample.is_empty intersection then acc else label :: acc ) + in + relevant_tests := List.append test_to_run !relevant_tests + + +let test_to_run_java changed_lines_file test_samples_file code_graph_file = + L.progress "@\n ***** Start Test Determinator ***** @\n" ; + if is_test_determinator_init () then () + else init_java changed_lines_file test_samples_file code_graph_file ; + let affected_methods = + compute_affected_methods_java (DiffLines.changed_lines_map ()) + (MethodRangeMap.method_range_map ()) + in let test_to_run = - List.fold test_samples ~init:[] ~f:(fun acc (label, profiler_samples) -> - let intersection = ProfilerSample.inter affected_methods profiler_samples in - if ProfilerSample.is_empty intersection then acc else label :: acc ) + if ProfilerSample.is_empty affected_methods then [] + else + List.fold (TestSample.test_sample ()) ~init:[] ~f:(fun acc (label, profiler_samples) -> + let intersection = ProfilerSample.inter affected_methods profiler_samples in + if ProfilerSample.is_empty intersection then acc else label :: acc ) in - print_test_to_run test_to_run + relevant_tests := List.append test_to_run !relevant_tests diff --git a/infer/src/java/testDeterminator.mli b/infer/src/java/testDeterminator.mli index b33f6e3ee..c49f6c9a7 100644 --- a/infer/src/java/testDeterminator.mli +++ b/infer/src/java/testDeterminator.mli @@ -7,4 +7,11 @@ * of patent rights can be found in the PATENTS file in the same directory. *) -val test_to_run : SourceFile.t -> Procdesc.t Typ.Procname.Hash.t -> string -> string -> unit +val test_to_run_java : string option -> string option -> string option -> unit + +val _test_to_run_clang : + SourceFile.t -> Procdesc.t Typ.Procname.Hash.t -> string option -> string option -> unit + +val print_test_to_run : unit -> unit + +val _get_relevant_test_to_run : unit -> string list