| """This module defines a custom go_test macro that produces separate targets for manual tests.""" |
| |
| load("@io_bazel_rules_go//go:def.bzl", _go_test = "go_test") |
| |
| def go_test(name, srcs, tags = [], args = [], **kwargs): |
| """Wrapper around go_test that splits manual and non-manual tests into separate targets. |
| |
| The purpose of this macro is to automatically create separate test targets for non-manual and |
| manual Go tests. The latter will be tagged as manual in order to exclude them from wildcard |
| queries such as "bazel test ...". It assumes that any manual test cases are placed in Go files |
| ending with "_manual_test.go". |
| |
| In addition, this macro customizes some go_test arguments with better defaults. |
| |
| This macro is not intended to be used directly. It is designed to be used with the |
| gazelle:map_kind directive, which customizes the kinds of rules generated by Gazelle. In |
| particular, it can be used to replace the default go_test rule (defined in the rules_go |
| repository) with this macro. See https://github.com/bazelbuild/bazel-gazelle#directives. |
| |
| Suppose this macro is invoked with name = "example_test", and that the srcs attribute contains a |
| combination of non-manual and manual test cases: |
| |
| ``` |
| # Macro invocation. |
| go_test( |
| name = "example_test", |
| srcs = [ |
| "foo_test.go", |
| "bar_test.go", |
| "baz_test.go", |
| "delta_manual_test.go", |
| "omega_manual_test.go", |
| ], |
| ... |
| ) |
| ``` |
| |
| The above macro invocation will result in two rules_go's go_test targets, one named |
| "example_test" containing the non-manual tests (*_test.go), and one named "example_manual_test" |
| containing both the non-manual and manual tests (*_test.go and *_manual_test.go): |
| |
| ``` |
| # Resulting rules_go's go_test targets: |
| |
| go_test( |
| name = "example_test", |
| srcs = [ |
| "foo_test.go", |
| "bar_test.go", |
| "baz_test.go", |
| ], |
| ... |
| ) |
| |
| go_test( |
| name = "example_manual_test", |
| srcs = [ |
| "foo_test.go", |
| "bar_test.go", |
| "baz_test.go", |
| "delta_manual_test.go", |
| "omega_manual_test.go", |
| ], |
| tags = ["manual"], # Exclude from Bazel wildcards, e.g. "bazel test ...". |
| ... |
| ) |
| ``` |
| |
| The reason why example_manual_test includes the non-manual tests as well is because they might |
| define auxiliary functions, test data, etc. shared between all tests, including the manual |
| ones. Thus, example_manual_test will run both the manual and non-manual tests when invoked with |
| "bazel test ...". |
| |
| If this macro is invoked without any files ending with "_manual_test.go", it behaves exactly |
| like the default go_test rule from the rules_go repository. |
| |
| Args: |
| name: Base name of the target(s) to generate. |
| srcs: Any *_test.go files. |
| tags: Any tags for the resulting go_test targets. |
| args: Any command-line arguments to pass to the test binaries of both go_test targets. |
| **kwargs: Any other arguments to pass to the resulting go_test targets. |
| """ |
| |
| # Gazelle only includes files ending with _test.go in the srcs attribute of go_test targets. |
| # In order to prevent bugs, we fail loudly if this ceases to be true for any reason. |
| for src in srcs: |
| if not src.endswith("_test.go"): |
| fail("go_test called with a src file that does not end with \"_test.go\".") |
| |
| # Make tests verbose by default. This improves error reporting in Infra-PerCommit-Test-Bazel-* |
| # for tests that time out, which by default fail silently without any indication of which test |
| # case caused the timeout. |
| # |
| # Note that Bazel omits the output of successful tests. This does not add noise to the logs. |
| args = args + ["--test.v"] # Equivalent to "go test [target] -v". |
| |
| non_manual_test_srcs = [src for src in srcs if not src.endswith("_manual_test.go")] |
| |
| if len(non_manual_test_srcs) > 0: |
| # Generate the base go_test target, excluding any *_manual_test.go files. |
| _go_test(name = name, srcs = non_manual_test_srcs, tags = tags, args = args, **kwargs) |
| |
| # Only generate the target for manual tests if there is at least one *_manual_test.go file. |
| if len(srcs) != len(non_manual_test_srcs): |
| _go_test( |
| name = name[:-4] + "manual_test", # Turn e.g. foo_test into foo_manual_test. |
| # Include *_manual_test.go and *_test.go sources as well, because the latter might |
| # contain functions, test data, etc. shared between the manual and non-manual tests. |
| srcs = srcs, |
| tags = tags + ["manual"], # Exclude from Bazel wildcards, e.g. "bazel test ...". |
| **kwargs |
| ) |