[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 =
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 \
profiler_sample_file"
profiler_samples_file"
and testing_mode =

@ -278,14 +278,15 @@ let create ~classname ~methodname ~signature ~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 parse_profiler_result label result =
let methods =
match json with
| `Assoc [_; ("methods", `List j); _] ->
match result with
| `Assoc [_; _; _; _; ("methods", `List j); _; _] ->
j
| _ ->
L.(die UserError "Unexpected JSON input for the collection of methods")
@ -299,17 +300,24 @@ let from_json json =
; ("signature", `String signature)
; _ ]
:: tl ->
let static_procname = create_static ~classname ~methodname ~signature in
let non_static_procname = create_non_static ~classname ~methodname ~signature in
parse_json tl (static_procname :: non_static_procname :: acc)
let procname =
create ~kind:Typ.Procname.Java.Non_Static ~classname ~methodname ~signature
in
parse_json tl (procname :: acc)
| [] ->
acc
| _ ->
L.(die UserError "Unexpected JSON input for the description of a single method")
in
parse_json methods []
(label, ProfilerSample.of_list (parse_json methods []))
in
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
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
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 =
L.result "@\n [Result Test Determinator:] 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 changed_lines = read_changed_lines_file changed_lines_file in
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 test_to_run =
String.Map.fold test_samples ~init:[] ~f:(fun ~key ~data acc ->
let intersection = ProfilerSample.inter affected_methods data in
if ProfilerSample.is_empty intersection then acc else key :: acc )
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 )
in
print_test_to_run test_to_run

@ -159,32 +159,31 @@ let test_jni_to_java_type_with_invalid_input =
let test_from_json_string_with_valid_input =
let create_test input expected _ =
let expected = JavaProfilerSamples.ProfilerSample.of_list expected 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
let input1 = "{\"whatever\": {}, \"methods\": [], \"foo\": {}}" in
let expected1 = [] in
let input1 =
"{\"label1\": {\"field1\": {}, \"field2\": {}, \"field3\": {}, \"field4\": {}, \"methods\": \
[], \"field6\": {},\"field7\": {}}}"
in
let expected1 = [("label1", JavaProfilerSamples.ProfilerSample.of_list [])] in
let input2 =
"{\"whatever\": {}, \"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\": \
\"\"},{\"class\": \"ggg.hhh.Iii\", \"boo\": \"\", \"method\": \"<clinit>\", \"signature\": \
"{\"label1\": {\"field1\": {}, \"field2\": {}, \"field3\": {}, \"field4\": {}, \"methods\": \
[{\"class\": \"ggg.hhh.Iii\", \"boo\": \"\", \"method\": \"<clinit>\", \"signature\": \
\"(Ljava/lang/String;[IJ)V\", \"wat\": \"\"},{\"class\": \"lll.mmm.Nnn\", \"boo\": \"\", \
\"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
let expected2 =
[ ( "label1"
, JavaProfilerSamples.ProfilerSample.of_list
[ Typ.Procname.(
Java
(Java.make
(Typ.Name.Java.from_string "lll.mmm.Nnn")
None "<init>"
[ 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 "lll.mmm.Nnn")
@ -201,27 +200,10 @@ let test_from_json_string_with_valid_input =
[ 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 "ggg.hhh.Iii")
None "<clinit>"
[ 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 "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.Non_Static)) ] )
; ( "label2"
, JavaProfilerSamples.ProfilerSample.of_list
[ Typ.Procname.(
Java
(Java.make
(Typ.Name.Java.from_string "ddd.eee.Fff")
@ -236,13 +218,7 @@ let test_from_json_string_with_valid_input =
(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)) ]
"methodOne" [] Java.Non_Static)) ] ) ]
in
[("test_from_json_string_1", input1, expected1); ("test_from_json_string_2", input2, expected2)]
|> 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"
, "{\"whatever\": {}, \"methods\": [{\"class\": \"aaa.bbb.Ccc\", \"boo\": \"\", \"method\": \
\"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 '('") ]
|> List.map ~f:(fun (name, 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