diff --git a/docker_compose_test/docker_compose_test.bzl b/docker_compose_test/docker_compose_test.bzl index 89fd688..d9bd2ef 100644 --- a/docker_compose_test/docker_compose_test.bzl +++ b/docker_compose_test/docker_compose_test.bzl @@ -17,6 +17,7 @@ load("@rules_pkg//:pkg.bzl", "pkg_tar") load("@repo_absolute_path//:build_root.bzl", "BUILD_WORKSPACE_DIRECTORY") load("@rules_go//go:def.bzl", "go_test") load("@rules_oci//oci:defs.bzl", "oci_image", "oci_load") +load(":multi_platform.bzl", "multi_platform") common_tags = [ "docker", # these tests depend on docker @@ -63,6 +64,7 @@ def go_docker_compose_test( data = [], tags = [], size = "large", + platforms = None, **kwargs, ): tags = common_tags + tags @@ -79,8 +81,12 @@ def go_docker_compose_test( tags = tags + go_test_target_tags, testonly = True, ) + if platforms: + multi_platform(name = name + ".go__test", actual = name + ".go_test", platforms = platforms, testonly = True) + else: + native.alias(name = name + ".go__test", actual = name + ".go_test", testonly = True) - compiled_tests_target = ":" + name + ".go_test" + compiled_tests_target = ":" + name + ".go__test" pkg_tar( name = name + ".compiled_go_test_target", diff --git a/docker_compose_test/multi_platform.bzl b/docker_compose_test/multi_platform.bzl new file mode 100644 index 0000000..f3d6976 --- /dev/null +++ b/docker_compose_test/multi_platform.bzl @@ -0,0 +1,36 @@ +"a rule transitioning an oci_image to multiple platforms" +# based (Apache-2.0) on rules_oci/examples/transition.bzl + + +def _multiplatform_transition(settings, attr): + """this function simply returns a string-list of the platforms as a transition.""" + return [ + {"//command_line_option:platforms": str(platform)} + for platform in attr.platforms + ] + +multiplatform_transition = transition( + # outputs a transition as a list of platforms as defined in the calling rule; these will cause + # the referencing rule to split its definition based in iterations of the selected platforms as + # thought given as a command-line argument + + implementation = _multiplatform_transition, + inputs = [], + outputs = ["//command_line_option:platforms"], +) + +def _impl(ctx): + """this function mostly acts as an alias() rule but splits across combinations of 'platforms'""" + return DefaultInfo(files = depset(ctx.files.actual)) + +multi_platform = rule( + doc = "causes the rule chain of dependencies to be split across values of 'platforms' and replacing the default value (based on the host)", + implementation = _impl, + attrs = { + "actual": attr.label(cfg = multiplatform_transition), + "platforms": attr.label_list(), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) diff --git a/examples/go-test-image-test-with-platforms/BUILD.bazel b/examples/go-test-image-test-with-platforms/BUILD.bazel new file mode 100644 index 0000000..f2059bc --- /dev/null +++ b/examples/go-test-image-test-with-platforms/BUILD.bazel @@ -0,0 +1,55 @@ +# Copyright (c) 2024, Salesforce, Inc. +# SPDX-License-Identifier: Apache-2 + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("@rules_docker_compose_test//docker_compose_test:docker_compose_test.bzl", "go_docker_compose_test") + +# As compared to examples/go-test-image-test, this example will succeed on non-linux hosts that run +# linux-archutecture containers (ie Mac "darwin") +# +# This example will compile linux unittests on a non-linux host, build a multi-arch OCI image,and +# use docker-compose to turn up the appropriate container to execute the corresponding architecture +# of compiled go testcase. +# +# We effectively overrule the default assumption that platform == host platform by providing two +# choices in a transition defined in multi_platform.bzl which causes the targets to duplicate +# across platform values and align corresponding platform values. +# +# We do this by: +# 1. providing a list of platforms to iterate +# 2. iterating that list in a transition around the `go_test()` target +# +# the same `cd examples && bazel test //go-test-image-test-with-platforms` demonstrates + +ARCH=["arm64", "x86_64"] + +[platform( + name = "linux_{}".format(a), + constraint_values = [ + "@platforms//os:linux", # yes, Mac docker runs linux images + "@platforms//cpu:{}".format(a), + ], +) for a in ARCH ] + +# The following go_docker_compose_test adds a "platforms" attribute, and pathname-based changes: + +go_docker_compose_test( + name = "go-test-image-test-with-platforms", + docker_compose_file = ":docker-compose.yml", + docker_compose_test_container = "test_container", # container name is subdir:test_container + platforms = [ "linux_{}".format(a) for a in ARCH ], # override default platform==host asusmption + test_srcs = [ "example_test.go", "another_test.go" ], + test_deps = [], + test_image_base = "@ubuntu", +) diff --git a/examples/go-test-image-test-with-platforms/another_test.go b/examples/go-test-image-test-with-platforms/another_test.go new file mode 100644 index 0000000..f72252b --- /dev/null +++ b/examples/go-test-image-test-with-platforms/another_test.go @@ -0,0 +1,8 @@ +package main + +import "testing" + +// identical to //examples/go-test-image-test/another_test.go +func TestExample2(t *testing.T) { + t.Log("bar") +} diff --git a/examples/go-test-image-test-with-platforms/docker-compose.yml b/examples/go-test-image-test-with-platforms/docker-compose.yml new file mode 100644 index 0000000..7c27365 --- /dev/null +++ b/examples/go-test-image-test-with-platforms/docker-compose.yml @@ -0,0 +1,22 @@ +# Copyright (c) 2024, Salesforce, Inc. +# SPDX-License-Identifier: Apache-2 + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +services: + # service name matches + test_container: + # image is : + image: go-test-image-test-with-platforms:test_container + # test binary is /tests/.go_test + entrypoint: ["tests/go-test-image-test-with-platforms.go_test"] diff --git a/examples/go-test-image-test-with-platforms/example_test.go b/examples/go-test-image-test-with-platforms/example_test.go new file mode 100644 index 0000000..71aa8a4 --- /dev/null +++ b/examples/go-test-image-test-with-platforms/example_test.go @@ -0,0 +1,8 @@ +package main + +import "testing" + +// identical to //examples/go-test-image-test/example_test.go +func TestExample(t *testing.T) { + t.Log("foo") +}