From 405928ad59c0dd188748ec16853258e7897d1f19 Mon Sep 17 00:00:00 2001 From: Dino Distefano Date: Fri, 25 May 2018 03:07:07 -0700 Subject: [PATCH] [Test determinator] Improving the search of affected methods and dealing with signature Reviewed By: martinoluca Differential Revision: D8135233 fbshipit-source-id: 4479016 --- infer/src/integration/testDeterminator.ml | 51 +++++++++++++++-------- infer/src/java/JavaProfilerSamples.ml | 9 ++-- infer/src/java/JavaProfilerSamples.mli | 6 ++- infer/src/unit/JavaProfilerSamplesTest.ml | 4 +- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/infer/src/integration/testDeterminator.ml b/infer/src/integration/testDeterminator.ml index 0feeed90a..3a461b86f 100644 --- a/infer/src/integration/testDeterminator.ml +++ b/infer/src/integration/testDeterminator.ml @@ -11,6 +11,9 @@ module F = Format open JavaProfilerSamples open! IStd +(* a flag used to make the method search signature sensitive *) +let use_method_signature = false + module RangeMap = Caml.Map.Make (struct type t = Typ.Procname.t @@ -59,6 +62,12 @@ module MethodRangeMap = struct let classname, methodname = split_class_method_name decl.method_name in match decl.signature with | Some signature -> + let signature = + if use_method_signature then signature + else + (* When we should not use the signature we use 'void ()' *) + JavaProfilerSamples.JNI.void_method_with_no_arguments + in let key = JavaProfilerSamples.create ~classname ~methodname ~signature in RangeMap.add key range acc | None -> @@ -104,7 +113,7 @@ module DiffLines = struct match changed_lines_file' with | Some changed_lines_file -> ( - L.progress "@\n Initializing modified lines map from file '%s'... " changed_lines_file ; + L.progress "@\nInitializing modified lines map from file '%s'... " changed_lines_file ; match Utils.read_file changed_lines_file with | Ok cl_list -> let changed_lines = @@ -130,7 +139,7 @@ module DiffLines = struct end let pp_profiler_sample_set fmt s = - F.fprintf fmt "size = %i" (ProfilerSample.cardinal s) ; + F.fprintf fmt " (size = %i) " (ProfilerSample.cardinal s) ; ProfilerSample.iter (fun m -> F.fprintf fmt "@\n > %a " Typ.Procname.pp m) s @@ -143,7 +152,9 @@ module TestSample = struct 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 + let ts = + JavaProfilerSamples.from_json_file test_samples_file ~use_signature:use_method_signature + in labeled_test_samples := ts | _ -> L.die UserError "Missing profiler samples argument" @@ -157,35 +168,41 @@ end let in_range l range = l >= (fst range).Location.line && l <= (snd range).Location.line -let affected_methods method_range_map changed_lines = +let affected_methods method_range_map file_changed_lines changed_lines = + L.progress "@\nLooking for affected methods in file '%s' " file_changed_lines ; RangeMap.fold - (fun key range 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 + (fun key ((l1, _) as range) acc -> + let method_file = SourceFile.to_string l1.Location.file in + if + String.equal method_file file_changed_lines + && List.exists ~f:(fun l -> in_range l range) changed_lines + then ( + L.progress "@\n ->Adding '%a' in affected methods...@\n" Typ.Procname.pp key ; + ProfilerSample.add key acc ) else acc ) method_range_map ProfilerSample.empty 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 + String.Map.fold changed_lines_map ~init:ProfilerSample.empty ~f: + (fun ~key:file_changed_lines ~data acc -> + let am = affected_methods method_range_map file_changed_lines data in ProfilerSample.union am acc ) in - L.progress "== Resulting Affected Methods ==@\n%a@\n== End Affected Methods ==@\n" + L.progress "@\n\n== Resulting Affected Methods ==%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 ; + L.progress "@\nLooking for file %s in changed-line map..." fname ; match String.Map.find changed_lines_map fname with | Some changed_lines -> 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" + let affected_methods = affected_methods method_range_map fname changed_lines in + L.progress "@\n\n== Resulting Affected Methods ==@\n%a@\n== End Affected Methods ==@\n" pp_profiler_sample_set affected_methods ; affected_methods | None -> @@ -198,7 +215,7 @@ let relevant_tests = ref [] let _get_relevant_test_to_run () = !relevant_tests let print_test_to_run () = - L.progress "@\n [TEST DETERMINATOR] Relevant Tests 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 @@ -227,7 +244,7 @@ let init_java changed_lines_file test_samples_file code_graph_file = (* test_to_run = { n | Affected_Method /\ ts_n != 0 } *) let _test_to_run_clang source_file cfg changed_lines_file test_samples_file = - L.progress "@\n ***** Start Test Determinator for %s ***** @\n" + 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 = @@ -245,7 +262,7 @@ let _test_to_run_clang source_file cfg changed_lines_file test_samples_file = let test_to_run_java changed_lines_file test_samples_file code_graph_file = - L.progress "@\n ***** Start Test Determinator ***** @\n" ; + 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 = diff --git a/infer/src/java/JavaProfilerSamples.ml b/infer/src/java/JavaProfilerSamples.ml index f10482926..6650b89d2 100644 --- a/infer/src/java/JavaProfilerSamples.ml +++ b/infer/src/java/JavaProfilerSamples.ml @@ -31,6 +31,8 @@ module JNI = struct let equal = [%compare.equal : t] + let void_method_with_no_arguments = "()V" + type non_terminal_symbol = SymArray | SymMethodOpen | SymMethodClose | SymMethod of t list type symbol = Terminal of t | NonTerminal of non_terminal_symbol @@ -284,7 +286,7 @@ type labeled_profiler_sample = string * ProfilerSample.t [@@deriving compare] let equal_labeled_profiler_sample = [%compare.equal : labeled_profiler_sample] -let from_json j = +let from_json j ~use_signature = let parse_profiler_result label result = let methods = match result with @@ -302,6 +304,7 @@ let from_json j = ; ("signature", `String signature) ; _ ] :: tl -> + let signature = if use_signature then signature else JNI.void_method_with_no_arguments in let procname = create ~classname ~methodname ~signature in parse_json tl (procname :: acc) | [] -> @@ -318,6 +321,6 @@ let from_json j = L.(die UserError "Unexpected JSON input for the list of profiler results") -let from_json_string str = from_json (Yojson.Basic.from_string str) +let from_json_string str ~use_signature = from_json (Yojson.Basic.from_string str) ~use_signature -let from_json_file file = from_json (Yojson.Basic.from_file file) +let from_json_file file ~use_signature = from_json (Yojson.Basic.from_file file) ~use_signature diff --git a/infer/src/java/JavaProfilerSamples.mli b/infer/src/java/JavaProfilerSamples.mli index bfb11abd4..65d865b03 100644 --- a/infer/src/java/JavaProfilerSamples.mli +++ b/infer/src/java/JavaProfilerSamples.mli @@ -12,6 +12,8 @@ open! IStd module ProfilerSample : Caml.Set.S with type elt = Typ.Procname.t module JNI : sig + val void_method_with_no_arguments : string + module VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY : sig type t = | Boolean @@ -45,8 +47,8 @@ type labeled_profiler_sample = string * ProfilerSample.t [@@deriving compare] val equal_labeled_profiler_sample : labeled_profiler_sample -> labeled_profiler_sample -> bool -val from_json_string : string -> labeled_profiler_sample list +val from_json_string : string -> use_signature:bool -> labeled_profiler_sample list -val from_json_file : string -> labeled_profiler_sample list +val from_json_file : string -> use_signature:bool -> labeled_profiler_sample list val create : classname:string -> methodname:string -> signature:string -> ProfilerSample.elt diff --git a/infer/src/unit/JavaProfilerSamplesTest.ml b/infer/src/unit/JavaProfilerSamplesTest.ml index ce26fbf4a..9f01d0913 100644 --- a/infer/src/unit/JavaProfilerSamplesTest.ml +++ b/infer/src/unit/JavaProfilerSamplesTest.ml @@ -159,7 +159,7 @@ let test_jni_to_java_type_with_invalid_input = let test_from_json_string_with_valid_input = let create_test input expected _ = - let found = JavaProfilerSamples.from_json_string input in + let found = JavaProfilerSamples.from_json_string input ~use_signature:true in assert_equal ~cmp:(List.equal ~equal:JavaProfilerSamples.equal_labeled_profiler_sample) expected found @@ -227,7 +227,7 @@ let test_from_json_string_with_valid_input = let test_from_json_string_with_invalid_input = let create_test input expected_exception _ = - let run () = JavaProfilerSamples.from_json_string input in + let run () = JavaProfilerSamples.from_json_string input ~use_signature:true in assert_raises expected_exception run in [ ( "test_from_json_string_1"