예제 #1
0
def _prepare_environment_for_android(disable_android_setup):
    """Additional environment overrides needed to run on an Android device."""
    environment.set_value('OS_OVERRIDE', 'ANDROID')

    # Bail out if we don't have an Android device connected.
    serial = environment.get_value('ANDROID_SERIAL')
    if not serial:
        # TODO(mbarbella): Handle the one-device case gracefully.
        raise errors.ReproduceToolUnrecoverableError(
            'This test case requires an Android device. Please set the '
            'ANDROID_SERIAL environment variable and try again.')

    print('Warning: this tool will make changes to settings on the connected '
          'Android device with serial {serial} that could result in data '
          'loss.'.format(serial=serial))
    willing_to_continue = prompts.get_boolean(
        'Are you sure you want to continue?')
    if not willing_to_continue:
        raise errors.ReproduceToolUnrecoverableError(
            'Bailing out to avoid changing settings on the connected device.')

    # Push the test case and build APK to the device.
    apk_path = environment.get_value('APP_PATH')
    device.update_build(apk_path,
                        should_initialize_device=not disable_android_setup)

    device.push_testcases_to_device()
예제 #2
0
파일: android.py 프로젝트: ze0r/clusterfuzz
def prepare_environment(disable_android_setup):
    """Additional environment overrides needed to run on an Android device."""
    environment.set_value('OS_OVERRIDE', 'ANDROID')

    # Bail out if we can't determine which Android device to use.
    serial = environment.get_value('ANDROID_SERIAL')
    if not serial:
        devices = get_devices()
        if len(devices) == 1:
            serial = devices[0]
            environment.set_value('ANDROID_SERIAL', serial)
        elif not devices:
            raise errors.ReproduceToolUnrecoverableError(
                'No connected Android devices were detected. Run with the -e '
                'argument to use an emulator.')
        else:
            raise errors.ReproduceToolUnrecoverableError(
                'You have multiple Android devices or emulators connected. Please '
                'set the ANDROID_SERIAL environment variable and try again.\n\n'
                'Attached devices: ' + ', '.join(devices))

    print('Warning: this tool will make changes to settings on the connected '
          'Android device with serial {serial} that could result in data '
          'loss.'.format(serial=serial))
    willing_to_continue = prompts.get_boolean(
        'Are you sure you want to continue?')
    if not willing_to_continue:
        raise errors.ReproduceToolUnrecoverableError(
            'Bailing out to avoid changing settings on the connected device.')

    # Push the test case and build APK to the device.
    apk_path = environment.get_value('APP_PATH')
    device.update_build(apk_path,
                        should_initialize_device=not disable_android_setup)

    device.push_testcases_to_device()
예제 #3
0
def _reproduce_crash(
    testcase_url,
    build_directory,
    iterations,
    disable_xvfb,
    verbose,
    disable_android_setup,
):
    """Reproduce a crash."""
    _prepare_initial_environment(build_directory, iterations, verbose)

    # Validate the test case URL and fetch the tool's configuration.
    testcase_id = _get_testcase_id_from_url(testcase_url)
    configuration = config.ReproduceToolConfiguration(testcase_url)

    testcase = _get_testcase(testcase_id, configuration)

    # For new user uploads, we'll fail without the metadata set by analyze task.
    if not testcase.platform:
        raise errors.ReproduceToolUnrecoverableError(
            "This test case has not yet been processed. Please try again later."
        )

    # Ensure that we support this test case's platform.
    if testcase.platform not in SUPPORTED_PLATFORMS:
        raise errors.ReproduceToolUnrecoverableError(
            "The reproduce tool is not yet supported on {platform}.".format(
                platform=testcase.platform))

    # Print warnings for this test case.
    if testcase.one_time_crasher_flag:
        print("Warning: this test case was a one-time crash. It may not be "
              "reproducible.")
    if testcase.flaky_stack:
        print("Warning: this test case is known to crash with different stack "
              "traces.")

    testcase_path = _download_testcase(testcase_id, testcase, configuration)
    _update_environment_for_testcase(testcase, build_directory)

    # Validate that we're running on the right platform for this test case.
    platform = environment.platform().lower()
    if testcase.platform == "android" and platform == "linux":
        android.prepare_environment(disable_android_setup)
    elif testcase.platform == "android" and platform != "linux":
        raise errors.ReproduceToolUnrecoverableError(
            "The ClusterFuzz environment only supports running Android test cases "
            "on Linux host machines. Unable to reproduce the test case on "
            "{current_platform}.".format(current_platform=platform))
    elif testcase.platform != platform:
        raise errors.ReproduceToolUnrecoverableError(
            "The specified test case was discovered on {testcase_platform}. "
            "Unable to attempt to reproduce it on {current_platform}.".format(
                testcase_platform=testcase.platform,
                current_platform=platform))

    x_processes = []
    if not disable_xvfb:
        _setup_x()
    timeout = environment.get_value("TEST_TIMEOUT")

    print("Running testcase...")
    try:
        result = testcase_manager.test_for_crash_with_retries(testcase,
                                                              testcase_path,
                                                              timeout,
                                                              crash_retries=1)

        # If we can't reproduce the crash, prompt the user to try again.
        if not result.is_crash():
            _print_stacktrace(result)
            result = None
            use_default_retries = prompts.get_boolean(
                "Failed to find the desired crash on first run. Re-run "
                "{crash_retries} times?".format(
                    crash_retries=environment.get_value("CRASH_RETRIES")))
            if use_default_retries:
                print(
                    "Attempting to reproduce test case. This may take a while..."
                )
                result = testcase_manager.test_for_crash_with_retries(
                    testcase, testcase_path, timeout)

    except KeyboardInterrupt:
        print("Aborting...")
        result = None

    # Terminate Xvfb and blackbox.
    for process in x_processes:
        process.terminate()

    return result