Exemple #1
0
def test_prepare_scheduler():
    # A core with no services.
    def create_services(bootstrap_options, legacy_graph_scheduler):
        return PantsServices()

    core = PantsDaemonCore(create_services)

    first_scheduler = core.prepare_scheduler(create_options_bootstrapper(args=["-ldebug"]))
    second_scheduler = core.prepare_scheduler(create_options_bootstrapper(args=["-lwarn"]))

    assert first_scheduler is not second_scheduler
Exemple #2
0
def test_prepare_scheduler():
    # A core with no services.
    def create_services(bootstrap_options, legacy_graph_scheduler):
        return PantsServices()

    core = PantsDaemonCore(create_options_bootstrapper([]), PyExecutor(2, 4),
                           create_services)

    first_scheduler, first_options_initializer = core.prepare(
        create_options_bootstrapper(["-ldebug"]))
    second_scheduler, second_options_initializer = core.prepare(
        create_options_bootstrapper(["-lwarn"]))
    assert first_scheduler is not second_scheduler
    assert first_options_initializer is second_options_initializer
Exemple #3
0
def test_filter_targets(rule_runner: RuleRunner) -> None:
    class MockTarget(Target):
        alias = "target"
        core_fields = (Sources, )

    class MockTargetWithNoSourcesField(Target):
        alias = "no_sources"
        core_fields = ()

    rule_runner.create_file("f1.txt")
    valid_tgt = MockTarget({Sources.alias: ["f1.txt"]},
                           address=Address("", target_name="valid"))
    empty_tgt = MockTarget({}, address=Address("", target_name="empty"))
    invalid_tgt = MockTargetWithNoSourcesField({},
                                               address=Address(
                                                   "", target_name="invalid"))

    result = rule_runner.request_product(
        TargetsWithSources,
        [
            TargetsWithSourcesRequest([valid_tgt, empty_tgt, invalid_tgt]),
            create_options_bootstrapper(),
        ],
    )
    assert tuple(result) == (valid_tgt, )
Exemple #4
0
def test_filter_field_sets(rule_runner: RuleRunner) -> None:
    @dataclass(frozen=True)
    class MockFieldSet(FieldSet):
        sources: Sources
        # Another field to demo that we will preserve the whole FieldSet data structure.
        tags: Tags

    rule_runner.create_file("f1.txt")
    valid_addr = Address("", target_name="valid")
    valid_field_set = MockFieldSet(valid_addr,
                                   Sources(["f1.txt"], address=valid_addr),
                                   Tags(None, address=valid_addr))

    empty_addr = Address("", target_name="empty")
    empty_field_set = MockFieldSet(empty_addr, Sources(None,
                                                       address=empty_addr),
                                   Tags(None, address=empty_addr))

    result = rule_runner.request_product(
        FieldSetsWithSources,
        [
            FieldSetsWithSourcesRequest([valid_field_set, empty_field_set]),
            create_options_bootstrapper(),
        ],
    )
    assert tuple(result) == (valid_field_set, )
Exemple #5
0
    def test_map_third_party_modules_to_addresses(self) -> None:
        self.add_to_build_file(
            "3rdparty/python",
            dedent("""\
                python_requirement_library(
                  name='ansicolors',
                  requirements=['ansicolors==1.21'],
                  module_mapping={'ansicolors': ['colors']},
                )

                python_requirement_library(
                  name='req1',
                  requirements=['req1', 'two_owners'],
                )

                python_requirement_library(
                  name='un_normalized',
                  requirements=['Un-Normalized-Project>3', 'two_owners'],
                )
                """),
        )
        result = self.request_product(ThirdPartyModuleToAddressMapping,
                                      [create_options_bootstrapper()])
        assert result.mapping == FrozenDict({
            "colors":
            Address.parse("3rdparty/python:ansicolors"),
            "req1":
            Address.parse("3rdparty/python:req1"),
            "un_normalized_project":
            Address.parse("3rdparty/python:un_normalized"),
        })
 def run_docformatter(
     self, targets: List[Target], *, passthrough_args: Optional[str] = None, skip: bool = False
 ) -> Tuple[Sequence[LintResult], FmtResult]:
     args = ["--backend-packages=pants.backend.python.lint.docformatter"]
     if passthrough_args:
         args.append(f"--docformatter-args='{passthrough_args}'")
     if skip:
         args.append("--docformatter-skip")
     options_bootstrapper = create_options_bootstrapper(args=args)
     field_sets = [DocformatterFieldSet.create(tgt) for tgt in targets]
     lint_results = self.request_product(
         LintResults, [DocformatterRequest(field_sets), options_bootstrapper]
     )
     input_sources = self.request_product(
         SourceFiles,
         [
             SourceFilesRequest(field_set.sources for field_set in field_sets),
             options_bootstrapper,
         ],
     )
     fmt_result = self.request_product(
         FmtResult,
         [
             DocformatterRequest(field_sets, prior_formatter_result=input_sources.snapshot),
             options_bootstrapper,
         ],
     )
     return lint_results.results, fmt_result
 def run_pylint(
     self,
     targets: List[Target],
     *,
     config: Optional[str] = None,
     passthrough_args: Optional[str] = None,
     skip: bool = False,
     additional_args: Optional[List[str]] = None,
 ) -> Sequence[LintResult]:
     args = list(self.global_args)
     if config:
         self.create_file(relpath="pylintrc", contents=config)
         args.append("--pylint-config=pylintrc")
     if passthrough_args:
         args.append(f"--pylint-args='{passthrough_args}'")
     if skip:
         args.append("--pylint-skip")
     if additional_args:
         args.extend(additional_args)
     results = self.request_product(
         LintResults,
         [
             PylintRequest(PylintFieldSet.create(tgt) for tgt in targets),
             create_options_bootstrapper(args=args),
         ],
     )
     return results.results
 def run_flake8(
     self,
     targets: List[Target],
     *,
     config: Optional[str] = None,
     passthrough_args: Optional[str] = None,
     skip: bool = False,
     additional_args: Optional[List[str]] = None,
 ) -> Sequence[LintResult]:
     args = ["--backend-packages=pants.backend.python.lint.flake8"]
     if config:
         self.create_file(relpath=".flake8", contents=config)
         args.append("--flake8-config=.flake8")
     if passthrough_args:
         args.append(f"--flake8-args='{passthrough_args}'")
     if skip:
         args.append("--flake8-skip")
     if additional_args:
         args.extend(additional_args)
     results = self.request_product(
         LintResults,
         [
             Flake8Request(Flake8FieldSet.create(tgt) for tgt in targets),
             create_options_bootstrapper(args=args),
         ],
     )
     return results.results
Exemple #9
0
def test_target_adaptor_parsed_correctly(
        target_adaptor_rule_runner: RuleRunner) -> None:
    target_adaptor_rule_runner.add_to_build_file(
        "helloworld",
        dedent("""\
            mock_tgt(
                fake_field=42,
                dependencies=[
                    # Because we don't follow dependencies or even parse dependencies, this
                    # self-cycle should be fine.
                    "helloworld",
                    ":sibling",
                    "helloworld/util",
                    "helloworld/util:tests",
                ],
            )
            """),
    )
    addr = Address("helloworld")
    target_adaptor = target_adaptor_rule_runner.request_product(
        TargetAdaptor, [addr, create_options_bootstrapper()])
    assert target_adaptor.name == "helloworld"
    assert target_adaptor.type_alias == "mock_tgt"
    assert target_adaptor.kwargs["dependencies"] == [
        "helloworld",
        ":sibling",
        "helloworld/util",
        "helloworld/util:tests",
    ]
    # NB: TargetAdaptors do not validate what fields are valid. The Target API should error
    # when encountering this, but it's fine at this stage.
    assert target_adaptor.kwargs["fake_field"] == 42
Exemple #10
0
def test_line_oriented_goal() -> None:
    class OutputtingGoalOptions(LineOriented, GoalSubsystem):
        name = "dummy"

    class OutputtingGoal(Goal):
        subsystem_cls = OutputtingGoalOptions

    @goal_rule
    def output_rule(console: Console,
                    options: OutputtingGoalOptions) -> OutputtingGoal:
        with options.output(console) as write_stdout:
            write_stdout("output...")
        with options.line_oriented(console) as print_stdout:
            print_stdout("line oriented")
        return OutputtingGoal(0)

    with mock_console(create_options_bootstrapper()) as (console,
                                                         stdio_reader):
        result: OutputtingGoal = run_rule_with_mocks(
            output_rule,
            rule_args=[
                console,
                create_goal_subsystem(OutputtingGoalOptions,
                                      sep="\\n",
                                      output_file=None),
            ],
        )
        assert result.exit_code == 0
        assert stdio_reader.get_stdout() == "output...line oriented\n"
Exemple #11
0
def test_context_object_on_streaming_workunits(
        rule_runner: RuleRunner, run_tracker: RunTracker) -> None:
    scheduler = rule_runner.scheduler

    def callback(**kwargs) -> None:
        context = kwargs["context"]
        assert isinstance(context, StreamingWorkunitContext)

        completed_workunits = kwargs["completed_workunits"]
        for workunit in completed_workunits:
            if "artifacts" in workunit and "stdout_digest" in workunit[
                    "artifacts"]:
                digest = workunit["artifacts"]["stdout_digest"]
                output = context.single_file_digests_to_bytes([digest])
                assert output == (b"stdout output\n", )

    handler = StreamingWorkunitHandler(
        scheduler,
        run_tracker=run_tracker,
        callbacks=[callback],
        report_interval_seconds=0.01,
        max_workunit_verbosity=LogLevel.INFO,
        specs=Specs.empty(),
        options_bootstrapper=create_options_bootstrapper([]),
    )

    stdout_process = Process(argv=("/bin/bash", "-c",
                                   "/bin/echo 'stdout output'"),
                             description="Stdout process")

    with handler.session():
        rule_runner.request(ProcessResult, [stdout_process])
Exemple #12
0
    def assert_injected(
        self,
        *,
        source_roots: List[str],
        original_declared_files: List[str],
        original_undeclared_files: List[str],
        expected_discovered: List[str],
    ) -> None:
        for f in original_undeclared_files:
            self.create_file(f, "# undeclared")
        request = AncestorFilesRequest(
            "__init__.py",
            self.make_snapshot({fp: "# declared" for fp in original_declared_files}),
        )
        bootstrapper = create_options_bootstrapper(args=[f"--source-root-patterns={source_roots}"])
        result = self.request_product(AncestorFiles, [request, bootstrapper]).snapshot
        assert list(result.files) == sorted(expected_discovered)

        materialized_result = self.request_product(DigestContents, [result.digest])
        for file_content in materialized_result:
            path = file_content.path
            if not path.endswith("__init__.py"):
                continue
            assert path in original_declared_files or path in expected_discovered
            expected = b"# declared" if path in original_declared_files else b"# undeclared"
            assert file_content.content == expected
Exemple #13
0
def run_goal(
    targets: Sequence[Target],
    *,
    target_type: list[str] | None = None,
    address_regex: list[str] | None = None,
    tag_regex: list[str] | None = None,
    granularity: TargetGranularity | None = None,
) -> str:
    with mock_console(create_options_bootstrapper()) as (console,
                                                         stdio_reader):
        run_rule_with_mocks(
            filter_targets,
            rule_args=[
                Targets(targets),
                create_goal_subsystem(
                    FilterSubsystem,
                    sep="\\n",
                    output_file=None,
                    target_type=target_type or [],
                    address_regex=address_regex or [],
                    tag_regex=tag_regex or [],
                    granularity=granularity or TargetGranularity.all_targets,
                    # Deprecated.
                    type=[],
                    target=[],
                    regex=[],
                    ancestor=[],
                ),
                console,
                RegisteredTargetTypes.create({type(tgt)
                                              for tgt in targets}),
            ],
        )
        assert not stdio_reader.get_stderr()
        return stdio_reader.get_stdout()
Exemple #14
0
def test_run_information(exit_code, expected, **kwargs) -> None:
    with temporary_dir() as buildroot:
        with environment_as(PANTS_BUILDROOT_OVERRIDE=buildroot):
            run_tracker = RunTracker(
                create_options_bootstrapper([]).bootstrap_options)

            specs = ["src/python/pants/goal/run_tracker_test.py"]
            run_tracker.start(run_start_time=time.time(), specs=specs)

            run_information = run_tracker.run_information()
            assert run_information["buildroot"] == get_buildroot()
            assert run_information["path"] == get_buildroot()
            # freezegun doesn't seem to accurately mock the time zone,
            # (i.e. the time zone used depends on that of the machine that
            # executes the test), so we can only safely assert that the
            # month and year appear in the human-readable string contained
            # in the "datetime" key
            assert "Jan" in run_information["datetime"]
            assert "2020" in run_information["datetime"]
            assert run_information["timestamp"] == 1578657601.0
            assert run_information["user"] == getpass.getuser()
            assert run_information["version"] == VERSION
            assert re.match("pants.*run_tracker_test.py",
                            run_information["cmd_line"])
            assert run_information["specs_from_command_line"] == [
                "src/python/pants/goal/run_tracker_test.py"
            ]

            frozen_time = kwargs["frozen_time"]
            frozen_time.tick(delta=datetime.timedelta(seconds=1))

            run_tracker.end_run(exit_code)
            run_information_after_ended = run_tracker.run_information()
            assert run_information_after_ended["outcome"] == expected
Exemple #15
0
def test_run_information(exit_code: ExitCode, expected: str, tmp_path: Path,
                         **kwargs) -> None:
    frozen_time = kwargs["frozen_time"]
    buildroot = tmp_path.as_posix()
    with environment_as(PANTS_BUILDROOT_OVERRIDE=buildroot):
        spec = "test/example.py"
        ob = create_options_bootstrapper(["list", spec])
        run_tracker = RunTracker(ob.args, ob.bootstrap_options)

        specs = [spec]
        run_tracker.start(run_start_time=time.time(), specs=specs)

        run_information = run_tracker.run_information()
        assert run_information["buildroot"] == get_buildroot()
        assert run_information["path"] == get_buildroot()
        # freezegun doesn't seem to accurately mock the time zone,
        # (i.e. the time zone used depends on that of the machine that
        # executes the test), so we can only safely assert that the
        # month and year appear in the human-readable string contained
        # in the "datetime" key
        assert "Jan" in run_information["datetime"]
        assert "2020" in run_information["datetime"]
        assert run_information["timestamp"] == 1578657601.0
        assert run_information["user"] == getpass.getuser()
        assert run_information["version"] == VERSION
        assert re.match(f"pants.*{spec}", run_information["cmd_line"])
        assert run_information["specs_from_command_line"] == [spec]

        frozen_time.tick(delta=datetime.timedelta(seconds=1))
        run_tracker.end_run(exit_code)
        run_information_after_ended = run_tracker.run_information()
        assert run_information_after_ended["outcome"] == expected
Exemple #16
0
def run_typecheck_rule(
    *,
    request_types: Sequence[Type[CheckRequest]],
    targets: list[Target],
    only: list[str] | None = None,
) -> Tuple[int, str]:
    union_membership = UnionMembership({CheckRequest: request_types})
    check_subsystem = create_subsystem(CheckSubsystem, only=only or [])
    with mock_console(create_options_bootstrapper()) as (console, stdio_reader):
        rule_runner = RuleRunner()
        result: Check = run_rule_with_mocks(
            check,
            rule_args=[
                console,
                Workspace(rule_runner.scheduler, _enforce_effects=False),
                Targets(targets),
                DistDir(relpath=Path("dist")),
                union_membership,
                check_subsystem,
            ],
            mock_gets=[
                MockGet(
                    output_type=CheckResults,
                    input_type=CheckRequest,
                    mock=lambda field_set_collection: field_set_collection.check_results,
                ),
            ],
            union_membership=union_membership,
        )
        assert not stdio_reader.get_stdout()
        return result.exit_code, stdio_reader.get_stderr()
Exemple #17
0
def test_streaming_workunits_expanded_specs(run_tracker: RunTracker) -> None:
    rule_runner = RuleRunner(
        target_types=[PythonLibrary],
        rules=[
            QueryRule(ProcessResult, (Process,)),
        ],
    )

    rule_runner.set_options(["--backend-packages=pants.backend.python"])

    rule_runner.create_file("src/python/somefiles/BUILD", "python_library()")
    rule_runner.create_file("src/python/somefiles/a.py", "print('')")
    rule_runner.create_file("src/python/somefiles/b.py", "print('')")

    rule_runner.create_file("src/python/others/BUILD", "python_library()")
    rule_runner.create_file("src/python/others/a.py", "print('')")
    rule_runner.create_file("src/python/others/b.py", "print('')")

    specs = SpecsParser(get_buildroot()).parse_specs(
        ["src/python/somefiles::", "src/python/others/b.py"]
    )

    class Callback(WorkunitsCallback):
        @property
        def can_finish_async(self) -> bool:
            return False

        def __call__(self, **kwargs) -> None:
            context = kwargs["context"]
            assert isinstance(context, StreamingWorkunitContext)

            expanded = context.get_expanded_specs()
            targets = expanded.targets

            assert len(targets.keys()) == 2
            assert targets["src/python/others/b.py"] == [
                TargetInfo(filename="src/python/others/b.py")
            ]
            assert set(targets["src/python/somefiles"]) == {
                TargetInfo(filename="src/python/somefiles/a.py"),
                TargetInfo(filename="src/python/somefiles/b.py"),
            }

    handler = StreamingWorkunitHandler(
        scheduler=rule_runner.scheduler,
        run_tracker=run_tracker,
        callbacks=[Callback()],
        report_interval_seconds=0.01,
        max_workunit_verbosity=LogLevel.INFO,
        specs=specs,
        options_bootstrapper=create_options_bootstrapper(
            ["--backend-packages=pants.backend.python"]
        ),
        pantsd=False,
    )
    stdout_process = Process(
        argv=("/bin/bash", "-c", "/bin/echo 'stdout output'"), description="Stdout process"
    )
    with handler:
        rule_runner.request(ProcessResult, [stdout_process])
Exemple #18
0
def test_log_filtering_by_rule() -> None:
    with temporary_dir() as tmpdir:
        ob = create_options_bootstrapper([
            f"--pants-workdir={tmpdir}",
            '--log-levels-by-target={"debug_target": "debug"}'
        ])

        # Do not set up a stdio destination, meaning that all messages will go to the log.
        global_bootstrap_options = ob.bootstrap_options.for_global_scope()
        with initialize_stdio(global_bootstrap_options):
            native_engine.write_log(msg="log msg one",
                                    level=LogLevel.INFO.level,
                                    target="some.target")
            native_engine.write_log(msg="log msg two",
                                    level=LogLevel.DEBUG.level,
                                    target="some.other.target")
            native_engine.write_log(msg="log msg three",
                                    level=LogLevel.DEBUG.level,
                                    target="debug_target")

            loglines = (Path(global_bootstrap_options.pants_workdir,
                             "pants.log").read_text().splitlines())

            assert "[INFO] log msg one" in loglines[0]
            assert "[DEBUG] log msg three" in loglines[1]
            assert len(loglines) == 2
Exemple #19
0
def create_dynamic_remote_options(
    *,
    initial_headers: dict[str, str] | None = None,
    address: str | None = "grpc://fake.url:10",
    token_path: str | None = None,
    plugin: str | None = None,
) -> DynamicRemoteOptions:
    if initial_headers is None:
        initial_headers = {}
    args = [
        "--remote-cache-read",
        f"--remote-execution-address={address}",
        f"--remote-store-address={address}",
        f"--remote-store-headers={initial_headers}",
        f"--remote-execution-headers={initial_headers}",
        "--remote-instance-name=main",
    ]
    if token_path:
        args.append(f"--remote-oauth-bearer-token-path={token_path}")
    if plugin:
        args.append(f"--remote-auth-plugin={plugin}")
    ob = create_options_bootstrapper(args)
    env = CompleteEnvironment({})
    _build_config, options = OptionsInitializer(ob).build_config_and_options(ob, env, raise_=False)
    return DynamicRemoteOptions.from_options(options, env)[0]
Exemple #20
0
    def run_goal_rule(
        self,
        goal: Type[Goal],
        *,
        global_args: Optional[Iterable[str]] = None,
        args: Optional[Iterable[str]] = None,
        env: Optional[Mapping[str, str]] = None,
    ) -> GoalRuleResult:
        options_bootstrapper = create_options_bootstrapper(
            args=(*(global_args or []), goal.name, *(args or [])),
            env=env,
        )

        raw_specs = options_bootstrapper.get_full_options([
            *GlobalOptions.known_scope_infos(),
            *goal.subsystem_cls.known_scope_infos()
        ]).specs
        specs = SpecsParser(self.build_root).parse_specs(raw_specs)

        stdout, stderr = StringIO(), StringIO()
        console = Console(stdout=stdout, stderr=stderr)

        exit_code = self.scheduler.run_goal_rule(
            goal,
            Params(
                specs,
                console,
                options_bootstrapper,
                Workspace(self.scheduler),
                InteractiveRunner(self.scheduler),
            ),
        )

        console.flush()
        return GoalRuleResult(exit_code, stdout.getvalue(), stderr.getvalue())
Exemple #21
0
 def run_mypy(
     self,
     targets: List[Target],
     *,
     config: Optional[str] = None,
     passthrough_args: Optional[str] = None,
     skip: bool = False,
     additional_args: Optional[List[str]] = None,
 ) -> Sequence[TypecheckResult]:
     args = list(self.global_args)
     if config:
         self.create_file(relpath="mypy.ini", contents=config)
         args.append("--mypy-config=mypy.ini")
     if passthrough_args:
         args.append(f"--mypy-args='{passthrough_args}'")
     if skip:
         args.append("--mypy-skip")
     if additional_args:
         args.extend(additional_args)
     result = self.request_product(
         TypecheckResults,
         [
             MyPyRequest(MyPyFieldSet.create(tgt) for tgt in targets),
             create_options_bootstrapper(args=args),
         ],
     )
     return result.results
Exemple #22
0
 def make_target(
     self,
     source_files: List[FileContent],
     *,
     package: Optional[str] = None,
     name: str = "target",
 ) -> Target:
     if not package:
         package = self.package
     for source_file in source_files:
         self.create_file(source_file.path, source_file.content.decode())
     source_globs = [
         PurePath(source_file.path).name for source_file in source_files
     ]
     self.add_to_build_file(
         f"{package}",
         dedent(f"""\
             python_library(
                 name={repr(name)},
                 sources={source_globs},
             )
             """),
     )
     return self.request_product(
         WrappedTarget,
         [
             Address(package, target_name=name),
             create_options_bootstrapper(args=self.global_args),
         ],
     ).target
Exemple #23
0
def test_anonymous_telemetry_with_no_repo_id() -> None:
    with temporary_dir() as buildroot:
        with environment_as(PANTS_BUILDROOT_OVERRIDE=buildroot):
            opts = create_options_bootstrapper([]).bootstrap_options
            run_tracker = RunTracker(opts)
            run_tracker.start(run_start_time=time.time(), specs=[])
            run_tracker.end_run(PANTS_SUCCEEDED_EXIT_CODE)
            repo_id = ""
            telemetry = run_tracker.get_anonymous_telemetry_data(repo_id)

            # Check that these keys have non-trivial values.
            for key in (
                    "run_id",
                    "timestamp",
                    "duration",
                    "outcome",
                    "platform",
                    "python_implementation",
                    "python_version",
                    "pants_version",
            ):
                assert bool(telemetry.get(key))

            for key in ("repo_id", "machine_id", "user_id"):
                assert telemetry.get(key) == ""
Exemple #24
0
    def set_options(
        self,
        args: Iterable[str],
        *,
        env: Mapping[str, str] | None = None,
        env_inherit: set[str] | None = None,
    ) -> None:
        """Update the engine session with new options and/or environment variables.

        The environment variables will be used to set the `CompleteEnvironment`, which is the
        environment variables captured by the parent Pants process. Some rules use this to be able
        to read arbitrary env vars. Any options that start with `PANTS_` will also be used to set
        options.

        Environment variables listed in `env_inherit` and not in `env` will be inherited from the test
        runner's environment (os.environ)

        This will override any previously configured values.
        """
        env = {
            **{
                k: os.environ[k]
                for k in (env_inherit or set()) if k in os.environ
            },
            **(env or {}),
        }
        self.options_bootstrapper = create_options_bootstrapper(args=args,
                                                                env=env)
        self.environment = CompleteEnvironment(env)
        self._set_new_session(self.scheduler.scheduler)
Exemple #25
0
def test_source_roots_request() -> None:
    rule_runner = RuleRunner(rules=[
        *source_root_rules(),
        QueryRule(SourceRootsResult, (SourceRootsRequest,
                                      OptionsBootstrapper)),
    ])
    req = SourceRootsRequest(
        files=(PurePath("src/python/foo/bar.py"),
               PurePath("tests/python/foo/bar_test.py")),
        dirs=(PurePath("src/python/foo"), PurePath("src/python/baz/qux")),
    )
    res = rule_runner.request_product(
        SourceRootsResult,
        [
            req,
            create_options_bootstrapper(
                args=["--source-root-patterns=['src/python','tests/python']"]),
        ],
    )
    assert {
        PurePath("src/python/foo/bar.py"): SourceRoot("src/python"),
        PurePath("tests/python/foo/bar_test.py"): SourceRoot("tests/python"),
        PurePath("src/python/foo"): SourceRoot("src/python"),
        PurePath("src/python/baz/qux"): SourceRoot("src/python"),
    } == dict(res.path_to_root)
Exemple #26
0
def run_goal(targets: list[MockTarget],
             *,
             show_documented: bool = False) -> tuple[str, str]:
    with mock_console(create_options_bootstrapper()) as (console,
                                                         stdio_reader):
        run_rule_with_mocks(
            list_targets,
            rule_args=[
                Addresses(tgt.address for tgt in targets),
                create_goal_subsystem(
                    ListSubsystem,
                    sep="\\n",
                    output_file=None,
                    documented=show_documented,
                ),
                console,
            ],
            mock_gets=[
                MockGet(
                    output_type=UnexpandedTargets,
                    input_type=Addresses,
                    mock=lambda _: UnexpandedTargets(targets),
                )
            ],
        )
        return stdio_reader.get_stdout(), stdio_reader.get_stderr()
Exemple #27
0
def create_execution_options(
    *,
    initial_headers: dict[str, str],
    token_path: str | None = None,
    plugin: str | None = None,
    remote_store_address: str = "grpc://fake.url:10",
    remote_execution_address: str = "grpc://fake.url:10",
    local_only: bool = False,
) -> ExecutionOptions:
    args = [
        "--remote-cache-read",
        f"--remote-execution-address={remote_execution_address}",
        f"--remote-store-address={remote_store_address}",
        f"--remote-store-headers={initial_headers}",
        f"--remote-execution-headers={initial_headers}",
        "--remote-instance-name=main",
    ]
    if token_path:
        args.append(f"--remote-oauth-bearer-token-path={token_path}")
    if plugin:
        args.append(f"--remote-auth-plugin={plugin}")
    ob = create_options_bootstrapper(args)
    env = CompleteEnvironment({})
    _build_config, options = OptionsInitializer(
        ob, env).build_config_and_options(ob, env, raise_=False)
    return ExecutionOptions.from_options(options, env, local_only=local_only)
Exemple #28
0
def run_typecheck_rule(
    *,
    request_types: List[Type[TypecheckRequest]],
    targets: List[Target],
    include_sources: bool = True,
) -> Tuple[int, str]:
    union_membership = UnionMembership({TypecheckRequest: request_types})
    with mock_console(create_options_bootstrapper()) as (console,
                                                         stdio_reader):
        result: Typecheck = run_rule_with_mocks(
            typecheck,
            rule_args=[console, Targets(targets), union_membership],
            mock_gets=[
                MockGet(
                    output_type=EnrichedTypecheckResults,
                    input_type=TypecheckRequest,
                    mock=lambda field_set_collection: field_set_collection.
                    typecheck_results,
                ),
                MockGet(
                    output_type=FieldSetsWithSources,
                    input_type=FieldSetsWithSourcesRequest,
                    mock=lambda field_sets: FieldSetsWithSources(
                        field_sets if include_sources else ()),
                ),
            ],
            union_membership=union_membership,
        )
        assert not stdio_reader.get_stdout()
        return result.exit_code, stdio_reader.get_stderr()
    def test_options_parse_memoization(self):
        # Confirm that re-executing with a new-but-identical Options object results in memoization.

        def parse(ob):
            return self.request_product(ScopedOptions,
                                        [Scope(GLOBAL_SCOPE), ob])

        # If two OptionsBootstrapper instances are not equal, memoization will definitely not kick in.
        one_opts = create_options_bootstrapper()
        two_opts = create_options_bootstrapper()
        self.assertEqual(one_opts, two_opts)
        self.assertEqual(hash(one_opts), hash(two_opts))

        # If they are equal, executing parsing on them should result in a memoized object.
        one = parse(one_opts)
        two = parse(two_opts)
        self.assertEqual(one, two)
        self.assertIs(one, two)
Exemple #30
0
def test_more_complicated_engine_aware(rule_runner: RuleRunner,
                                       run_tracker: RunTracker) -> None:
    tracker = WorkunitTracker()
    handler = StreamingWorkunitHandler(
        rule_runner.scheduler,
        run_tracker=run_tracker,
        callbacks=[tracker.add],
        report_interval_seconds=0.01,
        max_workunit_verbosity=LogLevel.TRACE,
        specs=Specs.empty(),
        options_bootstrapper=create_options_bootstrapper([]),
    )
    with handler.session():
        input_1 = CreateDigest((
            FileContent(path="a.txt", content=b"alpha"),
            FileContent(path="b.txt", content=b"beta"),
        ))
        digest_1 = rule_runner.request(Digest, [input_1])
        snapshot_1 = rule_runner.request(Snapshot, [digest_1])

        input_2 = CreateDigest((FileContent(path="g.txt", content=b"gamma"), ))
        digest_2 = rule_runner.request(Digest, [input_2])
        snapshot_2 = rule_runner.request(Snapshot, [digest_2])

        input = ComplicatedInput(snapshot_1=snapshot_1, snapshot_2=snapshot_2)

        rule_runner.request(Output, [input])

    finished = list(
        itertools.chain.from_iterable(tracker.finished_workunit_chunks))
    workunit = next(
        item for item in finished
        if item["name"] == "pants.engine.internals.engine_test.a_rule")

    streaming_workunit_context = handler._context

    artifacts = workunit["artifacts"]
    output_snapshot_1 = artifacts["snapshot_1"]
    output_snapshot_2 = artifacts["snapshot_2"]

    output_contents_list = streaming_workunit_context.snapshots_to_file_contents(
        [output_snapshot_1, output_snapshot_2])
    assert len(output_contents_list) == 2

    assert isinstance(output_contents_list[0], DigestContents)
    assert isinstance(output_contents_list[1], DigestContents)

    digest_contents_1 = output_contents_list[0]
    digest_contents_2 = output_contents_list[1]

    assert len(tuple(x for x in digest_contents_1
                     if x.content == b"alpha")) == 1
    assert len(tuple(x for x in digest_contents_1
                     if x.content == b"beta")) == 1

    assert len(tuple(x for x in digest_contents_2
                     if x.content == b"gamma")) == 1