Skip to content

Commit f2ac4e8

Browse files
authored
Merge branch 'master' into chore/build-retrieval-improvements
2 parents 816ea61 + 5cfd235 commit f2ac4e8

File tree

2 files changed

+50
-47
lines changed

2 files changed

+50
-47
lines changed

src/clusterfuzz/_internal/bot/untrusted_runner/build_setup_host.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,6 @@ def _clear_env():
3131
environment.remove_key('FUZZ_TARGET')
3232

3333

34-
def _handle_response(build, response):
35-
"""Handle build setup response."""
36-
if not response.result:
37-
_clear_env()
38-
return False
39-
40-
_update_env_from_response(response)
41-
42-
if not environment.get_value('APP_PATH'):
43-
fuzzer_directory = environment.get_value('FUZZER_DIR')
44-
if fuzzer_directory:
45-
build_manager.set_environment_vars([fuzzer_directory])
46-
47-
environment.set_value('APP_REVISION', build.revision)
48-
build.fuzz_targets = list(response.fuzz_targets)
49-
50-
return True
51-
52-
5334
def _update_env_from_response(response):
5435
"""Update environment variables from response."""
5536
environment.set_value('APP_PATH', response.app_path)
@@ -64,11 +45,37 @@ def _update_env_from_response(response):
6445
class RemoteRegularBuild(build_manager.RegularBuild):
6546
"""Remote regular build."""
6647

48+
def __init__(self, *args, **kwargs):
49+
super().__init__(*args, **kwargs)
50+
self._fuzz_targets = []
51+
52+
def _handle_response(self, response):
53+
"""Handle build setup response."""
54+
if not response.result:
55+
_clear_env()
56+
return False
57+
58+
_update_env_from_response(response)
59+
60+
if not environment.get_value('APP_PATH'):
61+
fuzzer_directory = environment.get_value('FUZZER_DIR')
62+
if fuzzer_directory:
63+
build_manager.set_environment_vars([fuzzer_directory])
64+
65+
environment.set_value('APP_REVISION', self.revision)
66+
self._fuzz_targets = list(response.fuzz_targets)
67+
68+
return True
69+
6770
def setup(self):
6871
request = untrusted_runner_pb2.SetupRegularBuildRequest( # pylint: disable=no-member
6972
base_build_dir=self.base_build_dir,
7073
revision=self.revision,
7174
build_url=self.build_url,
7275
fuzz_target=self.fuzz_target,
7376
build_prefix=self.build_prefix)
74-
return _handle_response(self, host.stub().SetupRegularBuild(request))
77+
return self._handle_response(host.stub().SetupRegularBuild(request))
78+
79+
@property
80+
def fuzz_targets(self):
81+
return self._fuzz_targets

src/clusterfuzz/_internal/build_management/build_manager.py

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ def __init__(self,
341341
self.build_prefix = build_prefix
342342
self.env_prefix = build_prefix + '_' if build_prefix else ''
343343
# This is used by users of the class to learn the fuzz targets in the build.
344-
self.fuzz_targets = None
344+
self._fuzz_targets = None
345+
self._unpack_everything = environment.get_value(
346+
'UNPACK_ALL_FUZZ_TARGETS_AND_FILES', default_value=False)
345347
# This is used by users of the class to instruct the class which fuzz
346348
# target to unpack.
347349
self.fuzz_target = fuzz_target
@@ -461,15 +463,12 @@ def _download_and_open_build_archive(self, base_build_dir: str,
461463
shell.remove_file(build_local_archive)
462464

463465
def _open_build_archive(self, base_build_dir: str, build_dir: str,
464-
build_url: str, http_build_url: Optional[str],
465-
unpack_everything: Optional[bool]):
466+
build_url: str, http_build_url: Optional[str]):
466467
"""Gets a handle on a build archive for the current build. Depending on the
467468
provided parameters, this function might download the build archive into
468469
the build directory or directly use remote HTTP archive.
469470
470471
Args:
471-
unpack_everything: wether we should unpack the whole archive or try
472-
selective unpacking.
473472
base_build_dir: the base build directory.
474473
build_dir: the current build directory.
475474
build_url: the build URL.
@@ -487,7 +486,8 @@ def _open_build_archive(self, base_build_dir: str, build_dir: str,
487486
allow_unpack_over_http = environment.get_value(
488487
'ALLOW_UNPACK_OVER_HTTP', default_value=False)
489488
can_unzip_over_http = (
490-
allow_unpack_over_http and not unpack_everything and http_build_url and
489+
allow_unpack_over_http and not self._unpack_everything and
490+
http_build_url and
491491
build_archive.unzip_over_http_compatible(http_build_url))
492492

493493
if not can_unzip_over_http:
@@ -507,9 +507,6 @@ def _unpack_build(self,
507507
# Track time taken to unpack builds so that it doesn't silently regress.
508508
start_time = time.time()
509509

510-
unpack_everything = environment.get_value(
511-
'UNPACK_ALL_FUZZ_TARGETS_AND_FILES')
512-
513510
logs.info(f'Unpacking build from {build_url} into {build_dir}.')
514511

515512
# Free up memory.
@@ -524,17 +521,13 @@ def _unpack_build(self,
524521

525522
try:
526523
with self._open_build_archive(base_build_dir, build_dir, build_url,
527-
http_build_url, unpack_everything) as build:
524+
http_build_url) as build:
528525
unpack_start_time = time.time()
529-
unpack_everything = environment.get_value(
530-
'UNPACK_ALL_FUZZ_TARGETS_AND_FILES')
531-
532-
if not unpack_everything:
526+
if not self._unpack_everything:
533527
# We will never unpack the full build so we need to get the targets
534528
# from the build archive.
535529
list_fuzz_target_start_time = time.time()
536-
self.fuzz_targets = list(build.list_fuzz_targets())
537-
# In minutes, as per metric definition.
530+
self._fuzz_targets = list(build.list_fuzz_targets())
538531
_emit_job_build_retrieval_metric(list_fuzz_target_start_time,
539532
'list_fuzz_targets',
540533
self._build_type)
@@ -569,12 +562,7 @@ def _unpack_build(self,
569562
logs.error(f'Unable to unpack build archive {build_url}: {e}')
570563
return False
571564

572-
if unpack_everything:
573-
list_fuzz_target_start_time = time.time()
574-
self.fuzz_targets = list(self._get_fuzz_targets_from_dir(build_dir))
575-
_emit_job_build_retrieval_metric(list_fuzz_target_start_time,
576-
'list_fuzz_targets', self._build_type)
577-
else:
565+
if not self._unpack_everything:
578566
# If this is partial build due to selected build files, then mark it as
579567
# such so that it is not re-used.
580568
partial_build_file_path = os.path.join(build_dir, PARTIAL_BUILD_FILE)
@@ -607,6 +595,14 @@ def build_dir(self):
607595
"""The build directory. Usually a subdirectory of base_build_dir."""
608596
raise NotImplementedError
609597

598+
@property
599+
def fuzz_targets(self):
600+
if not self._fuzz_targets and self._unpack_everything:
601+
# we can lazily compute that when unpacking the whole archive, since we
602+
# know all the fuzzers will be in the build directory.
603+
self._fuzz_targets = list(self._get_fuzz_targets_from_dir(self.build_dir))
604+
return self._fuzz_targets
605+
610606
def exists(self):
611607
"""Check if build already exists."""
612608
revision_file = os.path.join(self.build_dir, REVISION_FILE_NAME)
@@ -747,8 +743,8 @@ def setup(self):
747743
# This list will be incomplete because the directory on disk does not have
748744
# all fuzz targets. This is fine. The way fuzz_targets are added to db, it
749745
# does not clobber complete lists.
750-
assert self.fuzz_targets is None
751-
self.fuzz_targets = list(self._get_fuzz_targets_from_dir(self.build_dir))
746+
assert self._fuzz_targets is None
747+
self._fuzz_targets = list(self._get_fuzz_targets_from_dir(self.build_dir))
752748

753749
self._setup_application_path(build_update=build_update)
754750
self._post_setup_success(update_revision=build_update)
@@ -760,7 +756,7 @@ class SplitTargetBuild(RegularBuild):
760756

761757
def setup(self, *args, **kwargs):
762758
result = super().setup(*args, **kwargs)
763-
self.fuzz_targets = list(_split_target_build_list_targets())
759+
self._fuzz_targets = list(_split_target_build_list_targets())
764760
return result
765761

766762

@@ -799,7 +795,7 @@ def setup(self):
799795

800796
# Select a fuzzer, now that a list is available
801797
fuzz_targets = fuchsia.undercoat.list_fuzzers(handle)
802-
self.fuzz_targets = list(fuzz_targets)
798+
self._fuzz_targets = list(fuzz_targets)
803799
return True
804800

805801

@@ -968,7 +964,7 @@ def setup(self):
968964
else:
969965
logs.info('Build already exists.')
970966

971-
self.fuzz_targets = list(self._get_fuzz_targets_from_dir(self.build_dir))
967+
self._fuzz_targets = list(self._get_fuzz_targets_from_dir(self.build_dir))
972968
self._setup_application_path(build_update=build_update)
973969
self._post_setup_success(update_revision=build_update)
974970
return True

0 commit comments

Comments
 (0)