• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Bazel Authors. All rights reserved.
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"""Helpers and utilities multiple tests re-use."""
15
16load("@bazel_skylib//lib:structs.bzl", "structs")
17
18# Use this with is_windows()
19WINDOWS_ATTR = {"windows": attr.label(default = "@platforms//os:windows")}
20
21def _create_tests(tests, **kwargs):
22    test_names = []
23    for func in tests:
24        test_name = _test_name_from_function(func)
25        func(name = test_name, **kwargs)
26        test_names.append(test_name)
27    return test_names
28
29def _test_name_from_function(func):
30    """Derives the name of the given rule implementation function.
31
32    Args:
33      func: the function whose name to extract
34
35    Returns:
36      The name of the given function. Note it will have leading and trailing
37      "_" stripped -- this allows passing a private function and having the
38      name of the test not start with "_".
39    """
40
41    # Starlark currently stringifies a function as "<function NAME>", so we use
42    # that knowledge to parse the "NAME" portion out.
43    # NOTE: This is relying on an implementation detail of Bazel
44    func_name = str(func)
45    func_name = func_name.partition("<function ")[-1]
46    func_name = func_name.rpartition(">")[0]
47    func_name = func_name.partition(" ")[0]
48    return func_name.strip("_")
49
50def _struct_with(s, **kwargs):
51    struct_dict = structs.to_dict(s)
52    struct_dict.update(kwargs)
53    return struct(**struct_dict)
54
55def _is_bazel_6_or_higher():
56    # Bazel 5.4 has a bug where every access of testing.ExecutionInfo is a
57    # different object that isn't equal to any other. This is fixed in bazel 6+.
58    return testing.ExecutionInfo == testing.ExecutionInfo
59
60def _is_windows(env):
61    """Tell if the target platform is windows.
62
63    This assumes the `WINDOWS_ATTR` attribute was added.
64
65    Args:
66        env: The test env struct
67    Returns:
68        True if the target is Windows, False if not.
69    """
70    constraint = env.ctx.attr.windows[platform_common.ConstraintValueInfo]
71    return env.ctx.target_platform_has_constraint(constraint)
72
73util = struct(
74    create_tests = _create_tests,
75    struct_with = _struct_with,
76    is_bazel_6_or_higher = _is_bazel_6_or_higher,
77    is_windows = _is_windows,
78)
79