• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 24604025132

18 Apr 2026 11:49AM UTC coverage: 92.478% (-0.4%) from 92.924%
24604025132

Pull #23268

github

web-flow
Merge c60f47029 into a92bc34b6
Pull Request #23268: perf: Remove python coroutine/trampoline overhead in awaits for ~22% faster `dependencies` goal

31 of 37 new or added lines in 4 files covered. (83.78%)

443 existing lines in 21 files now uncovered.

91210 of 98629 relevant lines covered (92.48%)

4.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.26
/src/python/pants/core/goals/run_test.py
1
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
1✔
5

6
import os
1✔
7
import sys
1✔
8
from collections.abc import Iterable, Mapping
1✔
9
from typing import cast
1✔
10

11
import pytest
1✔
12
from _pytest.monkeypatch import MonkeyPatch
1✔
13

14
from pants.core.goals.run import (
1✔
15
    Run,
16
    RunDebugAdapterRequest,
17
    RunFieldSet,
18
    RunInSandboxBehavior,
19
    RunRequest,
20
    RunSubsystem,
21
    run,
22
)
23
from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem
1✔
24
from pants.engine.addresses import Address
1✔
25
from pants.engine.fs import CreateDigest, Digest, FileContent, Workspace
1✔
26
from pants.engine.internals.specs_rules import (
1✔
27
    AmbiguousImplementationsException,
28
    TooManyTargetsException,
29
)
30
from pants.engine.process import InteractiveProcess
1✔
31
from pants.engine.target import FieldSet, Target, TargetRootsToFieldSets
1✔
32
from pants.engine.unions import UnionMembership, UnionRule
1✔
33
from pants.option.global_options import GlobalOptions, KeepSandboxes
1✔
34
from pants.testutil.option_util import create_goal_subsystem, create_subsystem
1✔
35
from pants.testutil.rule_runner import RuleRunner, mock_console, run_rule_with_mocks
1✔
36
from pants.util.frozendict import FrozenDict
1✔
37

38

39
@pytest.fixture
1✔
40
def rule_runner() -> RuleRunner:
1✔
41
    return RuleRunner()
1✔
42

43

44
def create_mock_run_request(rule_runner: RuleRunner, program_text: bytes) -> RunRequest:
1✔
45
    digest = rule_runner.request(
1✔
46
        Digest,
47
        [CreateDigest([FileContent(path="program.py", content=program_text, is_executable=True)])],
48
    )
49
    return RunRequest(digest=digest, args=(os.path.join("{chroot}", "program.py"),))
1✔
50

51

52
def create_mock_run_debug_adapter_request(
1✔
53
    rule_runner: RuleRunner, program_text: bytes
54
) -> RunDebugAdapterRequest:
55
    return cast(RunDebugAdapterRequest, create_mock_run_request(rule_runner, program_text))
×
56

57

58
class TestRunFieldSet(RunFieldSet):
1✔
59
    __test__ = False
1✔
60

61
    required_fields = ()
1✔
62
    run_in_sandbox_behavior = RunInSandboxBehavior.NOT_SUPPORTED
1✔
63

64

65
class TestBinaryTarget(Target):
1✔
66
    __test__ = False
1✔
67

68
    alias = "binary"
1✔
69
    core_fields = ()
1✔
70

71

72
A_TARGET = TestBinaryTarget({}, Address("some/addr"))
1✔
73
A_FIELD_SET = TestRunFieldSet.create(A_TARGET)
1✔
74

75

76
def single_target_run(
1✔
77
    rule_runner: RuleRunner,
78
    monkeypatch: MonkeyPatch,
79
    *,
80
    program_text: bytes,
81
    targets_to_field_sets: Mapping[Target, Iterable[FieldSet]] = FrozenDict(
82
        {A_TARGET: (A_FIELD_SET,)}
83
    ),
84
) -> Run:
85
    workspace = Workspace(rule_runner.scheduler, _enforce_effects=False)
1✔
86

87
    def noop():
1✔
UNCOV
88
        pass
×
89

90
    monkeypatch.setattr("pants.engine.intrinsics.task_side_effected", noop)
1✔
91
    with mock_console(rule_runner.options_bootstrapper) as (console, _):
1✔
92
        return run_rule_with_mocks(
1✔
93
            run,
94
            rule_args=[
95
                create_goal_subsystem(RunSubsystem, args=[], cleanup=True, debug_adapter=False),
96
                create_subsystem(
97
                    DebugAdapterSubsystem,
98
                    host="127.0.0.1",
99
                    port="5678",
100
                ),
101
                create_subsystem(
102
                    GlobalOptions,
103
                    pants_workdir=rule_runner.pants_workdir,
104
                    keep_sandboxes=KeepSandboxes.never,
105
                ),
106
                workspace,
107
                rule_runner.environment,
108
            ],
109
            mock_calls={
110
                "pants.engine.internals.specs_rules.find_valid_field_sets_for_target_roots": lambda _: TargetRootsToFieldSets(
111
                    targets_to_field_sets
112
                ),
113
                "pants.core.goals.run.generate_run_request": lambda _: create_mock_run_request(
114
                    rule_runner, program_text
115
                ),
116
                "pants.core.goals.run.generate_run_debug_adapter_request": lambda _: create_mock_run_request(
117
                    rule_runner, program_text
118
                ),
119
                "pants.engine.intrinsics._interactive_process": lambda interactive_process: rule_runner.run_interactive_process(
120
                    interactive_process
121
                ),
122
            },
123
            union_membership=UnionMembership.from_rules(
124
                {UnionRule(RunFieldSet, TestRunFieldSet)},
125
            ),
126
        )
127

128

129
def test_normal_run(rule_runner: RuleRunner, monkeypatch: MonkeyPatch) -> None:
1✔
130
    program_text = f'#!{sys.executable}\nprint("hello")'.encode()
1✔
131
    res = single_target_run(
1✔
132
        rule_runner,
133
        monkeypatch,
134
        program_text=program_text,
135
    )
136
    assert res.exit_code == 0
1✔
137

138

139
def test_materialize_input_files(rule_runner: RuleRunner, monkeypatch: MonkeyPatch) -> None:
1✔
140
    program_text = f'#!{sys.executable}\nprint("hello")'.encode()
1✔
141
    binary = create_mock_run_request(rule_runner, program_text)
1✔
142
    with mock_console(rule_runner.options_bootstrapper):
1✔
143
        result = rule_runner.run_interactive_process(
1✔
144
            InteractiveProcess(
145
                argv=("./program.py",),
146
                run_in_workspace=False,
147
                input_digest=binary.digest,
148
            )
149
        )
150
    assert result.exit_code == 0
1✔
151

152

153
def test_failed_run(rule_runner: RuleRunner, monkeypatch: MonkeyPatch) -> None:
1✔
154
    program_text = f'#!{sys.executable}\nraise RuntimeError("foo")'.encode()
1✔
155
    res = single_target_run(rule_runner, monkeypatch, program_text=program_text)
1✔
156
    assert res.exit_code == 1
1✔
157

158

159
def test_multi_target_error(rule_runner: RuleRunner, monkeypatch: MonkeyPatch) -> None:
1✔
160
    program_text = f'#!{sys.executable}\nprint("hello")'.encode()
1✔
161
    t1 = TestBinaryTarget({}, Address("some/addr"))
1✔
162
    t1_fs = TestRunFieldSet.create(t1)
1✔
163
    t2 = TestBinaryTarget({}, Address("some/other_addr"))
1✔
164
    t2_fs = TestRunFieldSet.create(t2)
1✔
165
    with pytest.raises(TooManyTargetsException):
1✔
166
        single_target_run(
1✔
167
            rule_runner,
168
            monkeypatch,
169
            program_text=program_text,
170
            targets_to_field_sets={t1: [t1_fs], t2: [t2_fs]},
171
        )
172

173

174
def test_multi_field_set_error(rule_runner: RuleRunner, monkeypatch: MonkeyPatch) -> None:
1✔
175
    program_text = f'#!{sys.executable}\nprint("hello")'.encode()
1✔
176
    target = TestBinaryTarget({}, Address("some/addr"))
1✔
177
    fs1 = TestRunFieldSet.create(target)
1✔
178
    fs2 = TestRunFieldSet.create(target)
1✔
179
    with pytest.raises(AmbiguousImplementationsException):
1✔
180
        single_target_run(
1✔
181
            rule_runner,
182
            monkeypatch,
183
            program_text=program_text,
184
            targets_to_field_sets={target: [fs1, fs2]},
185
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc