Exemplo n.º 1
0
def run_reduction_on_report(
    test_dir: Path,
    reports_dir: Path,
    binary_manager: binaries_util.BinaryManager,
    settings: Settings,
) -> None:
    test = test_util.metadata_read(test_dir)

    if not test.device or not test.device.name:
        raise AssertionError(
            f"Cannot reduce {str(test_dir)}; device must be specified")

    try:
        run_reduction(
            source_dir_to_reduce=test_util.get_source_dir(test_dir),
            reduction_output_dir=test_util.get_reductions_dir(
                test_dir, test.device.name),
            binary_manager=binary_manager,
            settings=settings,
        )
    except ReductionFailedError as ex:
        # Create a symlink to the failed reduction so it is easy to investigate failed reductions.
        link_to_failed_reduction_path = (
            reports_dir / "failed_reductions" /
            f"{test_dir.name}_{ex.reduction_work_dir.name}")
        util.make_directory_symlink(
            new_symlink_file_path=link_to_failed_reduction_path,
            existing_dir=ex.reduction_work_dir,
        )
Exemplo n.º 2
0
def run_reduction_on_report(  # pylint: disable=too-many-locals;
    test_dir: Path,
    reports_dir: Path,
    binary_manager: binaries_util.BinaryManager,
    settings: Settings,
) -> None:
    test = test_util.metadata_read(test_dir)

    check(
        bool(test.device and test.device.name),
        AssertionError(
            f"Cannot reduce {str(test_dir)}; "
            f"device must be specified in {str(test_util.get_metadata_path(test_dir))}"
        ),
    )

    source_dir = test_util.get_source_dir(test_dir)

    try:
        run_reduction(
            source_dir_to_reduce=source_dir,
            reduction_output_dir=test_util.get_reductions_dir(
                test_dir, test.device.name),
            binary_manager=binary_manager,
            settings=settings,
        )
    except fuzz_glsl_test.ReductionFailedError as ex:
        # Create a symlink to the failed reduction so it is easy to investigate failed reductions.
        link_to_failed_reduction_path = (
            reports_dir / "failed_reductions" /
            f"{test_dir.name}_{ex.reduction_work_dir.name}")
        util.make_directory_symlink(
            new_symlink_file_path=link_to_failed_reduction_path,
            existing_dir=ex.reduction_work_dir,
        )
Exemplo n.º 3
0
def run_reduction(
    source_dir_to_reduce: Path,
    reduction_output_dir: Path,
    binary_manager: binaries_util.BinaryManager,
    settings: Settings,
) -> Path:
    test = test_util.metadata_read_from_source_dir(source_dir_to_reduce)

    reduced_source_dir = source_dir_to_reduce

    reduced_source_dir = run_reduction_part(
        reduction_part_output_dir=reduction_output_dir / "1",
        source_dir_to_reduce=reduced_source_dir,
        preserve_semantics=True,
        binary_manager=binary_manager,
        settings=settings,
    )

    if (test.crash_signature != signature_util.BAD_IMAGE_SIGNATURE
            and not settings.skip_semantics_changing_reduction):
        reduced_source_dir = run_reduction_part(
            reduction_part_output_dir=reduction_output_dir / "2",
            source_dir_to_reduce=reduced_source_dir,
            preserve_semantics=False,
            binary_manager=binary_manager,
            settings=settings,
        )

    # Create and return a symlink to the "best" reduction part directory.
    return util.make_directory_symlink(
        new_symlink_file_path=reduction_output_dir / fuzz.BEST_REDUCTION_NAME,
        existing_dir=reduced_source_dir.parent,
    )
Exemplo n.º 4
0
def run_reduction_on_report(
        test_dir: Path, reports_dir: Path,
        binary_manager: binaries_util.BinaryManager) -> None:
    test = test_util.metadata_read(test_dir)

    try:
        reduced_test = test_dir
        reduced_test = run_reduction(
            test_dir_reduction_output=test_dir,
            test_dir_to_reduce=reduced_test,
            preserve_semantics=True,
            binary_manager=binary_manager,
            reduction_name="1",
        )

        if test.crash_signature != signature_util.BAD_IMAGE_SIGNATURE:
            reduced_test = run_reduction(
                test_dir_reduction_output=test_dir,
                test_dir_to_reduce=reduced_test,
                preserve_semantics=False,
                binary_manager=binary_manager,
                reduction_name="2",
            )

        device_name = test.device.name

        # Create a symlink to the "best" reduction.
        best_reduced_test_link = test_util.get_reduced_test_dir(
            test_dir, device_name, fuzz.BEST_REDUCTION_NAME)
        util.make_directory_symlink(
            new_symlink_file_path=best_reduced_test_link,
            existing_dir=reduced_test)
    except ReductionFailedError as ex:
        # Create a symlink to the failed reduction so it is easy to investigate failed reductions.
        link_to_failed_reduction_path = (
            reports_dir / "failed_reductions" /
            f"{test_dir.name}_{ex.reduction_name}")
        util.make_directory_symlink(
            new_symlink_file_path=link_to_failed_reduction_path,
            existing_dir=ex.reduction_work_dir,
        )
Exemplo n.º 5
0
def run_reduction(
    source_dir_to_reduce: Path,
    reduction_output_dir: Path,
    binary_manager: binaries_util.BinaryManager,
    settings: Settings,
) -> Path:
    test = test_util.metadata_read_from_source_dir(source_dir_to_reduce)
    shader_jobs = tool.get_shader_jobs(source_dir_to_reduce)

    # TODO: if needed, this could become a parameter to this function.
    shader_job_to_reduce = shader_jobs[0]

    if len(shader_jobs) > 1:
        check(
            len(shader_jobs) == 2
            and shader_jobs[1].name == test_util.VARIANT_DIR,
            AssertionError(
                "Can only reduce tests with shader jobs reference and variant, or just variant."
            ),
        )
        shader_job_to_reduce = shader_jobs[1]

    shader_transformation_suffixes = shader_job_util.get_related_suffixes_that_exist(
        shader_job_to_reduce.shader_job,
        language_suffix=(shader_job_util.SUFFIX_TRANSFORMATIONS, ),
    )

    shader_spv_suffixes = shader_job_util.get_related_suffixes_that_exist(
        shader_job_to_reduce.shader_job,
        language_suffix=(shader_job_util.SUFFIX_SPIRV, ))

    reduced_source_dir = source_dir_to_reduce

    for index, suffix in enumerate(shader_transformation_suffixes):
        # E.g. .frag.transformations -> .frag
        extension_to_reduce = str(Path(suffix).with_suffix(""))
        reduced_source_dir = run_reduction_part(
            reduction_part_output_dir=reduction_output_dir /
            f"0_{index}_{suffix.split('.')[1]}",
            source_dir_to_reduce=reduced_source_dir,
            shader_job_name_to_reduce=shader_job_to_reduce.name,
            extension_to_reduce=extension_to_reduce,
            preserve_semantics=True,
            binary_manager=binary_manager,
            settings=settings,
        )

    if (test.crash_signature != signature_util.BAD_IMAGE_SIGNATURE
            and not settings.skip_spirv_reduce):
        for index, suffix in enumerate(shader_spv_suffixes):
            # E.g. .frag.spv -> .frag
            extension_to_reduce = str(Path(suffix).with_suffix(""))
            reduced_source_dir = run_reduction_part(
                reduction_part_output_dir=reduction_output_dir /
                f"1_{index}_{suffix.split('.')[1]}",
                source_dir_to_reduce=reduced_source_dir,
                shader_job_name_to_reduce=shader_job_to_reduce.name,
                extension_to_reduce=extension_to_reduce,
                preserve_semantics=False,
                binary_manager=binary_manager,
                settings=settings,
            )

    # Create and return a symlink to the "best" reduction.
    return util.make_directory_symlink(
        new_symlink_file_path=reduction_output_dir / fuzz.BEST_REDUCTION_NAME,
        existing_dir=reduced_source_dir.parent,
    )
Exemplo n.º 6
0
def run_reduction_on_report(  # pylint: disable=too-many-locals;
        test_dir: Path, reports_dir: Path,
        binary_manager: binaries_util.BinaryManager) -> None:
    test = test_util.metadata_read(test_dir)

    check(
        bool(test.device and test.device.name),
        AssertionError(
            f"Cannot reduce {str(test_dir)}; "
            f"device must be specified in {str(test_util.get_metadata_path(test_dir))}"
        ),
    )

    check(
        bool(test.crash_signature),
        AssertionError(
            f"Cannot reduce {str(test_dir)} because there is no crash string specified."
        ),
    )

    source_dir = test_util.get_source_dir(test_dir)

    shader_jobs = tool.get_shader_jobs(source_dir)

    # TODO: if needed, this could become a parameter to this function.
    shader_job_to_reduce = shader_jobs[0]

    if len(shader_jobs) > 1:
        check(
            len(shader_jobs) == 2
            and shader_jobs[1].name == test_util.VARIANT_DIR,
            AssertionError(
                "Can only reduce tests with shader jobs reference and variant, or just variant."
            ),
        )
        shader_job_to_reduce = shader_jobs[1]

    shader_transformation_suffixes = shader_job_util.get_related_suffixes_that_exist(
        shader_job_to_reduce.shader_job,
        language_suffix=(shader_job_util.SUFFIX_TRANSFORMATIONS, ),
    )

    shader_spv_suffixes = shader_job_util.get_related_suffixes_that_exist(
        shader_job_to_reduce.shader_job,
        language_suffix=(shader_job_util.SUFFIX_SPIRV, ))

    try:
        reduced_test = test_dir

        for index, suffix in enumerate(shader_transformation_suffixes):
            # E.g. .frag.transformations -> .frag
            extension_to_reduce = str(Path(suffix).with_suffix(""))
            reduced_test = run_reduction(
                test_dir_reduction_output=test_dir,
                test_dir_to_reduce=reduced_test,
                shader_job_name_to_reduce=shader_job_to_reduce.name,
                extension_to_reduce=extension_to_reduce,
                preserve_semantics=True,
                binary_manager=binary_manager,
                reduction_name=f"0_{index}_{suffix.split('.')[1]}",
            )

        if test.crash_signature != signature_util.BAD_IMAGE_SIGNATURE:
            for index, suffix in enumerate(shader_spv_suffixes):
                # E.g. .frag.spv -> .frag
                extension_to_reduce = str(Path(suffix).with_suffix(""))
                reduced_test = run_reduction(
                    test_dir_reduction_output=test_dir,
                    test_dir_to_reduce=reduced_test,
                    shader_job_name_to_reduce=shader_job_to_reduce.name,
                    extension_to_reduce=extension_to_reduce,
                    preserve_semantics=False,
                    binary_manager=binary_manager,
                    reduction_name=f"1_{index}_{suffix.split('.')[1]}",
                )

        device_name = test.device.name

        # Create a symlink to the "best" reduction.
        best_reduced_test_link = test_util.get_reduced_test_dir(
            test_dir, device_name, fuzz.BEST_REDUCTION_NAME)
        util.make_directory_symlink(
            new_symlink_file_path=best_reduced_test_link,
            existing_dir=reduced_test)
    except ReductionFailedError as ex:
        # Create a symlink to the failed reduction so it is easy to investigate failed reductions.
        link_to_failed_reduction_path = (
            reports_dir / "failed_reductions" /
            f"{test_dir.name}_{ex.reduction_name}")
        util.make_directory_symlink(
            new_symlink_file_path=link_to_failed_reduction_path,
            existing_dir=ex.reduction_work_dir,
        )