@@ -330,7 +330,9 @@ def __init__(self,
330330 self .build_prefix = build_prefix
331331 self .env_prefix = build_prefix + '_' if build_prefix else ''
332332 # This is used by users of the class to learn the fuzz targets in the build.
333- self .fuzz_targets = None
333+ self ._fuzz_targets = None
334+ self ._unpack_everything = environment .get_value (
335+ 'UNPACK_ALL_FUZZ_TARGETS_AND_FILES' , default_value = False )
334336 # This is used by users of the class to instruct the class which fuzz
335337 # target to unpack.
336338 self .fuzz_target = fuzz_target
@@ -457,15 +459,12 @@ def _download_and_open_build_archive(self, base_build_dir: str,
457459 shell .remove_file (build_local_archive )
458460
459461 def _open_build_archive (self , base_build_dir : str , build_dir : str ,
460- build_url : str , http_build_url : Optional [str ],
461- unpack_everything : Optional [bool ]):
462+ build_url : str , http_build_url : Optional [str ]):
462463 """Gets a handle on a build archive for the current build. Depending on the
463464 provided parameters, this function might download the build archive into
464465 the build directory or directly use remote HTTP archive.
465466
466467 Args:
467- unpack_everything: wether we should unpack the whole archive or try
468- selective unpacking.
469468 base_build_dir: the base build directory.
470469 build_dir: the current build directory.
471470 build_url: the build URL.
@@ -483,7 +482,8 @@ def _open_build_archive(self, base_build_dir: str, build_dir: str,
483482 allow_unpack_over_http = environment .get_value (
484483 'ALLOW_UNPACK_OVER_HTTP' , default_value = False )
485484 can_unzip_over_http = (
486- allow_unpack_over_http and not unpack_everything and http_build_url and
485+ allow_unpack_over_http and not self ._unpack_everything and
486+ http_build_url and
487487 build_archive .unzip_over_http_compatible (http_build_url ))
488488
489489 if not can_unzip_over_http :
@@ -503,9 +503,6 @@ def _unpack_build(self,
503503 # Track time taken to unpack builds so that it doesn't silently regress.
504504 start_time = time .time ()
505505
506- unpack_everything = environment .get_value (
507- 'UNPACK_ALL_FUZZ_TARGETS_AND_FILES' )
508-
509506 logs .info (f'Unpacking build from { build_url } into { build_dir } .' )
510507
511508 # Free up memory.
@@ -520,15 +517,12 @@ def _unpack_build(self,
520517
521518 try :
522519 with self ._open_build_archive (base_build_dir , build_dir , build_url ,
523- http_build_url , unpack_everything ) as build :
520+ http_build_url ) as build :
524521 unpack_start_time = time .time ()
525- unpack_everything = environment .get_value (
526- 'UNPACK_ALL_FUZZ_TARGETS_AND_FILES' )
527-
528- if not unpack_everything :
522+ if not self ._unpack_everything :
529523 # We will never unpack the full build so we need to get the targets
530524 # from the build archive.
531- self .fuzz_targets = list (build .list_fuzz_targets ())
525+ self ._fuzz_targets = list (build .list_fuzz_targets ())
532526 # We only want to unpack a single fuzz target if unpack_everything is
533527 # False.
534528 fuzz_target_to_unpack = self .fuzz_target
@@ -567,9 +561,7 @@ def _unpack_build(self,
567561 logs .error (f'Unable to unpack build archive { build_url } : { e } ' )
568562 return False
569563
570- if unpack_everything :
571- self .fuzz_targets = list (self ._get_fuzz_targets_from_dir (build_dir ))
572- else :
564+ if not self ._unpack_everything :
573565 # If this is partial build due to selected build files, then mark it as
574566 # such so that it is not re-used.
575567 partial_build_file_path = os .path .join (build_dir , PARTIAL_BUILD_FILE )
@@ -601,6 +593,14 @@ def build_dir(self):
601593 """The build directory. Usually a subdirectory of base_build_dir."""
602594 raise NotImplementedError
603595
596+ @property
597+ def fuzz_targets (self ):
598+ if not self ._fuzz_targets and self ._unpack_everything :
599+ # we can lazily compute that when unpacking the whole archive, since we
600+ # know all the fuzzers will be in the build directory.
601+ self ._fuzz_targets = list (self ._get_fuzz_targets_from_dir (self .build_dir ))
602+ return self ._fuzz_targets
603+
604604 def exists (self ):
605605 """Check if build already exists."""
606606 revision_file = os .path .join (self .build_dir , REVISION_FILE_NAME )
@@ -741,8 +741,8 @@ def setup(self):
741741 # This list will be incomplete because the directory on disk does not have
742742 # all fuzz targets. This is fine. The way fuzz_targets are added to db, it
743743 # does not clobber complete lists.
744- assert self .fuzz_targets is None
745- self .fuzz_targets = list (self ._get_fuzz_targets_from_dir (self .build_dir ))
744+ assert self ._fuzz_targets is None
745+ self ._fuzz_targets = list (self ._get_fuzz_targets_from_dir (self .build_dir ))
746746
747747 self ._setup_application_path (build_update = build_update )
748748 self ._post_setup_success (update_revision = build_update )
@@ -754,7 +754,7 @@ class SplitTargetBuild(RegularBuild):
754754
755755 def setup (self , * args , ** kwargs ):
756756 result = super ().setup (* args , ** kwargs )
757- self .fuzz_targets = list (_split_target_build_list_targets ())
757+ self ._fuzz_targets = list (_split_target_build_list_targets ())
758758 return result
759759
760760
@@ -793,7 +793,7 @@ def setup(self):
793793
794794 # Select a fuzzer, now that a list is available
795795 fuzz_targets = fuchsia .undercoat .list_fuzzers (handle )
796- self .fuzz_targets = list (fuzz_targets )
796+ self ._fuzz_targets = list (fuzz_targets )
797797 return True
798798
799799
@@ -972,7 +972,7 @@ def setup(self):
972972 else :
973973 logs .info ('Build already exists.' )
974974
975- self .fuzz_targets = list (self ._get_fuzz_targets_from_dir (self .build_dir ))
975+ self ._fuzz_targets = list (self ._get_fuzz_targets_from_dir (self .build_dir ))
976976 self ._setup_application_path (build_update = build_update )
977977 self ._post_setup_success (update_revision = build_update )
978978 return True
0 commit comments