[Test determinator] New format for the profiler samples passed in input to TD

Reviewed By: ddino

Differential Revision: D8041736

fbshipit-source-id: 5bd8ea0
master
Martino Luca 7 years ago committed by Facebook Github Bot
parent 81436c791f
commit 858c5aab01

@ -2043,9 +2043,9 @@ and test_filtering =
and profiler_sample = and profiler_sample =
CLOpt.mk_string ~long:"profiler-sample" ~default:"" CLOpt.mk_string ~long:"profiler-sample" ~default:""
"Specifies the file containing the profiler sample when Infer is run Test Determinator mode. \ "Specifies the file containing the profiler samples when Infer is run Test Determinator mode. \
--test-determinator --modified-lines modified_line_file --profiler-sample \ --test-determinator --modified-lines modified_line_file --profiler-sample \
profiler_sample_file" profiler_samples_file"
and testing_mode = and testing_mode =

@ -278,38 +278,46 @@ let create ~classname ~methodname ~signature ~kind =
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 kind)
let create_static = create ~kind:Typ.Procname.Java.Static type labeled_profiler_sample = string * ProfilerSample.t [@@deriving compare]
let create_non_static = create ~kind:Typ.Procname.Java.Non_Static let equal_labeled_profiler_sample = [%compare.equal : labeled_profiler_sample]
let from_json json = let from_json j =
let methods = let parse_profiler_result label result =
match json with let methods =
| `Assoc [_; ("methods", `List j); _] -> match result with
j | `Assoc [_; _; _; _; ("methods", `List j); _; _] ->
| _ -> j
L.(die UserError "Unexpected JSON input for the collection of methods") | _ ->
in L.(die UserError "Unexpected JSON input for the collection of methods")
let rec parse_json j acc = in
match j with let rec parse_json j acc =
| `Assoc match j with
[ ("class", `String classname) | `Assoc
; _ [ ("class", `String classname)
; ("method", `String methodname) ; _
; ("signature", `String signature) ; ("method", `String methodname)
; _ ] ; ("signature", `String signature)
:: tl -> ; _ ]
let static_procname = create_static ~classname ~methodname ~signature in :: tl ->
let non_static_procname = create_non_static ~classname ~methodname ~signature in let procname =
parse_json tl (static_procname :: non_static_procname :: acc) create ~kind:Typ.Procname.Java.Non_Static ~classname ~methodname ~signature
| [] -> in
acc parse_json tl (procname :: acc)
| _ -> | [] ->
L.(die UserError "Unexpected JSON input for the description of a single method") acc
| _ ->
L.(die UserError "Unexpected JSON input for the description of a single method")
in
(label, ProfilerSample.of_list (parse_json methods []))
in in
parse_json methods [] match j with
| `Assoc pr ->
List.map ~f:(fun (label, result) -> parse_profiler_result label result) pr
| _ ->
L.(die UserError "Unexpected JSON input for the list of profiler results")
let from_json_string str = ProfilerSample.of_list (from_json (Yojson.Basic.from_string str)) let from_json_string str = from_json (Yojson.Basic.from_string str)
let from_json_file file = ProfilerSample.of_list (from_json (Yojson.Basic.from_file file)) let from_json_file file = from_json (Yojson.Basic.from_file file)

@ -41,6 +41,10 @@ module JNI : sig
end end
end end
val from_json_string : string -> ProfilerSample.t type labeled_profiler_sample = string * ProfilerSample.t [@@deriving compare]
val from_json_file : string -> ProfilerSample.t val equal_labeled_profiler_sample : labeled_profiler_sample -> labeled_profiler_sample -> bool
val from_json_string : string -> labeled_profiler_sample list
val from_json_file : string -> labeled_profiler_sample list

@ -78,20 +78,6 @@ let read_changed_lines_file changed_lines_file =
String.Map.empty String.Map.empty
let read_test_samples_file test_samples_file =
match Utils.read_file test_samples_file with
| Ok ts_list ->
let test_samples =
List.fold ts_list ~init:String.Map.empty ~f:(fun acc test_id ->
let test_name, path = String.lsplit2_exn ~on:':' test_id in
let tset = JavaProfilerSamples.from_json_file path in
String.Map.set acc ~key:test_name ~data:tset )
in
test_samples
| Error _ ->
String.Map.empty
let print_test_to_run test_to_run = let print_test_to_run test_to_run =
L.result "@\n [Result Test Determinator:] Test to run = [" ; L.result "@\n [Result Test Determinator:] Test to run = [" ;
List.iter ~f:(L.result " %s ") test_to_run ; List.iter ~f:(L.result " %s ") test_to_run ;
@ -113,11 +99,11 @@ let test_to_run source_file cfg changed_lines_file test_samples_file =
let fname = SourceFile.to_rel_path source_file in let fname = SourceFile.to_rel_path source_file in
let changed_lines = read_changed_lines_file changed_lines_file in let changed_lines = read_changed_lines_file changed_lines_file in
print_changed_lines changed_lines ; print_changed_lines changed_lines ;
let test_samples = read_test_samples_file test_samples_file in let test_samples = JavaProfilerSamples.from_json_file test_samples_file in
let affected_methods = compute_affected_methods fname cfg changed_lines in let affected_methods = compute_affected_methods fname cfg changed_lines in
let test_to_run = let test_to_run =
String.Map.fold test_samples ~init:[] ~f:(fun ~key ~data acc -> List.fold test_samples ~init:[] ~f:(fun acc (label, profiler_samples) ->
let intersection = ProfilerSample.inter affected_methods data in let intersection = ProfilerSample.inter affected_methods profiler_samples in
if ProfilerSample.is_empty intersection then acc else key :: acc ) if ProfilerSample.is_empty intersection then acc else label :: acc )
in in
print_test_to_run test_to_run print_test_to_run test_to_run

@ -159,90 +159,66 @@ let test_jni_to_java_type_with_invalid_input =
let test_from_json_string_with_valid_input = let test_from_json_string_with_valid_input =
let create_test input expected _ = let create_test input expected _ =
let expected = JavaProfilerSamples.ProfilerSample.of_list expected in
let found = JavaProfilerSamples.from_json_string input in let found = JavaProfilerSamples.from_json_string input in
assert_equal ~cmp:JavaProfilerSamples.ProfilerSample.equal expected found assert_equal
~cmp:(List.equal ~equal:JavaProfilerSamples.equal_labeled_profiler_sample)
expected found
in in
let input1 = "{\"whatever\": {}, \"methods\": [], \"foo\": {}}" in let input1 =
let expected1 = [] in "{\"label1\": {\"field1\": {}, \"field2\": {}, \"field3\": {}, \"field4\": {}, \"methods\": \
[], \"field6\": {},\"field7\": {}}}"
in
let expected1 = [("label1", JavaProfilerSamples.ProfilerSample.of_list [])] in
let input2 = let input2 =
"{\"whatever\": {}, \"methods\": [{\"class\": \"aaa.bbb.Ccc\", \"boo\": \"\", \"method\": \ "{\"label1\": {\"field1\": {}, \"field2\": {}, \"field3\": {}, \"field4\": {}, \"methods\": \
\"methodOne\", \"signature\": \"()V\", \"wat\": \"\"},{\"class\": \"ddd.eee.Fff\", \"boo\": \ [{\"class\": \"ggg.hhh.Iii\", \"boo\": \"\", \"method\": \"<clinit>\", \"signature\": \
\"\", \"method\": \"methodTwo\", \"signature\": \"(Ljava/lang/String;[IJ)[[C\", \"wat\": \
\"\"},{\"class\": \"ggg.hhh.Iii\", \"boo\": \"\", \"method\": \"<clinit>\", \"signature\": \
\"(Ljava/lang/String;[IJ)V\", \"wat\": \"\"},{\"class\": \"lll.mmm.Nnn\", \"boo\": \"\", \ \"(Ljava/lang/String;[IJ)V\", \"wat\": \"\"},{\"class\": \"lll.mmm.Nnn\", \"boo\": \"\", \
\"method\": \"<init>\", \"signature\": \"(Ljava/lang/String;[IJ)V\", \"wat\": \"\"}], \ \"method\": \"<init>\", \"signature\": \"(Ljava/lang/String;[IJ)V\", \"wat\": \"\"}], \
\"foo\": {}}" \"field6\": {},\"field7\": {}},\"label2\": {\"field1\": {}, \"field2\": {}, \"field3\": {}, \
\"field4\": {}, \"methods\": [{\"class\": \"aaa.bbb.Ccc\", \"boo\": \"\", \"method\": \
\"methodOne\", \"signature\": \"()V\", \"wat\": \"\"},{\"class\": \"ddd.eee.Fff\", \"boo\": \
\"\", \"method\": \"methodTwo\", \"signature\": \"(Ljava/lang/String;[IJ)[[C\", \"wat\": \
\"\"}], \"field6\": {},\"field7\": {}}}"
in in
let expected2 = let expected2 =
[ Typ.Procname.( [ ( "label1"
Java , JavaProfilerSamples.ProfilerSample.of_list
(Java.make [ Typ.Procname.(
(Typ.Name.Java.from_string "lll.mmm.Nnn") Java
None "<init>" (Java.make
[ mk_split (Some "java.lang", "String") (Typ.Name.Java.from_string "lll.mmm.Nnn")
; mk_split (None, "int[]") None "<init>"
; mk_split (None, "long") ] [ mk_split (Some "java.lang", "String")
Java.Static)) ; mk_split (None, "int[]")
; Typ.Procname.( ; mk_split (None, "long") ]
Java Java.Non_Static))
(Java.make ; Typ.Procname.(
(Typ.Name.Java.from_string "lll.mmm.Nnn") Java
None "<init>" (Java.make
[ mk_split (Some "java.lang", "String") (Typ.Name.Java.from_string "ggg.hhh.Iii")
; mk_split (None, "int[]") None "<clinit>"
; mk_split (None, "long") ] [ mk_split (Some "java.lang", "String")
Java.Non_Static)) ; mk_split (None, "int[]")
; Typ.Procname.( ; mk_split (None, "long") ]
Java Java.Non_Static)) ] )
(Java.make ; ( "label2"
(Typ.Name.Java.from_string "ggg.hhh.Iii") , JavaProfilerSamples.ProfilerSample.of_list
None "<clinit>" [ Typ.Procname.(
[ mk_split (Some "java.lang", "String") Java
; mk_split (None, "int[]") (Java.make
; mk_split (None, "long") ] (Typ.Name.Java.from_string "ddd.eee.Fff")
Java.Static)) (Some (mk_split (None, "char[][]")))
; Typ.Procname.( "methodTwo"
Java [ mk_split (Some "java.lang", "String")
(Java.make ; mk_split (None, "int[]")
(Typ.Name.Java.from_string "ggg.hhh.Iii") ; mk_split (None, "long") ]
None "<clinit>" Java.Non_Static))
[ mk_split (Some "java.lang", "String") ; Typ.Procname.(
; mk_split (None, "int[]") Java
; mk_split (None, "long") ] (Java.make
Java.Non_Static)) (Typ.Name.Java.from_string "aaa.bbb.Ccc")
; Typ.Procname.( (Some (mk_split (None, "void")))
Java "methodOne" [] Java.Non_Static)) ] ) ]
(Java.make
(Typ.Name.Java.from_string "ddd.eee.Fff")
(Some (mk_split (None, "char[][]")))
"methodTwo"
[ mk_split (Some "java.lang", "String")
; mk_split (None, "int[]")
; mk_split (None, "long") ]
Java.Static))
; Typ.Procname.(
Java
(Java.make
(Typ.Name.Java.from_string "ddd.eee.Fff")
(Some (mk_split (None, "char[][]")))
"methodTwo"
[ mk_split (Some "java.lang", "String")
; mk_split (None, "int[]")
; mk_split (None, "long") ]
Java.Non_Static))
; Typ.Procname.(
Java
(Java.make
(Typ.Name.Java.from_string "aaa.bbb.Ccc")
(Some (mk_split (None, "void")))
"methodOne" [] Java.Static))
; Typ.Procname.(
Java
(Java.make
(Typ.Name.Java.from_string "aaa.bbb.Ccc")
(Some (mk_split (None, "void")))
"methodOne" [] Java.Non_Static)) ]
in in
[("test_from_json_string_1", input1, expected1); ("test_from_json_string_2", input2, expected2)] [("test_from_json_string_1", input1, expected1); ("test_from_json_string_2", input2, expected2)]
|> List.map ~f:(fun (name, test_input, expected_output) -> |> List.map ~f:(fun (name, test_input, expected_output) ->
@ -260,7 +236,7 @@ let test_from_json_string_with_invalid_input =
; ( "test_from_json_string_2" ; ( "test_from_json_string_2"
, "{\"whatever\": {}, \"methods\": [{\"class\": \"aaa.bbb.Ccc\", \"boo\": \"\", \"method\": \ , "{\"whatever\": {}, \"methods\": [{\"class\": \"aaa.bbb.Ccc\", \"boo\": \"\", \"method\": \
\"methodOne\", \"signature\": \"()V\"}], \"foo\": {}}" \"methodOne\", \"signature\": \"()V\"}], \"foo\": {}}"
, Logging.InferUserError "Unexpected JSON input for the description of a single method" ) , Logging.InferUserError "Unexpected JSON input for the collection of methods" )
; ("test_from_json_string_3", "(", Yojson.Json_error "Line 1, bytes 0-1:\nInvalid token '('") ] ; ("test_from_json_string_3", "(", Yojson.Json_error "Line 1, bytes 0-1:\nInvalid token '('") ]
|> List.map ~f:(fun (name, test_input, expected_exception) -> |> List.map ~f:(fun (name, test_input, expected_exception) ->
name >:: create_test test_input expected_exception ) name >:: create_test test_input expected_exception )

@ -0,0 +1,50 @@
{
"label1": {
"field1": {},
"field2": {},
"field3": {},
"field4": {},
"methods": [
{
"class": "MyFavouriteClassOne",
"id": "",
"method": "methodOne",
"signature": "()V",
"src_file": ""
},
{
"class": "MyFavouriteClassTwo",
"id": "",
"method": "methodTwo",
"signature": "(I)I",
"src_file": ""
}
],
"field6": {},
"field7": {}
},
"label2": {
"field1": {},
"field2": {},
"field3": {},
"field4": {},
"methods": [
{
"class": "MyFavouriteClassXX",
"id": "",
"method": "methodOne",
"signature": "()V",
"src_file": ""
},
{
"class": "MyFavouriteClassYY",
"id": "",
"method": "methodTwo",
"signature": "(I)I",
"src_file": ""
}
],
"field6": {},
"field7": {}
}
}

@ -1,20 +0,0 @@
{
"date": "",
"methods": [
{
"class": "MyFavouriteClassOne",
"id": "",
"method": "methodOne",
"signature": "()V",
"src_file": ""
},
{
"class": "MyFavouriteClassTwo",
"id": "",
"method": "methodTwo",
"signature": "(I)I",
"src_file": ""
}
],
"profiles": []
}

@ -1,20 +0,0 @@
{
"date": "",
"methods": [
{
"class": "MyFavouriteClassXX",
"id": "",
"method": "methodOne",
"signature": "()V",
"src_file": ""
},
{
"class": "MyFavouriteClassYY",
"id": "",
"method": "methodTwo",
"signature": "(I)I",
"src_file": ""
}
],
"profiles": []
}
Loading…
Cancel
Save