def gn_gen(self): """Finalize args.gn and run `gn gen`.""" args_gn_path = os.path.join(self.get_build_dir_path(), ARGS_GN_FILENAME) common.ensure_dir(self.get_build_dir_path()) common.delete_if_exists(args_gn_path) # Let users edit the current args. content = serialize_gn_args(self.get_gn_args()) content = common.edit_if_needed( content, prefix='edit-args-gn-', comment='Edit %s before building.' % ARGS_GN_FILENAME, should_edit=self.options.edit_mode) # Write args to file and store. with open(args_gn_path, 'w') as f: f.write(content) logger.info( common.colorize('\nGenerating %s:\n%s\n', common.BASH_GREEN_MARKER), args_gn_path, content) common.execute( 'gn', 'gen %s' % (self.get_build_dir_path()), self.get_source_dir_path())
def reproduce_crash(self): """Reproduce crash on Android.""" android.reset(self.testcase.android_package_name) android.reboot() android.ensure_active() android.clear_log() ret_value, _ = android.adb_shell( 'am start -a android.intent.action.MAIN ' "-n {package_name}/{class_name} '{testcase_url}'".format( package_name=self.testcase.android_package_name, class_name=self.testcase.android_main_class_name, testcase_url=self.get_testcase_url()), redirect_stderr_to_stdout=True, stdout_transformer=output_transformer.Identity()) time.sleep(TEST_TIMEOUT) run_monkey_gestures_if_needed(self.testcase.android_package_name, self.testcase.gestures) output = android.get_log() android.kill(self.testcase.android_package_name) lib_tmp_dir_path = tempfile.mkdtemp(dir=common.CLUSTERFUZZ_TMP_DIR) symbolized_output = symbolize( output=android.fix_lib_path( content=android.filter_log(output), search_paths=[ self.binary_provider.get_unstripped_lib_dir_path(), self.binary_provider.get_android_libclang_dir_path() ], lib_tmp_dir_path=lib_tmp_dir_path), source_dir_path=self.binary_provider.get_source_dir_path()) common.delete_if_exists(lib_tmp_dir_path) return ret_value, symbolized_output
def download_build_if_needed(dest, url): """Download and extract a build (if it's not already there).""" if os.path.exists(dest): return dest logger.info('Downloading build data...') gsutil_path = url.replace( 'https://storage.cloud.google.com/', 'gs://') common.gsutil('cp %s .' % gsutil_path, common.CLUSTERFUZZ_CACHE_DIR) filename = os.path.basename(gsutil_path) saved_file = os.path.join(common.CLUSTERFUZZ_CACHE_DIR, filename) tmp_dir_path = tempfile.mkdtemp(dir=common.CLUSTERFUZZ_TMP_DIR) common.execute('unzip', '-q %s -d %s' % (saved_file, tmp_dir_path), cwd='.') # args.gn is guaranteed to be in the wanted folder. In Chrome, it's under a # sub-directory. In Android, it's in the top dir. args_gn_path = common.find_file('args.gn', tmp_dir_path) shutil.copytree(os.path.dirname(args_gn_path), dest) logger.info('Cleaning up...') common.delete_if_exists(saved_file) common.delete_if_exists(tmp_dir_path)
def get_testcase_path(self): """Downloads & returns the location of the testcase file.""" testcase_dir = self.testcase_dir_name() filename = os.path.join(testcase_dir, 'testcase%s' % self.file_extension) common.delete_if_exists(testcase_dir) os.makedirs(testcase_dir) logger.info('Downloading testcase data...') auth_header = common.get_stored_auth_header() # Do not use curl because curl doesn't support downloading an empty file. # See: https://github.com/google/clusterfuzz-tools/issues/326 args = ( '--no-verbose --waitretry=%s --retry-connrefused --content-disposition ' '--header="Authorization: %s" "%s"' % (DOWNLOAD_TIMEOUT, auth_header, CLUSTERFUZZ_TESTCASE_URL % self.id)) common.execute('wget', args, testcase_dir) downloaded_filename = os.listdir(testcase_dir)[0] filename = self.get_true_testcase_path(downloaded_filename) return filename
def ensure_user_data_dir_if_needed(args, require_user_data_dir): """Ensure the right user-data-dir.""" if not require_user_data_dir and USER_DATA_DIR_ARG not in args: return args # Remove --user-data-dir-arg if exist. args = re.sub('%s[^ ]+' % USER_DATA_DIR_ARG, '', args) common.delete_if_exists(USER_DATA_DIR_PATH) return '%s %s=%s' % (args, USER_DATA_DIR_ARG, USER_DATA_DIR_PATH)
def get_testcase_path(self): """Downloads & returns the location of the testcase file.""" downloaded_file_path = download_testcase(CLUSTERFUZZ_TESTCASE_URL % self.id) common.delete_if_exists(self.testcase_dir_path) os.makedirs(self.testcase_dir_path) return get_true_testcase_path( self.testcase_dir_path, self.absolute_path, downloaded_file_path)
def write_content(path, content): """Write content to path on Android.""" with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(content) logger.info( common.colorize('\nWriting %s:\n%s\n', common.BASH_GREEN_MARKER), path, content) adb('push %s %s' % (tmp_file.name, path)) adb_shell('chmod 0644 %s' % path) common.delete_if_exists(tmp_file.name)
def test_deletes_file(self): """Ensure the file gets deleted.""" home = os.path.expanduser('~') directory = os.path.join(home, 'testcase') filename = os.path.join(directory, 'testcase.js') os.makedirs(directory) with open(filename, 'w') as f: f.write('text') self.assertTrue(os.path.isfile(filename)) common.delete_if_exists(directory) self.assertFalse(os.path.exists(directory))
def get_clank_sha(revision_url): """Get Clank SHA.""" tmp_file = tempfile.NamedTemporaryFile(delete=False) tmp_file.close() common.gsutil('cp %s %s' % (revision_url, tmp_file.name), cwd='.') with open(tmp_file.name, 'r') as file_handle: body = file_handle.read() common.delete_if_exists(tmp_file.name) match = re.search('"clank_revision": "([a-fA-F0-9]+)"', body) if match: return match.group(1) raise Exception('Clank SHA is not found in:\n%s' % body)
def pre_build_steps(self): """Steps to run before building.""" # Add argument for user profile directory. user_profile_dir = '/tmp/clusterfuzz-user-profile-data' common.delete_if_exists(user_profile_dir) user_data_str = ' --user-data-dir=%s' % user_profile_dir if user_data_str not in self.args: self.args += user_data_str # Move testcase to LayoutTests directory if needed. search_string = '%sLayoutTests%s' % (os.sep, os.sep) if search_string in self.original_testcase_path: search_index = self.original_testcase_path.find(search_string) new_testcase_path = os.path.join( self.source_directory, 'third_party', 'WebKit', 'LayoutTests', self.original_testcase_path[search_index + len(search_string):]) os.rename(self.testcase_path, new_testcase_path) self.testcase_path = new_testcase_path self.environment.pop('ASAN_SYMBOLIZER_PATH', None) super(LinuxChromeJobReproducer, self).pre_build_steps()
def get_testcase_path(self): """Downloads & returns the location of the testcase file.""" testcase_dir = self.testcase_dir_name() filename = os.path.join(testcase_dir, 'testcase%s' % self.file_extension) common.delete_if_exists(testcase_dir) os.makedirs(testcase_dir) logger.info('Downloading testcase data...') auth_header = common.get_stored_auth_header() args = ( '--remote-name --remote-header-name --retry-max-time 30 --retry 5 ' '--silent --show-error --fail --location ' '-H "Authorization: %s" %s' % (auth_header, CLUSTERFUZZ_TESTCASE_URL % self.id)) common.execute('curl', args, testcase_dir) downloaded_filename = os.listdir(testcase_dir)[0] filename = self.get_true_testcase_path(downloaded_filename) return filename
def get_testcase_path(self): """Downloads & returns the location of the testcase file.""" testcase_dir = self.testcase_dir_name() filename = os.path.join(testcase_dir, 'testcase%s' % self.file_extension) common.delete_if_exists(testcase_dir) logger.info('Downloading testcase data...') if not os.path.exists(common.CLUSTERFUZZ_TESTCASES_DIR): os.makedirs(common.CLUSTERFUZZ_TESTCASES_DIR) os.makedirs(testcase_dir) auth_header = common.get_stored_auth_header() args = '--content-disposition --header="Authorization: %s" "%s"' % ( auth_header, CLUSTERFUZZ_TESTCASE_URL % self.id) common.execute('wget', args, testcase_dir) downloaded_filename = os.listdir(testcase_dir)[0] filename = self.get_true_testcase_path(downloaded_filename) return filename
def test_delete_file(self): """Ensure the file is deleted.""" common.delete_if_exists(self.filename) self.assertTrue(os.path.exists(self.directory)) self.assertFalse(os.path.exists(self.filename))