|
| 1 | +"""Tests for the fuzzer runner module.""" |
| 2 | + |
| 3 | +from unittest.mock import MagicMock, patch |
| 4 | + |
| 5 | +from buttercup.fuzzer_runner.runner import Conf, Runner |
| 6 | + |
| 7 | + |
| 8 | +class TestRunner: |
| 9 | + """Tests for the Runner class.""" |
| 10 | + |
| 11 | + @patch("buttercup.fuzzer_runner.runner.patched_temp_dir") |
| 12 | + @patch("buttercup.fuzzer_runner.runner.scratch_cwd") |
| 13 | + @patch("os.makedirs") |
| 14 | + def test_run_fuzzer_initializes_engine(self, mock_makedirs, mock_scratch_cwd, mock_patched_temp_dir): |
| 15 | + """Test run_fuzzer""" |
| 16 | + from buttercup.common.types import FuzzConfiguration |
| 17 | + from clusterfuzz._internal.bot.fuzzers.libFuzzer import engine as libfuzzer_engine |
| 18 | + |
| 19 | + mock_patched_temp_dir.return_value.__enter__ = MagicMock() |
| 20 | + mock_patched_temp_dir.return_value.__exit__ = MagicMock(return_value=False) |
| 21 | + mock_scratch_cwd.return_value.__enter__ = MagicMock() |
| 22 | + mock_scratch_cwd.return_value.__exit__ = MagicMock(return_value=False) |
| 23 | + |
| 24 | + # Mock the engine methods that would fail without a real fuzzer binary |
| 25 | + mock_opts = MagicMock() |
| 26 | + mock_opts.corpus_dir = "/corpus" |
| 27 | + mock_opts.arguments = [] |
| 28 | + mock_opts.strategies = [] |
| 29 | + |
| 30 | + mock_result = MagicMock() |
| 31 | + mock_result.crashes = [] |
| 32 | + mock_result.logs = "test" |
| 33 | + mock_result.stats = {} |
| 34 | + mock_result.time_executed = 1.0 |
| 35 | + mock_result.timed_out = False |
| 36 | + |
| 37 | + with ( |
| 38 | + patch.object(libfuzzer_engine.Engine, "prepare", return_value=mock_opts), |
| 39 | + patch.object(libfuzzer_engine.Engine, "fuzz", return_value=mock_result), |
| 40 | + ): |
| 41 | + conf = Conf(timeout=60) |
| 42 | + runner = Runner(conf) |
| 43 | + fuzzconf = FuzzConfiguration( |
| 44 | + corpus_dir="/corpus", |
| 45 | + target_path="/target", |
| 46 | + engine="libfuzzer", |
| 47 | + sanitizer="address", |
| 48 | + ) |
| 49 | + |
| 50 | + result = runner.run_fuzzer(fuzzconf) |
| 51 | + |
| 52 | + assert result.crashes == [] |
| 53 | + assert result.timed_out is False |
| 54 | + |
| 55 | + @patch("buttercup.fuzzer_runner.runner.scratch_dir") |
| 56 | + @patch("buttercup.fuzzer_runner.runner.patched_temp_dir") |
| 57 | + @patch("buttercup.fuzzer_runner.runner.scratch_cwd") |
| 58 | + def test_merge_corpus_initializes_engine(self, mock_scratch_cwd, mock_patched_temp_dir, mock_scratch_dir): |
| 59 | + """Test merge_corpus.""" |
| 60 | + from buttercup.common.types import FuzzConfiguration |
| 61 | + from clusterfuzz._internal.bot.fuzzers.libFuzzer import engine as libfuzzer_engine |
| 62 | + |
| 63 | + mock_patched_temp_dir.return_value.__enter__ = MagicMock() |
| 64 | + mock_patched_temp_dir.return_value.__exit__ = MagicMock(return_value=False) |
| 65 | + mock_scratch_cwd.return_value.__enter__ = MagicMock() |
| 66 | + mock_scratch_cwd.return_value.__exit__ = MagicMock(return_value=False) |
| 67 | + |
| 68 | + mock_td = MagicMock() |
| 69 | + mock_td.path = "/tmp/scratch" |
| 70 | + mock_scratch_dir.return_value.__enter__ = MagicMock(return_value=mock_td) |
| 71 | + mock_scratch_dir.return_value.__exit__ = MagicMock(return_value=False) |
| 72 | + |
| 73 | + with patch.object(libfuzzer_engine.Engine, "minimize_corpus"): |
| 74 | + conf = Conf(timeout=60) |
| 75 | + runner = Runner(conf) |
| 76 | + fuzzconf = FuzzConfiguration( |
| 77 | + corpus_dir="/corpus", |
| 78 | + target_path="/target", |
| 79 | + engine="libfuzzer", |
| 80 | + sanitizer="address", |
| 81 | + ) |
| 82 | + |
| 83 | + runner.merge_corpus(fuzzconf, "/output") |
0 commit comments