def record_stats(self): """Use fuzzer.get_stats if it is offered, validate the stats and then save them to a file so that they will be synced to the filestore.""" # TODO(metzman): Make this more resilient so we don't wait forever and # so that breakages in stats parsing doesn't break runner. fuzzer_module = get_fuzzer_module(self.fuzzer) fuzzer_module_get_stats = getattr(fuzzer_module, 'get_stats', None) if fuzzer_module_get_stats is None: # Stats support is optional. return try: output_corpus = environment.get('OUTPUT_CORPUS_DIR') stats_json_str = fuzzer_module_get_stats(output_corpus, self.log_file) except Exception: # pylint: disable=broad-except logs.error('Call to %d failed.', fuzzer_module_get_stats) return try: fuzzer_stats.validate_fuzzer_stats(stats_json_str) except (ValueError, json.decoder.JSONDecodeError): logs.error('Stats are invalid.') return stats_filename = experiment_utils.get_stats_filename(self.cycle) stats_path = os.path.join(self.results_dir, stats_filename) with open(stats_path, 'w') as stats_file_handle: stats_file_handle.write(stats_json_str)
def get_fuzzer_stats(self, cycle): """Get the fuzzer stats for |cycle|.""" stats_filename = experiment_utils.get_stats_filename(cycle) stats_filestore_path = exp_path.filestore( os.path.join(self.trial_dir, stats_filename)) try: return get_fuzzer_stats(stats_filestore_path) except (ValueError, json.decoder.JSONDecodeError): logger.error('Stats are invalid.') return None