def CreateChromedriver(args): """Create a webdriver object and close it after.""" def DeleteWithRetry(path, func): # There seems to be a race condition on the bots that causes the paths # to not delete because they are being used. This allows up to 4 seconds # to delete for _ in xrange(8): try: return func(path) except WindowsError: time.sleep(0.5) raise def CollectCrashReports(user_data_dir, output_dir): """Searches for Chrome crash reports, collecting them for analysis. Args: user_data_dir: The full path of the User Data dir. output_dir: If not None, a path to which collected crash reports are to be moved. Returns: The number of crash reports found. """ report_dir = os.path.join(user_data_dir, 'Crashpad', 'reports') dumps = [] try: dumps = os.listdir(report_dir) except OSError: # Assume this is file not found, meaning no crash reports. return 0 for dump in dumps: dump_path = os.path.join(report_dir, dump) if (output_dir): target_path = os.path.join(output_dir, dump) try: shutil.copyfile(dump_path, target_path) logging.error('Saved Chrome crash dump to %s', target_path) except OSError: logging.exception( 'Failed to copy Chrome crash dump from %s to %s', dump_path, target_path) else: logging.error('Found Chrome crash dump at %s', dump_path) return len(dumps) driver = None user_data_dir = tempfile.mkdtemp() fd, log_file = tempfile.mkstemp() os.close(fd) chrome_options = ChromeOptions() chrome_options.binary_location = args.chrome_path chrome_options.add_argument('user-data-dir=' + user_data_dir) chrome_options.add_argument('log-file=' + log_file) chrome_options.add_argument('enable-logging') chrome_options.add_argument('v=1') emit_log = False try: driver = webdriver.Chrome(args.chromedriver_path, chrome_options=chrome_options) yield driver except: emit_log = True raise finally: if driver: driver.quit() chrome_helper.WaitForChromeExit(args.chrome_path) report_count = CollectCrashReports(user_data_dir, args.output_dir) if report_count: emit_log = True try: DeleteWithRetry(user_data_dir, shutil.rmtree) except: emit_log = True raise finally: if emit_log: with open(log_file) as fh: logging.error(fh.read()) if args.output_dir: target = os.path.join(args.output_dir, os.path.basename(log_file)) shutil.copyfile(log_file, target) logging.error('Saved Chrome log to %s', target) try: DeleteWithRetry(log_file, os.remove) except WindowsError: # Don't fail the test if the log file couldn't be deleted. logging.exception('Failed to delete log file %s' % log_file) if report_count: raise Exception('Failing test due to %s crash reports found' % report_count)
def CreateChromedriver(args): """Create a webdriver object ad close it after.""" def DeleteWithRetry(path, func): # There seems to be a race condition on the bots that causes the paths # to not delete because they are being used. This allows up to 2 seconds # to delete for _ in xrange(4): try: return func(path) except WindowsError: time.sleep(0.5) raise def CollectCrashReports(user_data_dir, output_dir): """Searches for Chrome crash reports, collecting them for analysis. Args: user_data_dir: The full path of the User Data dir. output_dir: If not None, a path to which collected crash reports are to be moved. """ report_dir = os.path.join(user_data_dir, 'Crashpad', 'reports') dumps = [] try: dumps = os.listdir(report_dir) except OSError: # Assume this is file not found, meaning no crash reports. return for dump in dumps: dump_path = os.path.join(report_dir, dump) if (output_dir): target_path = os.path.join(output_dir, dump) try: shutil.copyfile(dump_path, target_path) logging.error('Saved Chrome crash dump to %s', target_path) except OSError: logging.exception( 'Failed to copy Chrome crash dump from %s to %s', dump_path, target_path) else: logging.error('Found Chrome crash dump at %s', dump_path) driver = None user_data_dir = tempfile.mkdtemp() fd, log_file = tempfile.mkstemp() os.close(fd) chrome_options = ChromeOptions() chrome_options.binary_location = args.chrome_path chrome_options.add_argument('user-data-dir=' + user_data_dir) chrome_options.add_argument('log-file=' + log_file) chrome_options.add_argument('enable-logging') chrome_options.add_argument('v=1') try: driver = webdriver.Chrome(args.chromedriver_path, chrome_options=chrome_options) yield driver except: with open(log_file) as fh: logging.error(fh.read()) raise finally: if driver: driver.quit() chrome_helper.WaitForChromeExit() # To help with local crash analysis, change None to tempfile.gettempdir(). # TODO(grt): Copy crash dumps into ${ISOLATED_OUTDIR}. CollectCrashReports(user_data_dir, None) DeleteWithRetry(log_file, os.remove) DeleteWithRetry(user_data_dir, shutil.rmtree)