Skip to content

Commit 056e62f

Browse files
committed
WIP for cleaning up Go test container images
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
1 parent 3476209 commit 056e62f

25 files changed

Lines changed: 327 additions & 1095 deletions

bazel/go_container.bzl

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
# Copyright 2018- The Pixie Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
17+
"""
18+
Bazel rules and macros for generating Go container test libraries.
19+
20+
This module provides a custom rule and macros to generate C++ header files
21+
for Go container test fixtures at build time. This eliminates the need for
22+
manually maintaining per-version header files.
23+
24+
Usage:
25+
In BUILD.bazel:
26+
load("//bazel:go_container.bzl", "go_container_libraries")
27+
28+
go_container_libraries(
29+
use_case = "grpc_server",
30+
versions = ["1.23", "1.24"],
31+
legacy_versions = ["1.18", "1.19"],
32+
)
33+
"""
34+
35+
load("//bazel:pl_build_system.bzl", "pl_cc_test_library")
36+
37+
# Template for container header content
38+
_CONTAINER_HEADER_TEMPLATE = """\
39+
/*
40+
* Copyright 2018- The Pixie Authors.
41+
*
42+
* Licensed under the Apache License, Version 2.0 (the "License");
43+
* you may not use this file except in compliance with the License.
44+
* You may obtain a copy of the License at
45+
*
46+
* http://www.apache.org/licenses/LICENSE-2.0
47+
*
48+
* Unless required by applicable law or agreed to in writing, software
49+
* distributed under the License is distributed on an "AS IS" BASIS,
50+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51+
* See the License for the specific language governing permissions and
52+
* limitations under the License.
53+
*
54+
* SPDX-License-Identifier: Apache-2.0
55+
*/
56+
57+
#pragma once
58+
59+
#include <string>
60+
61+
#include "src/common/testing/test_environment.h"
62+
#include "src/common/testing/test_utils/container_runner.h"
63+
64+
namespace px {{
65+
namespace stirling {{
66+
namespace testing {{
67+
68+
class {class_name} : public ContainerRunner {{
69+
public:
70+
{class_name}()
71+
: ContainerRunner(::px::testing::BazelRunfilePath(kBazelImageTar), kContainerNamePrefix,
72+
kReadyMessage) {{}}
73+
74+
private:
75+
static constexpr std::string_view kBazelImageTar =
76+
"{tar_path}";
77+
static constexpr std::string_view kContainerNamePrefix = "{container_prefix}";
78+
static constexpr std::string_view kReadyMessage = {ready_message};
79+
}};
80+
81+
}} // namespace testing
82+
}} // namespace stirling
83+
}} // namespace px
84+
"""
85+
86+
# Configuration for each use case
87+
# Keys: use_case name
88+
# Values: dict with container_prefix, ready_message, tar patterns
89+
_GO_CONTAINER_CONFIGS = {
90+
"grpc_server": {
91+
"container_prefix": "grpc_server",
92+
"ready_message": '"Starting HTTP/2 server"',
93+
"tar_pattern_modern": "src/stirling/testing/demo_apps/go_grpc_tls_pl/server/golang_{version}_grpc_tls_server.tar",
94+
"tar_pattern_legacy": "src/stirling/source_connectors/socket_tracer/testing/containers/golang_{version}_grpc_server_with_buildinfo.tar",
95+
"class_suffix": "GRPCServerContainer",
96+
},
97+
"grpc_client": {
98+
"container_prefix": "grpc_client",
99+
"ready_message": '""',
100+
"tar_pattern_modern": "src/stirling/testing/demo_apps/go_grpc_tls_pl/client/golang_{version}_grpc_tls_client.tar",
101+
"tar_pattern_legacy": None,
102+
"class_suffix": "GRPCClientContainer",
103+
},
104+
"tls_server": {
105+
"container_prefix": "https_server",
106+
"ready_message": '"Starting HTTPS service"',
107+
"tar_pattern_modern": "src/stirling/testing/demo_apps/go_https/server/golang_{version}_https_server.tar",
108+
"tar_pattern_legacy": "src/stirling/source_connectors/socket_tracer/testing/containers/golang_{version}_https_server_with_buildinfo.tar",
109+
"class_suffix": "TLSServerContainer",
110+
},
111+
"tls_client": {
112+
"container_prefix": "https_client",
113+
"ready_message": 'R"({"status":"ok"})"',
114+
"tar_pattern_modern": "src/stirling/testing/demo_apps/go_https/client/golang_{version}_https_client.tar",
115+
"tar_pattern_legacy": None,
116+
"class_suffix": "TLSClientContainer",
117+
},
118+
}
119+
120+
def _version_to_class_prefix(version):
121+
"""Convert version string to class name prefix.
122+
123+
Args:
124+
version: Go SDK version string (e.g., "1.24", "1.23.11")
125+
126+
Returns:
127+
Class name prefix (e.g., "Go1_24_", "GoBoringCrypto")
128+
"""
129+
130+
# BoringCrypto versions (e.g., "1.23.11") get special naming
131+
if version.count(".") == 2:
132+
return "GoBoringCrypto"
133+
return "Go" + version.replace(".", "_") + "_"
134+
135+
def _version_to_label_suffix(version):
136+
"""Convert version string to bazel label suffix.
137+
138+
Args:
139+
version: Go SDK version string (e.g., "1.24", "1.23.11")
140+
141+
Returns:
142+
Label suffix (e.g., "1_24", "boringcrypto")
143+
"""
144+
145+
# BoringCrypto versions (e.g., "1.23.11") use "boringcrypto" in labels
146+
if version.count(".") == 2:
147+
return "boringcrypto"
148+
return version.replace(".", "_")
149+
150+
def _go_container_header_impl(ctx):
151+
"""Generate a Go container header file."""
152+
output = ctx.actions.declare_file(ctx.attr.header_name)
153+
154+
ctx.actions.write(
155+
output = output,
156+
content = _CONTAINER_HEADER_TEMPLATE.format(
157+
class_name = ctx.attr.class_name,
158+
tar_path = ctx.attr.tar_path,
159+
container_prefix = ctx.attr.container_prefix,
160+
ready_message = ctx.attr.ready_message,
161+
),
162+
)
163+
return [DefaultInfo(files = depset([output]))]
164+
165+
go_container_header = rule(
166+
implementation = _go_container_header_impl,
167+
attrs = {
168+
"class_name": attr.string(mandatory = True),
169+
"container_prefix": attr.string(mandatory = True),
170+
"header_name": attr.string(mandatory = True),
171+
"ready_message": attr.string(mandatory = True),
172+
"tar_path": attr.string(mandatory = True),
173+
},
174+
)
175+
176+
def go_container_library(name, use_case, version, is_legacy = False):
177+
"""
178+
Create a container library for a specific Go version and use case.
179+
180+
This macro generates a C++ header file and wraps it in a pl_cc_test_library
181+
that can be used as a dependency in tests.
182+
183+
Args:
184+
name: Target name for the library
185+
use_case: One of "grpc_server", "grpc_client", "tls_server", "tls_client"
186+
version: Go SDK version (e.g., "1.24", "1.23.11")
187+
is_legacy: Whether to use legacy tar path pattern (for older Go versions)
188+
"""
189+
config = _GO_CONTAINER_CONFIGS[use_case]
190+
label_suffix = _version_to_label_suffix(version)
191+
class_prefix = _version_to_class_prefix(version)
192+
193+
# Determine tar path pattern
194+
if is_legacy and config["tar_pattern_legacy"]:
195+
tar_pattern = config["tar_pattern_legacy"]
196+
else:
197+
tar_pattern = config["tar_pattern_modern"]
198+
199+
tar_path = tar_pattern.format(version = label_suffix)
200+
201+
# Class name: Go{version}_{UseCase}Container or GoBoringCrypto{UseCase}Container
202+
class_name = class_prefix + config["class_suffix"]
203+
204+
header_name = "go_{}_{}_container.h".format(label_suffix, use_case)
205+
206+
# Generate the header
207+
go_container_header(
208+
name = name + "_header",
209+
header_name = header_name,
210+
class_name = class_name,
211+
tar_path = tar_path,
212+
container_prefix = config["container_prefix"],
213+
ready_message = config["ready_message"],
214+
)
215+
216+
# Parse tar path to get the Bazel label
217+
# e.g., "src/stirling/testing/demo_apps/go_grpc_tls_pl/server/golang_1_24_grpc_tls_server.tar"
218+
# becomes "//src/stirling/testing/demo_apps/go_grpc_tls_pl/server:golang_1_24_grpc_tls_server.tar"
219+
tar_dir = tar_path.rsplit("/", 1)[0]
220+
tar_file = tar_path.rsplit("/", 1)[1]
221+
tar_label = "//" + tar_dir + ":" + tar_file
222+
223+
# Create the test library
224+
pl_cc_test_library(
225+
name = name,
226+
hdrs = [":" + name + "_header"],
227+
data = [tar_label],
228+
deps = ["//src/common/testing/test_utils:cc_library"],
229+
)
230+
231+
def go_container_libraries(use_case, versions, legacy_versions = []):
232+
"""
233+
Generate container libraries for all versions of a use case.
234+
235+
This is a convenience macro that generates multiple go_container_library
236+
targets in a single call.
237+
238+
Args:
239+
use_case: One of "grpc_server", "grpc_client", "tls_server", "tls_client"
240+
versions: List of Go SDK versions to generate libraries for
241+
legacy_versions: Subset of versions that should use legacy tar paths
242+
"""
243+
for version in versions:
244+
is_legacy = version in legacy_versions
245+
label_suffix = _version_to_label_suffix(version)
246+
target_name = "go_{}_{}_container".format(label_suffix, use_case)
247+
go_container_library(
248+
name = target_name,
249+
use_case = use_case,
250+
version = version,
251+
is_legacy = is_legacy,
252+
)
253+
254+
def go_container_deps(use_case, versions):
255+
"""
256+
Generate a list of container library deps for the given versions.
257+
258+
This is a helper function for use in BUILD files to generate dependency
259+
lists without manually listing each version.
260+
261+
Args:
262+
use_case: One of "grpc_server", "grpc_client", "tls_server", "tls_client"
263+
versions: List of Go SDK versions to include
264+
265+
Returns:
266+
List of Bazel labels for the container libraries
267+
"""
268+
deps = []
269+
for version in versions:
270+
label_suffix = _version_to_label_suffix(version)
271+
target_name = "go_{}_{}_container".format(label_suffix, use_case)
272+
deps.append("//src/stirling/source_connectors/socket_tracer/testing/container_images:" + target_name)
273+
return deps
274+
275+
def all_go_grpc_container_deps(versions):
276+
"""
277+
Generate deps for all gRPC server and client containers.
278+
279+
Args:
280+
versions: List of Go SDK versions to include
281+
282+
Returns:
283+
List of Bazel labels for all gRPC container libraries
284+
"""
285+
return go_container_deps("grpc_server", versions) + go_container_deps("grpc_client", versions)
286+
287+
def all_go_tls_container_deps(versions):
288+
"""
289+
Generate deps for all TLS server and client containers.
290+
291+
Args:
292+
versions: List of Go SDK versions to include
293+
294+
Returns:
295+
List of Bazel labels for all TLS container libraries
296+
"""
297+
return go_container_deps("tls_server", versions) + go_container_deps("tls_client", versions)

bazel/pl_build_system.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pl_go_test_versions = ["1.18", "1.19", "1.20", "1.21", "1.22"]
2828
pl_supported_go_sdk_versions = ["1.23", "1.24"]
2929

3030
# The last version in this list corresponds to the boringcrypto go sdk version.
31+
# This list is used for generating container libraries and other version-specific targets.
3132
pl_all_supported_go_sdk_versions = pl_supported_go_sdk_versions + pl_boringcrypto_go_sdk
3233

3334
def pl_go_sdk_version_template_to_label(tpl, version):

0 commit comments

Comments
 (0)