@@ -325,7 +325,7 @@ def extract_code_coverage_data(code_coverage_summary):
325
325
return line_total_summary
326
326
327
327
328
- def prepare_code_coverage_dict (
328
+ def prepare_code_coverage_data (
329
329
code_coverage_summary , project_name : str , date_str : str ,
330
330
project_language : str ) -> Optional [Dict [str , Any ]]:
331
331
"""Gets coverage URL and line coverage total of a project"""
@@ -472,7 +472,7 @@ def extract_local_project_data(project_name, oss_fuzz_path,
472
472
project_name
473
473
}
474
474
475
- code_coverage_data_dict = prepare_code_coverage_dict (
475
+ code_coverage_data_dict = prepare_code_coverage_data (
476
476
code_coverage_summary , project_name , '' , project_language )
477
477
478
478
if cov_fuzz_stats is not None :
@@ -737,7 +737,7 @@ def extract_project_data(project_name, date_str, should_include_details,
737
737
'project_name' : project_name
738
738
}
739
739
740
- code_coverage_data_dict = prepare_code_coverage_dict (
740
+ code_coverage_data_dict = prepare_code_coverage_data (
741
741
code_coverage_summary , project_name , date_str , project_language )
742
742
743
743
per_fuzzer_cov = {}
@@ -748,10 +748,19 @@ def extract_project_data(project_name, date_str, should_include_details,
748
748
749
749
amount_of_fuzzers = len (all_fuzzers )
750
750
for ff in all_fuzzers :
751
+ try :
752
+ fuzzer_corpus_size = oss_fuzz .get_fuzzer_corpus_size (
753
+ project_name , date_str .replace ("-" , "" ), ff ,
754
+ introspector_report )
755
+ except :
756
+ fuzzer_corpus_size = None
757
+
751
758
try :
752
759
fuzzer_cov = oss_fuzz .get_fuzzer_code_coverage_summary (
753
760
project_name , date_str .replace ("-" , "" ), ff )
754
761
fuzzer_cov_data = extract_code_coverage_data (fuzzer_cov )
762
+ if fuzzer_cov_data is not None :
763
+ fuzzer_cov_data ['corpus_size' ] = fuzzer_corpus_size
755
764
per_fuzzer_cov [ff ] = fuzzer_cov_data
756
765
except :
757
766
pass
@@ -919,8 +928,36 @@ def extend_db_timestamps(db_timestamp, output_directory):
919
928
json .dump (existing_timestamps , f )
920
929
921
930
931
+ def per_fuzzer_coverage_has_degraded (fuzzer_data : List [Dict [str , Any ]],
932
+ project_name : str ,
933
+ ff : str ) -> List [Dict [str , str ]]:
934
+ """Go through the fuzzer data and find coverage drops."""
935
+
936
+ def get_url (date ):
937
+ report_url = oss_fuzz .get_fuzzer_code_coverage_summary_url (
938
+ project_name , date .replace ('-' , '' ), ff )
939
+ report_url = report_url [:- len ('summary.json' )] + 'index.html'
940
+ return report_url
941
+
942
+ res = []
943
+ for yesterday , today in zip (fuzzer_data [:- 1 ], fuzzer_data [1 :]):
944
+ if yesterday ['percentage' ] - today [
945
+ 'percentage' ] > FUZZER_COVERAGE_IS_DEGRADED :
946
+ res .append ({
947
+ 'before_date' : yesterday ['date' ],
948
+ 'before_url' : get_url (yesterday ['date' ]),
949
+ 'before_perc' : yesterday ['percentage' ],
950
+ 'current_date' : today ['date' ],
951
+ 'current_url' : get_url (today ['date' ]),
952
+ 'current_perc' : today ['percentage' ],
953
+ })
954
+
955
+ return res
956
+
957
+
922
958
def per_fuzzer_coverage_analysis (project_name : str ,
923
- coverages : Dict [str , List [Tuple [int , str ]]],
959
+ per_fuzzer_data : Dict [str , List [Dict [str ,
960
+ Any ]]],
924
961
lost_fuzzers ):
925
962
"""Go through the recent coverage results and combine them into a short summary.
926
963
Including an assessment if the fuzzer got worse over time.
@@ -932,34 +969,47 @@ def per_fuzzer_coverage_analysis(project_name: str,
932
969
# at per fuzzer coverage, which is should already be normalized to what
933
970
# can be reached.
934
971
# TODO What would be a good percentage to mark as coverage degradation,
935
- # taking 5% for now but should be observed, maybe per it should be
972
+ # taking 5% for now but should be observed, maybe it should be
936
973
# configurable per project as well.
937
974
results = {}
938
- for ff , data in coverages .items ():
975
+ for ff , data in per_fuzzer_data .items ():
939
976
if len (data ) > 0 :
940
- values = [dd [0 ] for dd in data ]
941
- dates = [dd [1 ] for dd in data ]
942
- latest_date_with_value = next (dd [1 ] for dd in reversed (data )
943
- if dd [0 ] is not None )
977
+ percentages = [dd ['percentage' ] for dd in data ]
978
+ dates = [dd ['date' ] for dd in data ]
979
+ totals = [dd ['total' ] for dd in data ]
980
+ covered = [dd ['covered' ] for dd in data ]
981
+ corpus_size = [dd ['corpus_size' ] for dd in data ]
982
+ latest_date_with_value = next (dd ['date' ] for dd in reversed (data )
983
+ if dd ['percentage' ] is not None )
944
984
if latest_date_with_value is not None :
945
985
report_url = oss_fuzz .get_fuzzer_code_coverage_summary_url (
946
986
project_name , latest_date_with_value .replace ('-' , '' ), ff )
947
987
report_url = report_url [:- len ('summary.json' )] + 'index.html'
948
988
else :
949
989
report_url = None
950
- max_cov = max (values [:- 1 ], default = 0 )
951
- avg_cov = round (statistics .fmean (values ), 2 )
952
- current = values [- 1 ]
990
+ max_cov = max (percentages [:- 1 ], default = 0 )
991
+ avg_cov = round (statistics .fmean (percentages ), 2 )
992
+ current = percentages [- 1 ]
993
+ try :
994
+ days_degraded = per_fuzzer_coverage_has_degraded (
995
+ data , project_name , ff )
996
+ except :
997
+ days_degraded = []
953
998
results [ff ] = {
954
999
'report_url' : report_url ,
955
1000
'report_date' : latest_date_with_value ,
956
- 'coverages_values' : values ,
1001
+ 'hashed_name' : str (hash (ff )),
1002
+ 'coverages_perc' : percentages ,
1003
+ 'coverages_totals' : totals ,
1004
+ 'coverages_covered' : covered ,
1005
+ 'coverages_corpus' : corpus_size ,
957
1006
'coverages_dates' : dates ,
958
1007
'max' : max_cov ,
959
1008
'avg' : avg_cov ,
960
1009
'current' : current ,
961
- 'has_degraded ' :
1010
+ 'max_has_degraded ' :
962
1011
(max_cov - current ) > FUZZER_COVERAGE_IS_DEGRADED ,
1012
+ 'days_degraded' : days_degraded ,
963
1013
'got_lost' : ff in lost_fuzzers ,
964
1014
}
965
1015
return results
@@ -999,7 +1049,18 @@ def calculate_recent_results(projects_with_new_results, timestamps,
999
1049
except :
1000
1050
perc = 0
1001
1051
1002
- per_fuzzer_coverages [ff ].append ((perc , do ))
1052
+ per_fuzzer_coverages [ff ].append ({
1053
+ 'corpus_size' :
1054
+ cov_data ['corpus_size' ],
1055
+ 'covered' :
1056
+ cov_data ['covered' ],
1057
+ 'total' :
1058
+ cov_data ['count' ],
1059
+ 'percentage' :
1060
+ perc ,
1061
+ 'date' :
1062
+ do
1063
+ })
1003
1064
except :
1004
1065
continue
1005
1066
@@ -1411,6 +1472,7 @@ def setup_webapp_cache() -> None:
1411
1472
os .mkdir ("extracted-db-archive" )
1412
1473
1413
1474
db_archive .extractall ("extracted-db-archive" )
1475
+
1414
1476
logger .info ("Extracted it all" )
1415
1477
1416
1478
# Copy over the files
0 commit comments