def test_fuzz(self): """Test fuzz.""" engine_impl = engine.LibFuzzerEngine() options = engine.LibFuzzerOptions( '/corpus', ['-arg=1', '-timeout=123', '-dict=blah.dict', '-max_len=9001'], [], ['/corpus'], {}, False, False) with open(os.path.join(TEST_DIR, 'crash.txt')) as f: fuzz_output = f.read() def mock_fuzz(*args, **kwargs): # pylint: disable=unused-argument """Mock fuzz.""" self.fs.create_file('/fuzz-inputs/temp-9001/new/A') self.fs.create_file('/fuzz-inputs/temp-9001/new/B') return new_process.ProcessResult(command='command', return_code=0, output=fuzz_output, time_executed=2.0, timed_out=False) def mock_merge(*args, **kwargs): # pylint: disable=unused-argument """Mock merge.""" self.fs.create_file('/fuzz-inputs/temp-9001/merge-corpus/A') return new_process.ProcessResult(command='merge-command', return_code=0, output='merge', time_executed=2.0, timed_out=False) self.mock.fuzz.side_effect = mock_fuzz self.mock.merge.side_effect = mock_merge result = engine_impl.fuzz('/target', options, '/fake', 3600) self.assertEqual(1, len(result.crashes)) self.assertEqual(fuzz_output, result.logs) crash = result.crashes[0] self.assertEqual( '/fake/crash-1e15825e6f0b2240a5af75d84214adda1b6b5340', crash.input_path) self.assertEqual(fuzz_output, crash.stacktrace) self.assertItemsEqual(['-arg=1', '-timeout=123'], crash.reproduce_args) self.assertEqual(2, crash.crash_time) self.mock.fuzz.assert_called_with( mock.ANY, ['/fuzz-inputs/temp-9001/new', '/corpus'], additional_args=[ '-arg=1', '-timeout=123', '-dict=blah.dict', '-max_len=9001', '-artifact_prefix=/fake/' ], extra_env={}, fuzz_timeout=1470.0) self.mock.merge.assert_called_with( mock.ANY, [ '/fuzz-inputs/temp-9001/merge-corpus', '/fuzz-inputs/temp-9001/new', '/corpus' ], additional_args=['-arg=1', '-timeout=123'], merge_timeout=1800.0, tmp_dir='/fuzz-inputs/temp-9001/merge-workdir') self.assertDictEqual( { 'actual_duration': 2, 'average_exec_per_sec': 21, 'bad_instrumentation': 0, 'corpus_crash_count': 0, 'corpus_size': 0, 'crash_count': 1, 'dict_used': 1, 'edge_coverage': 1603, 'edges_total': 398467, 'expected_duration': 1450, 'feature_coverage': 3572, 'fuzzing_time_percent': 0.13793103448275862, 'initial_edge_coverage': 1603, 'initial_feature_coverage': 3572, 'leak_count': 0, 'log_lines_from_engine': 2, 'log_lines_ignored': 67, 'log_lines_unwanted': 0, 'manual_dict_size': 0, 'max_len': 9001, 'merge_edge_coverage': 0, 'new_edges': 0, 'new_features': 0, 'new_units_added': 1, 'new_units_generated': 0, 'number_of_executed_units': 1249, 'oom_count': 0, 'peak_rss_mb': 1197, 'recommended_dict_size': 0, 'slow_unit_count': 0, 'slow_units_count': 0, 'slowest_unit_time_sec': 0, 'startup_crash_count': 0, # TODO(ochang): Move strategy stats to common place, rather than in # engine implementation. 'strategy_corpus_mutations_ml_rnn': 0, 'strategy_corpus_mutations_radamsa': 0, 'strategy_corpus_subset': 0, 'strategy_dataflow_tracing': 0, 'strategy_fork': 0, 'strategy_mutator_plugin': 0, 'strategy_random_max_len': 0, 'strategy_recommended_dict': 0, 'strategy_selection_method': 'default', 'strategy_value_profile': 0, 'timeout_count': 0, 'timeout_limit': 123, }, result.stats)
def test_fuzz(self): """Test fuzz.""" engine_impl = engine.LibFuzzerEngine() options = engine.LibFuzzerOptions( "/corpus", ["-arg=1", "-timeout=123", "-dict=blah.dict", "-max_len=9001"], [], ["/corpus"], {}, False, False, ) with open(os.path.join(TEST_DIR, "crash.txt")) as f: fuzz_output = f.read() def mock_fuzz(*args, **kwargs): # pylint: disable=unused-argument """Mock fuzz.""" self.fs.create_file("/fuzz-inputs/temp-9001/new/A") self.fs.create_file("/fuzz-inputs/temp-9001/new/B") return new_process.ProcessResult( command="command", return_code=0, output=fuzz_output, time_executed=2.0, timed_out=False, ) # Record the merge calls manually as the mock module duplicates the second # call and overwrites the first call arguments. mock_merge_calls = [] def mock_merge(*args, **kwargs): # pylint: disable=unused-argument """Mock merge.""" mock_merge_calls.append(self.mock.merge.mock_calls[-1]) self.assertTrue(len(mock_merge_calls) <= 2) merge_output_file = "merge_step_%d.txt" % len(mock_merge_calls) with open(os.path.join(TEST_DIR, merge_output_file)) as f: merge_output = f.read() self.fs.create_file("/fuzz-inputs/temp-9001/merge-corpus/A") return new_process.ProcessResult( command="merge-command", return_code=0, output=merge_output, time_executed=2.0, timed_out=False, ) self.mock.fuzz.side_effect = mock_fuzz self.mock.merge.side_effect = mock_merge result = engine_impl.fuzz("/target", options, "/fake", 3600) self.assertEqual(1, len(result.crashes)) self.assertEqual(fuzz_output, result.logs) crash = result.crashes[0] self.assertEqual("/fake/crash-1e15825e6f0b2240a5af75d84214adda1b6b5340", crash.input_path) self.assertEqual(fuzz_output, crash.stacktrace) self.assertItemsEqual(["-arg=1", "-timeout=60"], crash.reproduce_args) self.assertEqual(2, crash.crash_time) self.mock.fuzz.assert_called_with( mock.ANY, ["/fuzz-inputs/temp-9001/new", "/corpus"], additional_args=[ "-arg=1", "-timeout=123", "-dict=blah.dict", "-max_len=9001", ], artifact_prefix="/fake", extra_env={}, fuzz_timeout=1470.0, ) self.assertEqual(2, len(mock_merge_calls)) # Main things to test are: # 1) The new corpus directory is used in the second call only. # 2) the merge contro file is explicitly specified for both calls. mock_merge_calls[0].assert_called_with( mock.ANY, ["/fuzz-inputs/temp-9001/merge-corpus", "/corpus"], additional_args=[ "-arg=1", "-timeout=123", "-merge_control_file=/fuzz-inputs/temp-9001/merge-workdir/MCF", ], artifact_prefix=None, merge_timeout=1800.0, tmp_dir="/fuzz-inputs/temp-9001/merge-workdir", ) mock_merge_calls[1].assert_called_with( mock.ANY, [ "/fuzz-inputs/temp-9001/merge-corpus", "/corpus", "/fuzz-inputs/temp-9001/new", ], additional_args=[ "-arg=1", "-timeout=123", "-merge_control_file=/fuzz-inputs/temp-9001/merge-workdir/MCF", ], artifact_prefix=None, merge_timeout=1800.0, tmp_dir="/fuzz-inputs/temp-9001/merge-workdir", ) self.assertDictEqual( { "actual_duration": 2, "average_exec_per_sec": 21, "bad_instrumentation": 0, "corpus_crash_count": 0, "corpus_size": 0, "crash_count": 1, "dict_used": 1, "edge_coverage": 411, "edges_total": 398467, "expected_duration": 1450, "feature_coverage": 1873, "fuzzing_time_percent": 0.13793103448275862, "initial_edge_coverage": 410, "initial_feature_coverage": 1869, "leak_count": 0, "log_lines_from_engine": 2, "log_lines_ignored": 67, "log_lines_unwanted": 0, "manual_dict_size": 0, "max_len": 9001, "merge_edge_coverage": 0, "new_edges": 1, "new_features": 4, "new_units_added": 1, "new_units_generated": 0, "number_of_executed_units": 1249, "oom_count": 0, "peak_rss_mb": 1197, "recommended_dict_size": 0, "slow_unit_count": 0, "slow_units_count": 0, "slowest_unit_time_sec": 0, "startup_crash_count": 0, "strategy_corpus_mutations_ml_rnn": 0, "strategy_corpus_mutations_radamsa": 0, "strategy_corpus_subset": 0, "strategy_dataflow_tracing": 0, "strategy_fork": 0, "strategy_mutator_plugin": 0, "strategy_random_max_len": 0, "strategy_recommended_dict": 0, "strategy_selection_method": "default", "strategy_value_profile": 0, "timeout_count": 0, "timeout_limit": 123, }, result.stats, )
def test_fuzz(self): """Test fuzz.""" engine_impl = engine.LibFuzzerEngine() options = engine.LibFuzzerOptions( '/corpus', ['-arg=1', '-timeout=123', '-dict=blah.dict', '-max_len=9001'], [], ['/corpus'], {}, False, False) with open(os.path.join(TEST_DIR, 'crash.txt')) as f: fuzz_output = f.read() def mock_fuzz(*args, **kwargs): # pylint: disable=unused-argument """Mock fuzz.""" self.fs.create_file('/fuzz-inputs/temp-9001/new/A') self.fs.create_file('/fuzz-inputs/temp-9001/new/B') return new_process.ProcessResult( command='command', return_code=0, output=fuzz_output, time_executed=2.0, timed_out=False) # Record the merge calls manually as the mock module duplicates the second # call and overwrites the first call arguments. mock_merge_calls = [] def mock_merge(*args, **kwargs): # pylint: disable=unused-argument """Mock merge.""" mock_merge_calls.append(self.mock.merge.mock_calls[-1]) self.assertTrue(len(mock_merge_calls) <= 2) merge_output_file = 'merge_step_%d.txt' % len(mock_merge_calls) with open(os.path.join(TEST_DIR, merge_output_file)) as f: merge_output = f.read() self.fs.create_file('/fuzz-inputs/temp-9001/merge-corpus/A') return new_process.ProcessResult( command='merge-command', return_code=0, output=merge_output, time_executed=2.0, timed_out=False) self.mock.fuzz.side_effect = mock_fuzz self.mock.merge.side_effect = mock_merge result = engine_impl.fuzz('/target', options, '/fake', 3600) self.assertEqual(1, len(result.crashes)) self.assertEqual(fuzz_output, result.logs) crash = result.crashes[0] self.assertEqual('/fake/crash-1e15825e6f0b2240a5af75d84214adda1b6b5340', crash.input_path) self.assertEqual(fuzz_output, crash.stacktrace) six.assertCountEqual(self, ['-arg=1', '-timeout=60'], crash.reproduce_args) self.assertEqual(2, crash.crash_time) self.mock.fuzz.assert_called_with( mock.ANY, ['/fuzz-inputs/temp-9001/new', '/corpus'], additional_args=[ '-arg=1', '-timeout=123', '-dict=blah.dict', '-max_len=9001', ], artifact_prefix='/fake', extra_env={}, fuzz_timeout=1470.0) self.assertEqual(2, len(mock_merge_calls)) # Main things to test are: # 1) The new corpus directory is used in the second call only. # 2) the merge contro file is explicitly specified for both calls. mock_merge_calls[0].assert_called_with( mock.ANY, [ '/fuzz-inputs/temp-9001/merge-corpus', '/corpus', ], additional_args=[ '-arg=1', '-timeout=123', '-merge_control_file=/fuzz-inputs/temp-9001/merge-workdir/MCF', ], artifact_prefix=None, merge_timeout=1800.0, tmp_dir='/fuzz-inputs/temp-9001/merge-workdir') mock_merge_calls[1].assert_called_with( mock.ANY, [ '/fuzz-inputs/temp-9001/merge-corpus', '/corpus', '/fuzz-inputs/temp-9001/new', ], additional_args=[ '-arg=1', '-timeout=123', '-merge_control_file=/fuzz-inputs/temp-9001/merge-workdir/MCF', ], artifact_prefix=None, merge_timeout=1800.0, tmp_dir='/fuzz-inputs/temp-9001/merge-workdir') self.assertDictEqual({ 'actual_duration': 2, 'average_exec_per_sec': 21, 'bad_instrumentation': 0, 'corpus_crash_count': 0, 'corpus_size': 0, 'crash_count': 1, 'dict_used': 1, 'edge_coverage': 411, 'edges_total': 398467, 'expected_duration': 1450, 'feature_coverage': 1873, 'fuzzing_time_percent': 0.13793103448275862, 'initial_edge_coverage': 410, 'initial_feature_coverage': 1869, 'leak_count': 0, 'log_lines_from_engine': 2, 'log_lines_ignored': 67, 'log_lines_unwanted': 0, 'manual_dict_size': 0, 'max_len': 9001, 'merge_edge_coverage': 0, 'new_edges': 1, 'new_features': 4, 'new_units_added': 1, 'new_units_generated': 0, 'number_of_executed_units': 1249, 'oom_count': 0, 'peak_rss_mb': 1197, 'recommended_dict_size': 0, 'slow_unit_count': 0, 'slow_units_count': 0, 'slowest_unit_time_sec': 0, 'startup_crash_count': 0, 'strategy_corpus_mutations_ml_rnn': 0, 'strategy_corpus_mutations_radamsa': 0, 'strategy_corpus_subset': 0, 'strategy_dataflow_tracing': 0, 'strategy_entropic': 0, 'strategy_fork': 0, 'strategy_mutator_plugin': 0, 'strategy_mutator_plugin_radamsa': 0, 'strategy_peach_grammar_mutation': '', 'strategy_random_max_len': 0, 'strategy_recommended_dict': 0, 'strategy_selection_method': 'default', 'strategy_value_profile': 0, 'timeout_count': 0, 'timeout_limit': 123, }, result.stats)