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

pantsbuild / pants / 18822648545

26 Oct 2025 07:24PM UTC coverage: 79.831% (-0.4%) from 80.28%
18822648545

Pull #22809

github

web-flow
Merge 9401c4830 into 170094e99
Pull Request #22809: golang: fix Go SDK version check for coverage experiment

0 of 1 new or added line in 1 file covered. (0.0%)

439 existing lines in 25 files now uncovered.

77436 of 97000 relevant lines covered (79.83%)

3.35 hits per line

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

55.45
/src/python/pants/backend/go/util_rules/build_opts_test.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3
from __future__ import annotations
1✔
4

5
import os
1✔
6
import pprint
1✔
7
import subprocess
1✔
8
from collections.abc import Callable, Iterable
1✔
9
from textwrap import dedent
1✔
10

11
import pytest
1✔
12

13
from pants.backend.go import target_type_rules
1✔
14
from pants.backend.go.goals import package_binary
1✔
15
from pants.backend.go.goals.package_binary import GoBinaryFieldSet
1✔
16
from pants.backend.go.target_types import GoBinaryTarget, GoModTarget, GoPackageTarget
1✔
17
from pants.backend.go.util_rules import (
1✔
18
    assembly,
19
    build_opts,
20
    build_pkg,
21
    build_pkg_target,
22
    first_party_pkg,
23
    go_mod,
24
    goroot,
25
    implicit_linker_deps,
26
    import_analysis,
27
    link,
28
    sdk,
29
    third_party_pkg,
30
)
31
from pants.backend.go.util_rules.build_opts import (
1✔
32
    GoBuildOptions,
33
    GoBuildOptionsFromTargetRequest,
34
    asan_supported,
35
    msan_supported,
36
    race_detector_supported,
37
)
38
from pants.backend.go.util_rules.build_pkg import BuildGoPackageRequest
1✔
39
from pants.backend.go.util_rules.build_pkg_target import BuildGoPackageTargetRequest
1✔
40
from pants.backend.go.util_rules.goroot import GoRoot
1✔
41
from pants.build_graph.address import Address
1✔
42
from pants.core.goals.package import BuiltPackage
1✔
43
from pants.engine.rules import QueryRule
1✔
44
from pants.engine.target import Target
1✔
45
from pants.testutil.rule_runner import RuleRunner
1✔
46

47

48
@pytest.fixture
1✔
49
def rule_runner() -> RuleRunner:
1✔
50
    rule_runner = RuleRunner(
1✔
51
        rules=[
52
            *build_opts.rules(),
53
            # for building binaries:
54
            *import_analysis.rules(),
55
            *package_binary.rules(),
56
            *assembly.rules(),
57
            *build_pkg.rules(),
58
            *build_pkg_target.rules(),
59
            *first_party_pkg.rules(),
60
            *go_mod.rules(),
61
            *goroot.rules(),
62
            *link.rules(),
63
            *implicit_linker_deps.rules(),
64
            *target_type_rules.rules(),
65
            *third_party_pkg.rules(),
66
            *sdk.rules(),
67
            QueryRule(GoBuildOptions, (GoBuildOptionsFromTargetRequest,)),
68
            QueryRule(BuiltPackage, (GoBinaryFieldSet,)),
69
            QueryRule(GoRoot, ()),
70
            QueryRule(BuildGoPackageRequest, [BuildGoPackageTargetRequest]),
71
        ],
72
        target_types=[
73
            GoModTarget,
74
            GoPackageTarget,
75
            GoBinaryTarget,
76
        ],
77
    )
78
    rule_runner.set_options([], env_inherit={"PATH"})
1✔
79
    return rule_runner
1✔
80

81

82
@pytest.mark.parametrize(
1✔
83
    "field_name,getter,enabled_for_platform",
84
    (
85
        ("race", lambda opts: opts.with_race_detector, race_detector_supported),
86
        ("msan", lambda opts: opts.with_msan, msan_supported),
87
        ("asan", lambda opts: opts.with_asan, asan_supported),
88
    ),
89
)
90
def test_runtime_check_enable_fields_work_as_expected(
1✔
91
    rule_runner: RuleRunner,
92
    field_name: str,
93
    getter: Callable[[GoBuildOptions], bool],
94
    enabled_for_platform: Callable[[GoRoot], bool],
95
) -> None:
96
    def module_files(dir_path: str, value: bool | None) -> dict:
1✔
97
        field = f", {field_name}={value}" if value is not None else ""
1✔
98
        return {
1✔
99
            f"{dir_path}/BUILD": dedent(
100
                f"""\
101
            go_mod(name="mod"{field})
102
            go_package(name="pkg")
103
            go_binary(name="bin_with_field_unspecified")
104
            go_binary(name="bin_with_field_false", {field_name}=False)
105
            go_binary(name="bin_with_field_true", {field_name}=True)
106
            """
107
            ),
108
            f"{dir_path}/go.mod": f"module test.pantsbuild.org/{dir_path}\n",
109
            f"{dir_path}/main.go": dedent(
110
                """\
111
            package main
112
            func main() {}
113
            """
114
            ),
115
            f"{dir_path}/pkg_false/BUILD": f"go_package(test_{field_name}=False)\n",
116
            f"{dir_path}/pkg_false/foo.go": "package pkg_false\n",
117
            f"{dir_path}/pkg_true/BUILD": f"go_package(test_{field_name}=True)\n",
118
            f"{dir_path}/pkg_true/foo.go": "package pkg_true\n",
119
        }
120

121
    files = {
1✔
122
        **module_files("mod_unspecified", None),
123
        **module_files("mod_false", False),
124
        **module_files("mod_true", True),
125
    }
126
    pprint.pprint(files)
1✔
127
    rule_runner.write_files(files)
1✔
128

129
    goroot = rule_runner.request(GoRoot, [])
1✔
130
    if not enabled_for_platform(goroot):
1✔
131
        pytest.skip(f"Skipping test because `{field_name}` is not supported on this platform.")
×
132

133
    def assert_value(
1✔
134
        address: Address, expected_value: bool, *, for_tests: bool = False, msg: str
135
    ) -> None:
136
        opts = rule_runner.request(
1✔
137
            GoBuildOptions,
138
            (GoBuildOptionsFromTargetRequest(address=address, for_tests=for_tests),),
139
        )
UNCOV
140
        assert getter(opts) is expected_value, f"{address}: expected {expected_value} {msg}"
×
141

142
    # go_mod does not specify a value for `race`
143
    assert_value(
1✔
144
        Address("mod_unspecified", target_name="bin_with_field_unspecified"),
145
        False,
146
        msg="when unspecified on go_binary and when unspecified on go_mod",
147
    )
UNCOV
148
    assert_value(
×
149
        Address("mod_unspecified", target_name="bin_with_field_false"),
150
        False,
151
        msg=f"when {field_name}=False on go_binary and when unspecified on go_mod",
152
    )
UNCOV
153
    assert_value(
×
154
        Address("mod_unspecified", target_name="bin_with_field_true"),
155
        True,
156
        msg=f"when {field_name}=True on go_binary and when unspecified on go_mod",
157
    )
UNCOV
158
    assert_value(
×
159
        Address("mod_unspecified", target_name="pkg"),
160
        False,
161
        for_tests=True,
162
        msg="for go_package when unspecified on go_mod",
163
    )
UNCOV
164
    assert_value(
×
165
        Address("mod_unspecified/pkg_false"),
166
        False,
167
        for_tests=True,
168
        msg=f"for go_package(test_{field_name}=False) when unspecified on go_mod",
169
    )
UNCOV
170
    assert_value(
×
171
        Address("mod_unspecified/pkg_true"),
172
        True,
173
        for_tests=True,
174
        msg=f"for go_package(test_{field_name}=True) when unspecified on go_mod",
175
    )
UNCOV
176
    assert_value(
×
177
        Address("mod_unspecified", target_name="mod"),
178
        False,
179
        msg="for go_mod when unspecified on go_mod",
180
    )
181

182
    # go_mod specifies False for `race`
UNCOV
183
    assert_value(
×
184
        Address("mod_false", target_name="bin_with_field_unspecified"),
185
        False,
186
        msg=f"when unspecified on go_binary and when {field_name}=False on go_mod",
187
    )
UNCOV
188
    assert_value(
×
189
        Address("mod_false", target_name="bin_with_field_false"),
190
        False,
191
        msg=f"when {field_name}=False on go_binary and when {field_name}=False on go_mod",
192
    )
UNCOV
193
    assert_value(
×
194
        Address("mod_false", target_name="bin_with_field_true"),
195
        True,
196
        msg=f"when {field_name}=True on go_binary and when {field_name}=False on go_mod",
197
    )
UNCOV
198
    assert_value(
×
199
        Address("mod_false", target_name="pkg"),
200
        False,
201
        for_tests=True,
202
        msg=f"for go_package when {field_name}=False on go_mod",
203
    )
UNCOV
204
    assert_value(
×
205
        Address("mod_false/pkg_false"),
206
        False,
207
        for_tests=True,
208
        msg=f"for go_package(test_{field_name}=False) when {field_name}=False on go_mod",
209
    )
UNCOV
210
    assert_value(
×
211
        Address("mod_false/pkg_true"),
212
        True,
213
        for_tests=True,
214
        msg=f"for go_package(test_{field_name}=True) when {field_name}=False on go_mod",
215
    )
UNCOV
216
    assert_value(
×
217
        Address("mod_false", target_name="mod"),
218
        False,
219
        msg=f"for go_mod when {field_name}=False on go_mod",
220
    )
221

222
    # go_mod specifies True for `race`
UNCOV
223
    assert_value(
×
224
        Address("mod_true", target_name="bin_with_field_unspecified"),
225
        True,
226
        msg=f"when unspecified on go_binary and when {field_name}=True on go_mod",
227
    )
UNCOV
228
    assert_value(
×
229
        Address("mod_true", target_name="bin_with_field_false"),
230
        False,
231
        msg=f"when {field_name}=False on go_binary and when {field_name}=True on go_mod",
232
    )
UNCOV
233
    assert_value(
×
234
        Address("mod_true", target_name="bin_with_field_true"),
235
        True,
236
        msg=f"when {field_name}=True on go_binary and when {field_name}=True on go_mod",
237
    )
UNCOV
238
    assert_value(
×
239
        Address("mod_true", target_name="pkg"),
240
        True,
241
        for_tests=True,
242
        msg=f"for go_package when {field_name}=True on go_mod",
243
    )
UNCOV
244
    assert_value(
×
245
        Address("mod_true/pkg_false"),
246
        False,
247
        for_tests=True,
248
        msg=f"for go_package(test_{field_name}=False) when {field_name}=True on go_mod",
249
    )
UNCOV
250
    assert_value(
×
251
        Address("mod_true/pkg_true"),
252
        True,
253
        for_tests=True,
254
        msg=f"for go_package(test_{field_name}=True) when {field_name}=True on go_mod",
255
    )
UNCOV
256
    assert_value(
×
257
        Address("mod_true", target_name="mod"),
258
        True,
259
        msg=f"for go_mod when {field_name}=True on go_mod",
260
    )
261

262
    # Test when `--go-test-force-{race,msan}` is in effect.
UNCOV
263
    rule_runner.set_options([f"--go-test-force-{field_name}"], env_inherit={"PATH"})
×
UNCOV
264
    assert_value(
×
265
        Address("mod_unspecified", target_name="pkg"),
266
        True,
267
        for_tests=True,
268
        msg=f"for go_package when --go-test-force-{field_name} and when unspecified on go_mod",
269
    )
UNCOV
270
    assert_value(
×
271
        Address("mod_false", target_name="pkg"),
272
        True,
273
        for_tests=True,
274
        msg=f"for go_package when --go-test-force-{field_name}and when {field_name}=False on go_mod",
275
    )
276

277

278
def build_package(rule_runner: RuleRunner, binary_target: Target) -> BuiltPackage:
1✔
279
    field_set = GoBinaryFieldSet.create(binary_target)
1✔
280
    result = rule_runner.request(BuiltPackage, [field_set])
1✔
UNCOV
281
    rule_runner.write_digest(result.digest)
×
UNCOV
282
    return result
×
283

284

285
def test_race_detector_actually_works(rule_runner: RuleRunner) -> None:
1✔
286
    rule_runner.write_files(
1✔
287
        {
288
            "BUILD": dedent(
289
                """\
290
            go_mod(name="mod")
291
            go_package()
292
            go_binary(name="bin", race=True)
293
            """
294
            ),
295
            "go.mod": "module example.pantsbuild.org/racy\n",
296
            "racy.go": dedent(
297
                """\
298
            // From example in https://go.dev/blog/race-detector
299
            package main
300

301
            import "fmt"
302

303
            func main() {
304
                done := make(chan bool)
305
                m := make(map[string]string)
306
                m["name"] = "world"
307
                go func() {
308
                    m["name"] = "data race"
309
                    done <- true
310
                }()
311
                fmt.Println("Hello,", m["name"])
312
                <-done
313
            }
314
            """
315
            ),
316
        }
317
    )
318

319
    binary_tgt = rule_runner.get_target(Address("", target_name="bin"))
1✔
320
    built_package = build_package(rule_runner, binary_tgt)
1✔
UNCOV
321
    assert len(built_package.artifacts) == 1
×
UNCOV
322
    assert built_package.artifacts[0].relpath == "bin"
×
323

UNCOV
324
    result = subprocess.run([os.path.join(rule_runner.build_root, "bin")], capture_output=True)
×
UNCOV
325
    assert result.returncode == 66  # standard exit code if race detector finds a race
×
UNCOV
326
    assert b"WARNING: DATA RACE" in result.stderr
×
327

328

329
def test_compiler_flags_fields(rule_runner: RuleRunner) -> None:
1✔
330
    rule_runner.write_files(
1✔
331
        {
332
            "mod_with_field/BUILD": dedent(
333
                """\
334
            go_mod(
335
              name="mod",
336
              compiler_flags=["-foo"],
337
            )
338

339
            go_package(name="pkg")
340

341
            go_binary(
342
              name="bin_without_field",
343
            )
344

345
            go_binary(
346
              name="bin_with_field",
347
              compiler_flags=["-bar"],
348
            )
349
            """
350
            ),
351
            "mod_with_field/go.mod": "module example.pantsbuild.org/mod_with_field\n",
352
            "mod_with_field/main.go": dedent(
353
                """\
354
            package main
355
            func main() {}
356
            """
357
            ),
358
            "mod_with_field/pkg_with_field/BUILD": dedent(
359
                """
360
                go_package(
361
                  compiler_flags=["-xyzzy"],
362
                )
363
                """
364
            ),
365
            "mod_with_field/pkg_with_field/foo.go": dedent(
366
                """\
367
            package pkg_with_field
368
            """
369
            ),
370
        }
371
    )
372

373
    def assert_flags(address: Address, expected_value: Iterable[str]) -> None:
1✔
374
        opts = rule_runner.request(
1✔
375
            GoBuildOptions,
376
            (
377
                GoBuildOptionsFromTargetRequest(
378
                    address=address,
379
                ),
380
            ),
381
        )
UNCOV
382
        assert opts.compiler_flags == tuple(expected_value), (
×
383
            f"{address}: expected `compiler_flags` to be {expected_value}"
384
        )
385

386
    assert_flags(Address("mod_with_field", target_name="mod"), ["-foo"])
1✔
UNCOV
387
    assert_flags(Address("mod_with_field", target_name="bin_without_field"), ["-foo"])
×
UNCOV
388
    assert_flags(Address("mod_with_field", target_name="bin_with_field"), ["-foo", "-bar"])
×
UNCOV
389
    assert_flags(Address("mod_with_field", target_name="pkg"), ["-foo"])
×
UNCOV
390
    assert_flags(Address("mod_with_field/pkg_with_field"), ["-foo"])
×
391

UNCOV
392
    build_request = rule_runner.request(
×
393
        BuildGoPackageRequest,
394
        [
395
            BuildGoPackageTargetRequest(
396
                Address("mod_with_field/pkg_with_field"), build_opts=GoBuildOptions()
397
            )
398
        ],
399
    )
UNCOV
400
    assert build_request.pkg_specific_compiler_flags == ("-xyzzy",)
×
401

402

403
def test_linker_flags_fields(rule_runner: RuleRunner) -> None:
1✔
404
    rule_runner.write_files(
1✔
405
        {
406
            "mod_with_field/BUILD": dedent(
407
                """\
408
            go_mod(
409
              name="mod",
410
              linker_flags=["-foo"],
411
            )
412

413
            go_package(name="pkg")
414

415
            go_binary(
416
              name="bin_without_field",
417
            )
418

419
            go_binary(
420
              name="bin_with_field",
421
              linker_flags=["-bar"],
422
            )
423
            """
424
            ),
425
            "mod_with_field/go.mod": "module example.pantsbuild.org/mod_with_field\n",
426
            "mod_with_field/main.go": dedent(
427
                """\
428
            package main
429
            func main() {}
430
            """
431
            ),
432
        }
433
    )
434

435
    def assert_flags(address: Address, expected_value: Iterable[str]) -> None:
1✔
436
        opts = rule_runner.request(
1✔
437
            GoBuildOptions,
438
            (
439
                GoBuildOptionsFromTargetRequest(
440
                    address=address,
441
                ),
442
            ),
443
        )
UNCOV
444
        assert opts.linker_flags == tuple(expected_value), (
×
445
            f"{address}: expected `linker_flags` to be {expected_value}"
446
        )
447

448
    assert_flags(Address("mod_with_field", target_name="mod"), ["-foo"])
1✔
UNCOV
449
    assert_flags(Address("mod_with_field", target_name="bin_without_field"), ["-foo"])
×
UNCOV
450
    assert_flags(Address("mod_with_field", target_name="bin_with_field"), ["-foo", "-bar"])
×
451

452

453
def test_assembler_flags_fields(rule_runner: RuleRunner) -> None:
1✔
454
    rule_runner.write_files(
1✔
455
        {
456
            "mod_with_field/BUILD": dedent(
457
                """\
458
            go_mod(
459
              name="mod",
460
              assembler_flags=["-foo"],
461
            )
462

463
            go_package(name="pkg")
464

465
            go_binary(
466
              name="bin_without_field",
467
            )
468

469
            go_binary(
470
              name="bin_with_field",
471
              assembler_flags=["-bar"],
472
            )
473
            """
474
            ),
475
            "mod_with_field/go.mod": "module example.pantsbuild.org/mod_with_field\n",
476
            "mod_with_field/main.go": dedent(
477
                """\
478
            package main
479
            func main() {}
480
            """
481
            ),
482
            "mod_with_field/pkg_with_field/BUILD": dedent(
483
                """
484
                go_package(
485
                  assembler_flags=["-xyzzy"],
486
                )
487
                """
488
            ),
489
            "mod_with_field/pkg_with_field/foo.go": dedent(
490
                """\
491
            package pkg_with_field
492
            """
493
            ),
494
        }
495
    )
496

497
    def assert_flags(address: Address, expected_value: Iterable[str]) -> None:
1✔
498
        opts = rule_runner.request(
1✔
499
            GoBuildOptions,
500
            (
501
                GoBuildOptionsFromTargetRequest(
502
                    address=address,
503
                ),
504
            ),
505
        )
UNCOV
506
        assert opts.assembler_flags == tuple(expected_value), (
×
507
            f"{address}: expected `assembler_flags` to be {expected_value}"
508
        )
509

510
    assert_flags(Address("mod_with_field", target_name="mod"), ["-foo"])
1✔
UNCOV
511
    assert_flags(Address("mod_with_field", target_name="bin_without_field"), ["-foo"])
×
UNCOV
512
    assert_flags(Address("mod_with_field", target_name="bin_with_field"), ["-foo", "-bar"])
×
UNCOV
513
    assert_flags(Address("mod_with_field", target_name="pkg"), ["-foo"])
×
UNCOV
514
    assert_flags(Address("mod_with_field/pkg_with_field"), ["-foo"])
×
515

UNCOV
516
    build_request = rule_runner.request(
×
517
        BuildGoPackageRequest,
518
        [
519
            BuildGoPackageTargetRequest(
520
                Address("mod_with_field/pkg_with_field"), build_opts=GoBuildOptions()
521
            )
522
        ],
523
    )
UNCOV
524
    assert build_request.pkg_specific_assembler_flags == ("-xyzzy",)
×
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