| """Recipe to build and upload fuzz testing targets to clusterfuzz GCS Bucket""" |
| import os |
| |
| from helpers import branch_utils |
| from helpers import gcs_utils |
| from slave import base_recipe |
| from slave.step import gcs_upload_step |
| from slave.step import gn_step |
| from slave.step import make_clean_step |
| from slave.step import ninja_step |
| from slave.step import shell_step |
| |
| BUILD_CONFIGS = { |
| 'tcp_socket_impl_fuzzer': { |
| 'archive_name': 'tcp_socket_impl_fuzzer', |
| 'build_args_product': 'video_x64_eng', |
| 'build_target': ('chromecast/internal/smart_home/actions/' |
| 'platform/cast:tcp_socket_impl_fuzzer'), |
| 'run_gtests': False, |
| 'build_args': [ |
| 'use_libfuzzer=true', |
| 'is_asan=true', |
| 'is_component_build=false', |
| ], |
| 'gcs_bucket': 'catabuilder-clusterfuzz-results', |
| 'gcs_path': 'tcp_socket_impl_fuzzer', |
| }, |
| 'udp_socket_impl_fuzzer': { |
| 'archive_name': 'udp_socket_impl_fuzzer', |
| 'build_args_product': 'video_x64_eng', |
| 'build_target': ('chromecast/internal/smart_home/actions/' |
| 'platform/cast:udp_socket_impl_fuzzer'), |
| 'run_gtests': False, |
| 'build_args': [ |
| 'use_libfuzzer=true', |
| 'is_asan=true', |
| 'is_component_build=false', |
| ], |
| 'gcs_bucket': 'catabuilder-clusterfuzz-results', |
| 'gcs_path': 'udp_socket_impl_fuzzer', |
| }, |
| } |
| |
| |
| def GetValidBuildNames(): |
| return list(BUILD_CONFIGS.keys()) |
| |
| |
| def CreateRecipe(build_name: str, **kwargs): |
| """Builds a recipe object.""" |
| config = BUILD_CONFIGS[build_name] |
| return FuzzRecipe(config, **kwargs) |
| |
| |
| class FuzzRecipe(base_recipe.BaseRecipe): |
| """Recipe to build and upload fuzz testing targets to clusterfuzz GCS""" |
| |
| def __init__(self, config, **kwargs): |
| base_recipe.BaseRecipe.__init__( |
| self, enable_build_accelerator=True, **kwargs) |
| self._build_config = config |
| |
| def get_num_jobs(self): # pylint:disable=method-hidden |
| """Count of jobs to use.""" |
| setup_steps = self.get_setup_steps() |
| return setup_steps[0].get_num_jobs() |
| |
| def get_steps(self): |
| cwd = os.getcwd() |
| gcs_bucket = self._build_config.get('gcs_bucket') |
| gcs_path = self._build_config.get('gcs_path') |
| jobs = self.get_num_jobs() |
| build_args = self._build_config.get('build_args') |
| build_args_product = self._build_config.get('build_args_product') |
| build_target = self._build_config.get('build_target') |
| post_submit_upload = self.build_system == 'catabuilder' |
| archive_name = self._build_config.get('archive_name') |
| fuzz_archive = '{}.zip'.format(self.build_number) |
| |
| # Going to build target to out directory |
| out_dir = os.path.join('out', archive_name, self.build_number) |
| steps = [] |
| if self.build_system == 'catabuilder': |
| steps.append(make_clean_step.MakeCleanStep(**self._step_kwargs)) |
| |
| # Generate gn gen step |
| gn_gen_step = gn_step.GnGenStep( |
| build_args_product=build_args_product, |
| build_args=build_args, |
| out_dir=out_dir, |
| halt_on_failure=True, |
| cwd=cwd, |
| **self._step_kwargs) |
| steps.append(gn_gen_step) |
| |
| # Generate gn args step |
| gn_args_step = gn_step.GnArgsStep( |
| out_dir=out_dir, cwd=cwd, halt_on_failure=True, **self._step_kwargs) |
| steps.append(gn_args_step) |
| |
| # Generate ninja build step |
| ninja_build_step = ninja_step.NinjaStep( |
| out_dir=out_dir, |
| target=build_target, |
| cwd=cwd, |
| jobs=jobs, |
| halt_on_failure=True, |
| **self._step_kwargs) |
| steps.append(ninja_build_step) |
| |
| # Zip build artifacts excluding obj file |
| zip_output_step = shell_step.ShellStep( |
| name='Zip build artifacts', |
| command=['zip', '-rq', fuzz_archive, |
| '.', '-x', "'*obj*'"], |
| directory=os.getcwd()+'/'+out_dir, |
| **self._step_kwargs) |
| |
| steps.append(zip_output_step) |
| |
| # Upload Fuzz Testing build output to gcs |
| # only if recipe is running from Catabuilder. |
| if post_submit_upload: |
| # Write and upload targets.list file |
| contents = '\n'.join( |
| BUILD_CONFIGS[config]['gcs_path'] for config in BUILD_CONFIGS) |
| targets_list_file = self._executor.write_temp_file(contents) |
| |
| gcs_step = gcs_upload_step.GcsUploadStep( |
| gcs_bucket, |
| 'targets.list', |
| name='Clusterfuzz GCS upload for targets.list', |
| src_path=targets_list_file, |
| **self._step_kwargs) |
| |
| gcs_step = gcs_upload_step.GcsUploadStep( |
| gcs_bucket, |
| gcs_path, |
| name='Clusterfuzz GCS upload for target: ' + archive_name, |
| src_path=os.getcwd()+'/'+out_dir+'/'+fuzz_archive, |
| **self._step_kwargs) |
| steps.append(gcs_step) |
| |
| return steps |