Beispiel #1
0
    def execute_rule(
        self,
        args: Optional[Iterable[str]] = None,
        global_args: Optional[Iterable[str]] = None,
        env: Optional[Dict[str, str]] = None,
        exit_code: int = 0,
        additional_params: Optional[Iterable[Any]] = None,
    ) -> str:
        """Executes the @goal_rule for this test class.

        :API: public

        Returns the text output of the task.
        """
        # Create an OptionsBootstrapper for these args/env, and a captured Console instance.
        options_bootstrapper = create_options_bootstrapper(
            args=(*(global_args or []), self.goal_cls.name, *(args or [])), env=env,
        )
        BuildConfigInitializer.get(options_bootstrapper)
        full_options = options_bootstrapper.get_full_options(
            [*GlobalOptions.known_scope_infos(), *self.goal_cls.subsystem_cls.known_scope_infos()]
        )
        stdout, stderr = StringIO(), StringIO()
        console = Console(stdout=stdout, stderr=stderr)
        scheduler = self.scheduler
        workspace = Workspace(scheduler)

        # Run for the target specs parsed from the args.
        specs = SpecsCalculator.parse_specs(full_options.specs, self.build_root)
        params = Params(
            specs.provided_specs,
            console,
            options_bootstrapper,
            workspace,
            *(additional_params or []),
        )
        actual_exit_code = self.scheduler.run_goal_rule(self.goal_cls, params)

        # Flush and capture console output.
        console.flush()
        stdout_val = stdout.getvalue()
        stderr_val = stderr.getvalue()

        assert (
            exit_code == actual_exit_code
        ), f"Exited with {actual_exit_code} (expected {exit_code}):\nstdout:\n{stdout_val}\nstderr:\n{stderr_val}"

        return stdout_val
Beispiel #2
0
    def test_resolve_sources_snapshot(self) -> None:
        """This tests that convert filesystem specs and/or address specs into a single snapshot.

        Some important edge cases:
        - When a filesystem spec refers to a file without any owning target, it should be included
          in the snapshot.
        - If a file is covered both by an address spec and by a filesystem spec, we should merge it
          so that the file only shows up once.
        """
        self.create_files("demo", ["f1.txt", "f2.txt"])
        self.add_to_build_file("demo", "target(sources=['*.txt'])")
        specs = SpecsCalculator.parse_specs(["demo:demo", "demo/f1.txt", "demo/BUILD"])
        result = self.request_single_product(
            SourcesSnapshot, Params(specs, create_options_bootstrapper())
        )
        assert result.snapshot.files == ("demo/BUILD", "demo/f1.txt", "demo/f2.txt")
Beispiel #3
0
    def test_resolve_addresses(self) -> None:
        """This tests that we correctly handle resolving from both address and filesystem specs."""
        self.create_file("fs_spec/f.txt")
        self.add_to_build_file("fs_spec", "target(sources=['f.txt'])")
        self.create_file("address_spec/f.txt")
        self.add_to_build_file("address_spec", "target(sources=['f.txt'])")
        no_interaction_specs = ["fs_spec/f.txt", "address_spec:address_spec"]

        # If a generated subtarget's original base target is included via an address spec,
        # we will still include the generated subtarget for consistency. When we expand Targets
        # into their base targets this redundancy is removed, but during Address expansion we
        # get literal matches.
        self.create_files("multiple_files", ["f1.txt", "f2.txt"])
        self.add_to_build_file("multiple_files", "target(sources=['*.txt'])")
        multiple_files_specs = ["multiple_files/f2.txt", "multiple_files:multiple_files"]

        specs = SpecsCalculator.parse_specs([*no_interaction_specs, *multiple_files_specs])
        result = self.request_single_product(
            AddressesWithOrigins, Params(specs, create_options_bootstrapper())
        )
        assert set(result) == {
            AddressWithOrigin(
                Address("fs_spec", relative_file_path="f.txt"),
                origin=FilesystemLiteralSpec("fs_spec/f.txt"),
            ),
            AddressWithOrigin(
                Address("address_spec"), origin=SingleAddress("address_spec", "address_spec"),
            ),
            AddressWithOrigin(
                Address("multiple_files"), origin=SingleAddress("multiple_files", "multiple_files"),
            ),
            AddressWithOrigin(
                Address("multiple_files", relative_file_path="f2.txt"),
                origin=FilesystemLiteralSpec(file="multiple_files/f2.txt"),
            ),
        }