diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b85ea4d1..440262bc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,32 +21,32 @@ env: OPAL_RPC_CREDENTIALS: ${{ secrets.OPAL_RPC_CREDENTIALS }} jobs: - test-matrix: + macos-test-matrix: runs-on: - self-hosted - - "os=${{ matrix.os }}" - - "arch=${{ matrix.arch }}" - - "os_distribution=${{ matrix.os_distribution }}" - - "os_version=${{ matrix.os_version }}" - - "revision=${{ matrix.revision }}" + - "os=macos" + - "arch=arm64" + - "os_distribution=sonoma" + - "os_version=14" + - "revision=4edc10aa8f8ca239699aaf1078832208fb3b7efe" timeout-minutes: 10 strategy: fail-fast: false matrix: - include: - - os: macos - arch: arm64 - os_distribution: sonoma - os_version: "14" - revision: 4edc10aa8f8ca239699aaf1078832208fb3b7efe - remote_execution: 'false' - - - os: macos - arch: arm64 - os_distribution: sonoma - os_version: "14" - revision: 4edc10aa8f8ca239699aaf1078832208fb3b7efe - remote_execution: 'true' + test_package: + - cpp + - csharp + - docker + - genrules + - go + #- ios # TODO: fix ios builds + - java + - kotlin + - perl + - scala + - swift + - typescript + execution_type: [remote, local] steps: - uses: "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" @@ -61,36 +61,81 @@ jobs: - name: Build and test env: - ARCH: ${{ matrix.arch }} - OS: ${{ matrix.os }} - REMOTE_EXECUTION: ${{ matrix.remote_execution }} - run: python3 infra/test-all.py + ARCH: arm64 + OS: macos + EXECUTION_TYPE: ${{ matrix.execution_type }} + run: python3 infra/test-all.py --package=${{ matrix.test_package }} - ci-runners-test-matrix: + linux-test-matrix: runs-on: - self-hosted - "os=linux" - "arch=x64" - - "remote_execution=${{ matrix.remote_execution }}" - "engflow-bento-name=example-gh-x64" - "engflow-cluster=glass" - - "engflow-job-name=ci-runners-test-matrix-${{matrix.remote_execution}}_${{matrix.allow_bento_snapshot}}" + - "engflow-job-name=linux-test-matrix-${{matrix.execution_type}}" + - "engflow-job-type=${{github.event_name}}-${{github.ref_name}}" + - "engflow-run-id=${{ github.run_id }}" + - "engflow-bento-allow-save=false" + + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + test_package: + - cpp + - csharp + - docker + - genrules + - go + #- ios # TODO: fix ios builds + - java + - kotlin + - perl + - scala + - swift + - typescript + execution_type: [remote, local] + + steps: + - uses: "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" + + - name: Set up authentication + shell: bash + run: cp infra/bazelrc .bazelrc.user + + - name: Generate python requirements lock + shell: bash + run: bazel run //python:requirements.update + + - name: Build and test + env: + ARCH: x64 + OS: linux + EXECUTION_TYPE: ${{ matrix.execution_type }} + run: python3 infra/test-all.py --package=${{ matrix.test_package }} + + bento-snapshot: + runs-on: + - self-hosted + - "os=linux" + - "arch=x64" + - "remote_execution=true" + - "engflow-bento-name=example-gh-x64" + - "engflow-cluster=glass" + - "engflow-job-name=bento-snapshot" - "engflow-job-type=${{github.event_name}}-${{github.ref_name}}" - "engflow-run-id=${{ github.run_id }}" # To avoid a race condition, among all the jobs that use the same Bento in the same repo, only # one should specify "engflow-bento-allow-save=true". - - "engflow-bento-allow-save=${{ matrix.allow_bento_snapshot }}" + - "engflow-bento-allow-save=true" timeout-minutes: 10 strategy: fail-fast: false matrix: - include: - - remote_execution: 'false' - allow_bento_snapshot: 'false' - - - remote_execution: 'true' - allow_bento_snapshot: 'true' + test_package: [cpp] + execution_type: [remote] steps: - uses: "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" @@ -107,8 +152,8 @@ jobs: env: ARCH: x64 OS: linux - REMOTE_EXECUTION: ${{ matrix.remote_execution }} - run: python3 infra/test-all.py + EXECUTION_TYPE: ${{ matrix.execution_type }} + run: python3 infra/test-all.py --package=${{ matrix.test_package }} buck2-test: runs-on: diff --git a/cpp/BUILD b/cpp/BUILD index eab1ab18..d392faa4 100644 --- a/cpp/BUILD +++ b/cpp/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_cc//cc:cc_test.bzl", "cc_test") @@ -16,6 +17,13 @@ cc_library( ], ) +build_test( + name = "cpp_build_test", + targets = [ + ":cpp", + ], +) + cc_test( name = "cpp_test", size = "small", diff --git a/csharp/BUILD b/csharp/BUILD index 668f17bd..94036417 100644 --- a/csharp/BUILD +++ b/csharp/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_dotnet//dotnet:defs.bzl", "csharp_binary") csharp_binary( @@ -9,3 +10,10 @@ csharp_binary( "net8.0", ], ) + +build_test( + name = "csharp_test", + targets = [ + ":csharp.exe", + ], +) diff --git a/docker/BUILD b/docker/BUILD new file mode 100644 index 00000000..e69de29b diff --git a/docker/network/BUILD b/docker/network/BUILD index 520957a0..f9e67ff9 100644 --- a/docker/network/BUILD +++ b/docker/network/BUILD @@ -22,7 +22,10 @@ DOCKER_JDK_PSQL = "docker://gcr.io/YOUR-IMAGE-NAME@sha256:b6ed8f68abd6e23409ee7a java_test( name = "docker-network-test", srcs = ["DockerNetworkTest.java"], - tags = ["manual"], + tags = [ + "manual", + "no-ci", # Consistent NPE + ], test_class = "docker.network.DockerNetworkTest", ) diff --git a/docker/sandbox/BUILD b/docker/sandbox/BUILD index 167df89f..fc3f7afe 100644 --- a/docker/sandbox/BUILD +++ b/docker/sandbox/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_java//java:java_binary.bzl", "java_binary") @@ -25,3 +26,11 @@ cc_binary( name = "hello-cc", srcs = ["hello.cc"], ) + +build_test( + name = "hello_test", + tags = ["no-macos-ci"], + targets = [ + ":hello", + ], +) diff --git a/docker/sysbox/dind_test/BUILD b/docker/sysbox/dind_test/BUILD index 58b2b1d2..c05874c9 100644 --- a/docker/sysbox/dind_test/BUILD +++ b/docker/sysbox/dind_test/BUILD @@ -30,5 +30,9 @@ sh_test( # DO NOT ENABLE!!! "dockerPrivileged": "True", # sysbox containers will refuse to start }, - tags = ["manual"], + tags = [ + "manual", + "no-local-ci", + "no-macos-ci", + ], ) diff --git a/genrules/BUILD b/genrules/BUILD index 1a462fa4..c5ca8dd3 100644 --- a/genrules/BUILD +++ b/genrules/BUILD @@ -16,6 +16,8 @@ # on the user's input. # This can be used for stress testing your build infrastructure. # Change the upper bound of the range and enjoy! +load("@bazel_skylib//rules:build_test.bzl", "build_test") + UPPER_BOUND = 10 [genrule( @@ -55,3 +57,11 @@ UPPER_BOUND = 10 tags = ["manual"], tools = ["@ubuntu_20.04_1.3GB//file"], ) for x in range(1, 2)] + +# Only test a few to ensure they build, without creating undue load. +build_test( + name = "foo_TXT_test", + targets = [ + ":foo_TXT_4KB_1", + ], +) diff --git a/go/BUILD b/go/BUILD index e87cfd8b..19bbd0f9 100644 --- a/go/BUILD +++ b/go/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_go//go:def.bzl", "go_binary", "go_library") go_binary( @@ -12,3 +13,10 @@ go_library( importpath = "github.com/EngFlow/example/go", visibility = ["//visibility:private"], ) + +build_test( + name = "go_build_test", + targets = [ + ":go", + ], +) diff --git a/infra/test-all.py b/infra/test-all.py old mode 100644 new mode 100755 index 7a62415c..8b9e4f17 --- a/infra/test-all.py +++ b/infra/test-all.py @@ -1,25 +1,57 @@ #!/usr/bin/env python3 +import argparse import os import subprocess import sys -def main(): - # All targets that can run in any environment, except ios examples. - targets = [ - "//...", - # TODO: Add testing configuration for ios tests. - "-//ios/...", - ] - - for key in ("ARCH", "OPAL_RPC_CREDENTIALS", "OS", "REMOTE_EXECUTION"): +EXTRA_FLAGS = { + "ios": ["--config=ios"], + "swift": ["--config=clang"], +} + + +def report_error(msg): + print(msg, file=sys.stderr) + sys.exit(1) + + +def validate_env(): + for key in ("ARCH", "OS", "EXECUTION_TYPE", "OPAL_RPC_CREDENTIALS"): if not os.getenv(key): - sys.stderr.write(f"{key} not set\n") - sys.exit(1) + report_error(f"{key} not set") + + +def find_tests(package): + os_name = os.getenv("OS") + remote = os.getenv("EXECUTION_TYPE") + + # Remove tests based on tags and environment + query = f""" + let t = tests(//{package}/...) in + $t + - attr(tags, no-ci, $t) + - attr(tags, no-{os_name}-ci, $t) + - attr(tags, no-{remote}-ci, $t) + """.strip() + + print(f"Executing query to find test targets:\n{query}") + args = ["bazel", "query", "--output=label", "--", query] + result = subprocess.run(args, capture_output=True) + output = result.stdout.decode() + return [t for t in output.split("\n") if t] + + +def run_tests(package): + targets = find_tests(package) + if not targets: + print(f"No targets found for {package}, skipping.") + return 0 + print(f"Executing tests {targets}") os_arch = os.getenv("OS") + "_" + os.getenv("ARCH") flags = ["--config=ci"] - if os.getenv("REMOTE_EXECUTION") == "true": + if os.getenv("EXECUTION_TYPE") == "remote": flags += [ "--config=remote_" + os_arch, "--config=opal", @@ -29,13 +61,44 @@ def main(): "--config=opal_bes", "--config=opal_auth", ] - # The //docker/sysbox/... targets should only run in linux + remote - if os.getenv("REMOTE_EXECUTION") == "true" and os.getenv("OS") == "linux": - targets += ["//docker/sysbox/dind_test:check_docker",] + + if package in EXTRA_FLAGS: + flags += EXTRA_FLAGS[package] + + print(f"---------------\nTesting {package}...") + sys.stdout.flush() + args = ["bazel", "test"] + flags + ["--"] + targets + result = subprocess.run(args, check=False) + sys.stdout.flush() + sys.stderr.flush() + return result.returncode + + +def main(): + parser = argparse.ArgumentParser( + description="Runs example test suites", fromfile_prefix_chars="@" + ) + parser.add_argument( + "--package", + required=False, + help="Package to test.", + ) + parser.add_argument( + "--validate-env", + action=argparse.BooleanOptionalAction, + help="Whether to validate environment variables", + ) + opts = parser.parse_args() + + if opts.validate_env: + validate_env() + + package = opts.package - result = subprocess.run(args) - sys.exit(result.returncode) + returncode = run_tests(opts.package) + if returncode != 0: + sys.exit(returncode) if __name__ == "__main__": diff --git a/ios/BUILD.bazel b/ios/BUILD similarity index 81% rename from ios/BUILD.bazel rename to ios/BUILD index ab1fdf9b..87e22895 100644 --- a/ios/BUILD.bazel +++ b/ios/BUILD @@ -1,10 +1,10 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_apple//apple:ios.bzl", "ios_application", "ios_ui_test", "ios_unit_test") load("@rules_swift//swift:swift.bzl", "swift_library") swift_library( name = "HelloAppLibrary", srcs = ["HelloApp.swift"], - tags = ["manual"], ) ios_application( @@ -18,11 +18,17 @@ ios_application( deps = [":HelloAppLibrary"], ) +build_test( + name = "HelloApp_build_test", + targets = [ + ":HelloApp", + ], +) + swift_library( name = "HelloTestLib", testonly = True, srcs = ["HelloTest.swift"], - tags = ["manual"], ) ios_unit_test( @@ -38,13 +44,15 @@ swift_library( "HelloAppUITest.swift", ], module_name = "HelloAppUITest", - tags = ["manual"], ) ios_ui_test( name = "HelloAppUITest", minimum_os_version = "26.0", runner = "@rules_apple//apple/testing/default_runner:ios_xctestrun_ordered_runner", + tags = [ + "no-remote-ci", # Investigating permissions error. + ], test_host = ":HelloApp", deps = [":HelloAppUITestLib"], ) diff --git a/java/BUILD b/java/BUILD new file mode 100644 index 00000000..e69de29b diff --git a/java/com/engflow/binaryinput/BUILD b/java/com/engflow/binaryinput/BUILD index 44a15c24..4402ecd2 100644 --- a/java/com/engflow/binaryinput/BUILD +++ b/java/com/engflow/binaryinput/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_java//java:defs.bzl", "java_binary", "java_library") NUM_FILES = 100 @@ -43,3 +44,10 @@ java_binary( ) ], ) + +build_test( + name = "main_test", + targets = [ + ":main", + ], +) diff --git a/java/com/engflow/notificationqueue/BUILD b/java/com/engflow/notificationqueue/BUILD index e9b5586f..b117334b 100644 --- a/java/com/engflow/notificationqueue/BUILD +++ b/java/com/engflow/notificationqueue/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@grpc-java//:java_grpc_library.bzl", "java_grpc_library") load("@rules_java//java:java_binary.bzl", "java_binary") @@ -28,3 +29,10 @@ java_binary( "@protobuf//java/core", ], ) + +build_test( + name = "client_test", + targets = [ + ":client", + ], +) diff --git a/java/com/engflow/notificationqueue/demoserver/BUILD b/java/com/engflow/notificationqueue/demoserver/BUILD index 3d51a2ef..9cca5105 100644 --- a/java/com/engflow/notificationqueue/demoserver/BUILD +++ b/java/com/engflow/notificationqueue/demoserver/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@grpc-java//:java_grpc_library.bzl", "java_grpc_library") load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library") load("@protobuf//bazel:proto_library.bzl", "proto_library") @@ -40,3 +41,10 @@ java_binary( "@grpc-java//stub", ], ) + +build_test( + name = "server_test", + targets = [ + ":server", + ], +) diff --git a/kotlin/BUILD b/kotlin/BUILD index 05163505..330bb776 100644 --- a/kotlin/BUILD +++ b/kotlin/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_binary") kt_jvm_binary( @@ -5,3 +6,10 @@ kt_jvm_binary( srcs = ["Main.kt"], main_class = "example.MainKt", ) + +build_test( + name = "kotlin_test", + targets = [ + ":kotlin", + ], +) diff --git a/perl/BUILD b/perl/BUILD index 18e7c3b9..8c0f6c76 100644 --- a/perl/BUILD +++ b/perl/BUILD @@ -1,6 +1,14 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_perl//perl:perl.bzl", "perl_binary") perl_binary( name = "perl", srcs = ["hello_world.pl"], ) + +build_test( + name = "perl_test", + targets = [ + ":perl", + ], +) diff --git a/python/BUILD b/python/BUILD index 2903d1b3..8db53f9c 100644 --- a/python/BUILD +++ b/python/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test") load("@rules_python//python:pip.bzl", "compile_pip_requirements") load("//python/pytest:pytest.bzl", "pytest_test") @@ -57,3 +58,10 @@ compile_pip_requirements( requirements_txt = "requirements_lock.txt", tags = ["manual"], ) + +build_test( + name = "python_test", + targets = [ + ":python", + ], +) diff --git a/swift/BUILD b/swift/BUILD index c5d89e1c..f728cc33 100644 --- a/swift/BUILD +++ b/swift/BUILD @@ -1,11 +1,14 @@ load("@rules_swift//swift:swift.bzl", "swift_test") swift_test( - name = "tests", + name = "swift_test", size = "small", srcs = [ "example.swift", "main.swift", ], - tags = ["manual"], + tags = [ + "manual", + "no-ci", # Broken toolchain setup + ], )