1+ "Define a rule for running bazel test under Bazel"
2+
3+ load ("//:version.bzl" , "SUPPORTED_BAZEL_VERSIONS" )
4+ load ("//python:defs.bzl" , "py_test" )
5+
6+ BAZEL_BINARY = "@build_bazel_bazel_%s//:bazel_binary" % SUPPORTED_BAZEL_VERSIONS [0 ].replace ("." , "_" )
7+
8+ _ATTRS = {
9+ "bazel_binary" : attr .label (
10+ default = BAZEL_BINARY ,
11+ doc = """The bazel binary files to test against.
12+
13+ It is assumed by the test runner that the bazel binary is found at label_workspace/bazel (wksp/bazel.exe on Windows)""" ,
14+ ),
15+ "bazel_commands" : attr .string_list (
16+ default = ["info" , "test ..." ],
17+ doc = """The list of bazel commands to run. Defaults to `["info", "test ..."]`.
18+
19+ Note that if a command contains a bare `--` argument, the --test_arg passed to Bazel will appear before it.
20+ """ ,
21+ ),
22+ "workspace_files" : attr .label (
23+ doc = """A filegroup of all files in the workspace-under-test necessary to run the test.""" ,
24+ ),
25+ }
26+
27+ # Avoid using non-normalized paths (workspace/../other_workspace/path)
28+ def _to_manifest_path (ctx , file ):
29+ if file .short_path .startswith ("../" ):
30+ return file .short_path [3 :]
31+ else :
32+ return ctx .workspace_name + "/" + file .short_path
33+
34+ def _config_impl (ctx ):
35+ if len (SUPPORTED_BAZEL_VERSIONS ) > 1 :
36+ fail ("""
37+ bazel_integration_test doesn't support multiple Bazel versions to test against yet.
38+ """ )
39+ if len (ctx .files .workspace_files ) == 0 :
40+ fail ("""
41+ No files were found to run under integration testing. See comment in /.bazelrc.
42+ You probably need to run
43+ tools/bazel_integration_test/update_deleted_packages.sh
44+ """ )
45+
46+ # Serialize configuration file for test runner
47+ config = ctx .actions .declare_file ("%s.json" % ctx .attr .name )
48+ ctx .actions .write (
49+ output = config ,
50+ content = """
51+ {{
52+ "workspaceRoot": "{TMPL_workspace_root}",
53+ "bazelBinaryWorkspace": "{TMPL_bazel_binary_workspace}",
54+ "bazelCommands": [ {TMPL_bazel_commands} ]
55+ }}
56+ """ .format (
57+ TMPL_workspace_root = ctx .files .workspace_files [0 ].dirname ,
58+ TMPL_bazel_binary_workspace = ctx .attr .bazel_binary .label .workspace_name ,
59+ TMPL_bazel_commands = ", " .join (["\" %s\" " % s for s in ctx .attr .bazel_commands ]),
60+ ),
61+ )
62+
63+ return [DefaultInfo (
64+ files = depset ([config ]),
65+ runfiles = ctx .runfiles (files = [config ]),
66+ )]
67+
68+ _config = rule (
69+ implementation = _config_impl ,
70+ doc = "Configures an integration test that runs a specified version of bazel against an external workspace." ,
71+ attrs = _ATTRS ,
72+ )
73+
74+ def bazel_integration_test (name , ** kwargs ):
75+ """Wrapper macro to set default srcs and run a py_test with config
76+
77+ Args:
78+ name: name of the resulting py_test
79+ **kwargs: additional attributes like timeout and visibility
80+ """
81+ # By default, we assume sources for "pip_example" are in examples/pip/**/*
82+ dirname = name [:- len ("_example" )]
83+ native .filegroup (
84+ name = "_%s_sources" % name ,
85+ srcs = native .glob (
86+ ["%s/**/*" % dirname ],
87+ exclude = ["%s/bazel-*/**" % dirname ],
88+ ),
89+ )
90+ workspace_files = kwargs .pop ("workspace_files" , "_%s_sources" % name )
91+
92+ _config (
93+ name = "_%s_config" % name ,
94+ workspace_files = workspace_files ,
95+ )
96+
97+ py_test (
98+ name = name ,
99+ srcs = [Label ("//tools/bazel_integration_test:test_runner.py" )],
100+ main = "test_runner.py" ,
101+ args = [native .package_name () + "/_%s_config.json" % name ],
102+ deps = [Label ("//python/runfiles" )],
103+ data = [
104+ BAZEL_BINARY ,
105+ "_%s_config" % name ,
106+ workspace_files ,
107+ ],
108+ ** kwargs ,
109+ )
110+
111+
0 commit comments