• 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

83.93
/src/python/pants/backend/codegen/protobuf/go/rules_integration_test.py
1
# Copyright 2021 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
from collections.abc import Iterable
1✔
6
from textwrap import dedent
1✔
7

8
import pytest
1✔
9

10
from pants.backend.codegen.protobuf import protobuf_dependency_inference, target_types
1✔
11
from pants.backend.codegen.protobuf.go.rules import (
1✔
12
    GenerateGoFromProtobufRequest,
13
    parse_go_package_option,
14
)
15
from pants.backend.codegen.protobuf.go.rules import rules as go_protobuf_rules
1✔
16
from pants.backend.codegen.protobuf.target_types import (
1✔
17
    ProtobufSourceField,
18
    ProtobufSourcesGeneratorTarget,
19
    ProtobufSourceTarget,
20
)
21
from pants.backend.codegen.protobuf.target_types import rules as protobuf_target_types_rules
1✔
22
from pants.backend.go import target_type_rules
1✔
23
from pants.backend.go.goals import test
1✔
24
from pants.backend.go.goals.test import GoTestFieldSet, GoTestRequest
1✔
25
from pants.backend.go.target_types import GoModTarget, GoPackageTarget
1✔
26
from pants.backend.go.util_rules import (
1✔
27
    assembly,
28
    build_pkg,
29
    build_pkg_target,
30
    first_party_pkg,
31
    go_mod,
32
    implicit_linker_deps,
33
    link,
34
    sdk,
35
    tests_analysis,
36
    third_party_pkg,
37
)
38
from pants.build_graph.address import Address
1✔
39
from pants.core.goals.test import TestResult, get_filtered_environment
1✔
40
from pants.core.util_rules import config_files, source_files, stripped_source_files
1✔
41
from pants.core.util_rules.external_tool import rules as external_tool_rules
1✔
42
from pants.engine.fs import Digest, DigestContents
1✔
43
from pants.engine.rules import QueryRule
1✔
44
from pants.engine.target import GeneratedSources, HydratedSources, HydrateSourcesRequest
1✔
45
from pants.testutil.rule_runner import PYTHON_BOOTSTRAP_ENV, RuleRunner
1✔
46
from pants.testutil.skip_utils import requires_go
1✔
47

48

49
@pytest.fixture
1✔
50
def rule_runner() -> RuleRunner:
1✔
51
    rule_runner = RuleRunner(
1✔
52
        rules=[
53
            *config_files.rules(),
54
            *external_tool_rules(),
55
            *source_files.rules(),
56
            *protobuf_target_types_rules(),
57
            *protobuf_dependency_inference.rules(),
58
            *stripped_source_files.rules(),
59
            *go_protobuf_rules(),
60
            *sdk.rules(),
61
            *target_types.rules(),
62
            # Rules needed to run Go unit test.
63
            *test.rules(),
64
            *assembly.rules(),
65
            *build_pkg.rules(),
66
            *build_pkg_target.rules(),
67
            *first_party_pkg.rules(),
68
            *go_mod.rules(),
69
            *link.rules(),
70
            *implicit_linker_deps.rules(),
71
            *sdk.rules(),
72
            *target_type_rules.rules(),
73
            *tests_analysis.rules(),
74
            *third_party_pkg.rules(),
75
            get_filtered_environment,
76
            QueryRule(HydratedSources, [HydrateSourcesRequest]),
77
            QueryRule(GeneratedSources, [GenerateGoFromProtobufRequest]),
78
            QueryRule(DigestContents, (Digest,)),
79
            QueryRule(TestResult, (GoTestRequest.Batch,)),
80
        ],
81
        target_types=[
82
            GoModTarget,
83
            GoPackageTarget,
84
            ProtobufSourceTarget,
85
            ProtobufSourcesGeneratorTarget,
86
        ],
87
    )
88
    rule_runner.set_options(
1✔
89
        [],
90
        env_inherit=PYTHON_BOOTSTRAP_ENV,
91
    )
92
    return rule_runner
1✔
93

94

95
def assert_files_generated(
1✔
96
    rule_runner: RuleRunner,
97
    address: Address,
98
    *,
99
    expected_files: list[str],
100
    source_roots: list[str],
101
    extra_args: Iterable[str] = (),
102
) -> None:
103
    args = [f"--source-root-patterns={repr(source_roots)}", *extra_args]
1✔
104
    rule_runner.set_options(args, env_inherit=PYTHON_BOOTSTRAP_ENV)
1✔
105
    tgt = rule_runner.get_target(address)
1✔
106
    protocol_sources = rule_runner.request(
1✔
107
        HydratedSources, [HydrateSourcesRequest(tgt[ProtobufSourceField])]
108
    )
109
    generated_sources = rule_runner.request(
1✔
110
        GeneratedSources, [GenerateGoFromProtobufRequest(protocol_sources.snapshot, tgt)]
111
    )
UNCOV
112
    assert set(generated_sources.snapshot.files) == set(expected_files)
×
113

114

115
def test_extracts_go_package() -> None:
1✔
116
    import_path = parse_go_package_option(b"""option go_package = "example.com/dir1";""")
1✔
117
    assert import_path == "example.com/dir1"
1✔
118

119

120
@requires_go
1✔
121
def test_generates_go(rule_runner: RuleRunner) -> None:
1✔
122
    # This tests a few things:
123
    #  * We generate the correct file names.
124
    #  * Protobuf files can import other protobuf files, and those can import others
125
    #    (transitive dependencies). We'll only generate the requested target, though.
126
    #  * We can handle multiple source roots, which need to be preserved in the final output.
127
    rule_runner.write_files(
1✔
128
        {
129
            "src/protobuf/dir1/f.proto": dedent(
130
                """\
131
                syntax = "proto3";
132

133
                option go_package = "example.com/dir1";
134

135
                package dir1;
136

137
                message Person {
138
                  string name = 1;
139
                  int32 id = 2;
140
                  string email = 3;
141
                }
142
                """
143
            ),
144
            "src/protobuf/dir1/f2.proto": dedent(
145
                """\
146
                syntax = "proto3";
147

148
                option go_package = "example.com/dir1";
149

150
                package dir1;
151

152
                message Place {
153
                  string town = 1;
154
                  string country = 2;
155
                }
156
                """
157
            ),
158
            "src/protobuf/dir1/BUILD": dedent(
159
                """\
160
                protobuf_sources()
161
                """
162
            ),
163
            "src/protobuf/dir2/f.proto": dedent(
164
                """\
165
                syntax = "proto3";
166

167
                option go_package = "example.com/dir2";
168

169
                package dir2;
170

171
                import "dir1/f.proto";
172

173
                message Employee {
174
                  dir1.Person self = 1;
175
                  dir1.Person manager = 2;
176
                }
177
                """
178
            ),
179
            "src/protobuf/dir2/BUILD": "protobuf_sources()",
180
            # Test another source root.
181
            "tests/protobuf/test_protos/f.proto": dedent(
182
                """\
183
                syntax = "proto3";
184

185
                option go_package = "example.com/test_protos";
186

187
                package test_protos;
188

189
                import "dir2/f.proto";
190
                """
191
            ),
192
            "tests/protobuf/test_protos/BUILD": ("protobuf_sources()"),
193
            "src/go/people/BUILD": dedent(
194
                """\
195
                go_mod(name="mod")
196
                go_package(name="pkg")
197
                """
198
            ),
199
            "src/go/people/go.mod": dedent(
200
                """\
201
                module example.com/people
202
                require google.golang.org/protobuf v1.27.1
203
                """
204
            ),
205
            "src/go/people/go.sum": dedent(
206
                """\
207
                github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
208
                github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
209
                github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
210
                github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
211
                golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
212
                golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
213
                google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
214
                google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
215
                google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
216
                """
217
            ),
218
            "src/go/people/proto_test.go": dedent(
219
                """\
220
                package people
221
                import (
222
                  "testing"
223
                  pb_dir1 "example.com/dir1"
224
                  pb_dir2 "example.com/dir2"
225
                )
226
                func TestProtoGen(t *testing.T) {
227
                  person := pb_dir1.Person{
228
                    Name: "name",
229
                    Id: 1,
230
                    Email: "name@example.com",
231
                  }
232
                  if person.Name != "name" {
233
                    t.Fail()
234
                  }
235
                  place := pb_dir1.Place{
236
                    Town: "Any Town",
237
                    Country: "Some Country",
238
                  }
239
                  if place.Town != "Any Town" {
240
                    t.Fail()
241
                  }
242
                  employee := pb_dir2.Employee{
243
                    Self: &pb_dir1.Person{
244
                      Name: "self",
245
                      Id: 1,
246
                      Email: "self@example.com",
247
                    },
248
                    Manager: &pb_dir1.Person{
249
                      Name: "manager",
250
                      Id: 2,
251
                      Email: "manager@example.com",
252
                    },
253
                  }
254
                  if employee.Self.Name != "self" {
255
                    t.Fail()
256
                  }
257
                }
258
                """
259
            ),
260
        }
261
    )
262

263
    def assert_gen(addr: Address, expected: Iterable[str]) -> None:
1✔
264
        assert_files_generated(
1✔
265
            rule_runner,
266
            addr,
267
            source_roots=["src/python", "/src/protobuf", "/tests/protobuf"],
268
            expected_files=list(expected),
269
        )
270

271
    assert_gen(
1✔
272
        Address("src/protobuf/dir1", relative_file_path="f.proto"),
273
        ("src/protobuf/dir1/f.pb.go",),
274
    )
UNCOV
275
    assert_gen(
×
276
        Address("src/protobuf/dir1", relative_file_path="f2.proto"),
277
        ("src/protobuf/dir1/f2.pb.go",),
278
    )
UNCOV
279
    assert_gen(
×
280
        Address("src/protobuf/dir2", relative_file_path="f.proto"),
281
        ("src/protobuf/dir2/f.pb.go",),
282
    )
UNCOV
283
    assert_gen(
×
284
        Address("tests/protobuf/test_protos", relative_file_path="f.proto"),
285
        ("tests/protobuf/test_protos/f.pb.go",),
286
    )
287

UNCOV
288
    rule_runner.set_options(
×
289
        ["--go-test-args=-v"],
290
        env_inherit=PYTHON_BOOTSTRAP_ENV,
291
    )
UNCOV
292
    tgt = rule_runner.get_target(Address("src/go/people", target_name="pkg"))
×
UNCOV
293
    result = rule_runner.request(
×
294
        TestResult, [GoTestRequest.Batch("", (GoTestFieldSet.create(tgt),), None)]
295
    )
UNCOV
296
    assert result.exit_code == 0
×
UNCOV
297
    assert b"PASS: TestProtoGen" in result.stdout_bytes
×
298

299

300
@requires_go
1✔
301
def test_generates_go_grpc(rule_runner: RuleRunner) -> None:
1✔
302
    rule_runner.write_files(
1✔
303
        {
304
            "protos/BUILD": "protobuf_sources(grpc=True)",
305
            "protos/service.proto": dedent(
306
                """\
307
            syntax = "proto3";
308

309
            option go_package = "example.com/protos";
310

311
            package service;
312

313
            message TestMessage {
314
              string foo = 1;
315
            }
316

317
            service TestService {
318
              rpc noStreaming (TestMessage) returns (TestMessage);
319
              rpc clientStreaming (stream TestMessage) returns (TestMessage);
320
              rpc serverStreaming (TestMessage) returns (stream TestMessage);
321
              rpc bothStreaming (stream TestMessage) returns (stream TestMessage);
322
            }
323
            """
324
            ),
325
        }
326
    )
327
    assert_files_generated(
1✔
328
        rule_runner,
329
        Address("protos", relative_file_path="service.proto"),
330
        source_roots=["/"],
331
        expected_files=[
332
            "protos/service.pb.go",
333
            "protos/service_grpc.pb.go",
334
        ],
335
    )
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