Skip to content

Commit 44f9318

Browse files
Switch fuzz task to UTaskLocalExecutor and improve fuzzer setup robustness.
- Change `fuzz` task type to `UTaskLocalExecutor` in `task_types.py` to run fuzz tasks locally. - Update `_update_fuzzer` in `setup.py` to support downloading fuzzer binaries using `blobs.read_blob_to_disk` when running on a trusted bot (non-uworker), removing the strict dependency on signed URLs for local execution. - Add unit tests for `_update_fuzzer` in `setup_test.py` covering local and uworker scenarios.
1 parent 843b903 commit 44f9318

File tree

3 files changed

+78
-3
lines changed

3 files changed

+78
-3
lines changed

src/clusterfuzz/_internal/bot/tasks/setup.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,12 @@ def _update_fuzzer(
624624

625625
# Copy the archive to local disk and unpack it.
626626
archive_path = os.path.join(fuzzer_directory, fuzzer.filename)
627-
if not storage.download_signed_url_to_file(update_input.fuzzer_download_url,
628-
archive_path):
627+
if not environment.is_uworker():
628+
if not blobs.read_blob_to_disk(fuzzer.blobstore_key, archive_path):
629+
logs.error('Failed to copy fuzzer archive.')
630+
return False
631+
elif not storage.download_signed_url_to_file(update_input.fuzzer_download_url,
632+
archive_path):
629633
logs.error('Failed to copy fuzzer archive.')
630634
return False
631635

src/clusterfuzz/_internal/bot/tasks/task_types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def execute(self, task_argument, job_type, uworker_env):
225225
'analyze': UTask,
226226
'blame': TrustedTask,
227227
'corpus_pruning': UTask,
228-
'fuzz': UTask,
228+
'fuzz': UTaskLocalExecutor,
229229
'impact': TrustedTask,
230230
'minimize': UTask,
231231
'progression': UTask,

src/clusterfuzz/_internal/tests/core/bot/tasks/setup_test.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,3 +472,74 @@ def test_prepare_env_fails(self):
472472
self.assertIsNone(path)
473473
self.mock_logs['error'].assert_called_with(
474474
'Error setting up testcase locally: mock prepare error')
475+
476+
@test_utils.with_cloud_emulators('datastore')
477+
class UpdateFuzzerTest(unittest.TestCase):
478+
"""Tests _update_fuzzer."""
479+
480+
def setUp(self):
481+
helpers.patch_environ(self)
482+
helpers.patch(self, [
483+
'clusterfuzz._internal.google_cloud_utils.storage.download_signed_url_to_file',
484+
'clusterfuzz._internal.google_cloud_utils.blobs.read_blob_to_disk',
485+
'clusterfuzz._internal.system.shell.remove_directory',
486+
'clusterfuzz._internal.system.shell.remove_file',
487+
'clusterfuzz._internal.system.archive.open',
488+
'clusterfuzz._internal.build_management.revisions.write_revision_to_revision_file',
489+
'clusterfuzz._internal.build_management.revisions.needs_update',
490+
'os.path.exists',
491+
'os.chmod',
492+
])
493+
self.mock.remove_directory.return_value = True
494+
self.mock.needs_update.return_value = True
495+
self.mock.exists.return_value = True
496+
497+
self.fuzzer_name = 'test_fuzzer'
498+
self.fuzzer = data_types.Fuzzer(
499+
name=self.fuzzer_name, filename='fuzzer.zip', executable_path='fuzzer_exe', blobstore_key='blob_key', revision=123)
500+
self.update_input = uworker_msg_pb2.SetupInput(
501+
fuzzer_name=self.fuzzer_name,
502+
fuzzer=uworker_io.entity_to_protobuf(self.fuzzer),
503+
fuzzer_download_url='https://signed_url')
504+
self.fuzzer_directory = '/fuzzer_dir'
505+
self.version_file = '/fuzzer_dir/version'
506+
507+
def test_update_fuzzer_local(self):
508+
"""Test update_fuzzer when local (not uworker)."""
509+
environment.set_value('UWORKER', False) # Not uworker
510+
self.mock.read_blob_to_disk.return_value = True
511+
512+
result = setup._update_fuzzer(self.update_input, self.fuzzer_directory, self.version_file)
513+
514+
self.assertTrue(result)
515+
self.mock.read_blob_to_disk.assert_called_once_with('blob_key', '/fuzzer_dir/fuzzer.zip')
516+
self.mock.download_signed_url_to_file.assert_not_called()
517+
518+
def test_update_fuzzer_uworker(self):
519+
"""Test update_fuzzer when uworker."""
520+
environment.set_value('UWORKER', True)
521+
self.mock.download_signed_url_to_file.return_value = True
522+
523+
result = setup._update_fuzzer(self.update_input, self.fuzzer_directory, self.version_file)
524+
525+
self.assertTrue(result)
526+
self.mock.download_signed_url_to_file.assert_called_once_with('https://signed_url', '/fuzzer_dir/fuzzer.zip')
527+
self.mock.read_blob_to_disk.assert_not_called()
528+
529+
def test_update_fuzzer_local_fail(self):
530+
"""Test update_fuzzer fail local."""
531+
environment.set_value('UWORKER', False)
532+
self.mock.read_blob_to_disk.return_value = False
533+
534+
result = setup._update_fuzzer(self.update_input, self.fuzzer_directory, self.version_file)
535+
536+
self.assertFalse(result)
537+
538+
def test_update_fuzzer_uworker_fail(self):
539+
"""Test update_fuzzer fail uworker."""
540+
environment.set_value('UWORKER', True)
541+
self.mock.download_signed_url_to_file.return_value = False
542+
543+
result = setup._update_fuzzer(self.update_input, self.fuzzer_directory, self.version_file)
544+
545+
self.assertFalse(result)

0 commit comments

Comments
 (0)