| # Copyright 2022 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| """Rules for running lit tests with the upstream lit binary.""" |
| |
| # This exists as a separate file from iree_lit_test.bzl because we anticipate |
| # upstreaming it soon. |
| |
| load("@bazel_skylib//lib:paths.bzl", "paths") |
| load(":native_binary.bzl", "native_test") |
| |
| def _tools_on_path_impl(ctx): |
| runfiles = ctx.runfiles() |
| |
| # For Bazel 4.x support. Drop when Bazel 4.x is no longer supported |
| to_merge = [d[DefaultInfo].default_runfiles for d in ctx.attr.srcs] |
| if hasattr(runfiles, "merge_all"): |
| runfiles = runfiles.merge_all(to_merge) |
| else: |
| for m in to_merge: |
| runfiles = runfiles.merge(m) |
| |
| runfiles_symlinks = {} |
| |
| for src in ctx.attr.srcs: |
| exe = src[DefaultInfo].files_to_run.executable |
| if not exe: |
| fail("All targets used as tools by lit tests must have exactly one" + |
| " executable, but {} has none".format(src)) |
| bin_path = paths.join(ctx.attr.bin_dir, exe.basename) |
| if bin_path in runfiles_symlinks: |
| fail("All tools used by lit tests must have unique basenames, as" + |
| " they are added to the path." + |
| " {} and {} conflict".format(runfiles_symlinks[bin_path], exe)) |
| runfiles_symlinks[bin_path] = exe |
| |
| return [ |
| DefaultInfo(runfiles = ctx.runfiles( |
| symlinks = runfiles_symlinks, |
| ).merge(runfiles)), |
| ] |
| |
| _tools_on_path = rule( |
| _tools_on_path_impl, |
| attrs = { |
| "srcs": attr.label_list(allow_files = True, mandatory = True), |
| "bin_dir": attr.string(mandatory = True), |
| }, |
| doc = "Symlinks srcs into a single lit_bin directory. All basenames must be unique.", |
| ) |
| |
| def lit_test( |
| name, |
| test_file, |
| cfg, |
| tools = None, |
| args = None, |
| data = None, |
| visibility = None, |
| env = None, |
| timeout = None, |
| **kwargs): |
| """Runs a single test file with LLVM's lit tool. |
| |
| Args: |
| name: string. the name of the generated test target. |
| test_file: label. The file on which to run lit. |
| cfg: label. The lit config file. It must list the file extension of |
| `test_file` in config.suffixes and must be in a parent directory of |
| `test_file`. |
| tools: label list. Tools invoked in the lit RUN lines. These binaries will |
| be symlinked into a directory which is on the path. They must therefore |
| have unique basenames. |
| args: string list. Additional arguments to pass to lit. Note that the test |
| file, `-v`, and a `--path` argument for the directory to which `tools` |
| are symlinked are added automatically. |
| data: label list. Additional data dependencies of the test. Note that |
| targets in `cfg` and `tools`, as well as their data dependencies, are |
| added automatically. |
| visibility: visibility of the generated test target. |
| env: string_dict. Environment variables available during test execution. |
| See the common Bazel test attribute. |
| timeout: bazel test timeout string, as per common bazel definitions. |
| **kwargs: additional keyword arguments to pass to all generated rules. |
| |
| See https://llvm.org/docs/CommandGuide/lit.html for details on lit |
| """ |
| args = args or [] |
| data = data or [] |
| tools = tools or [] |
| |
| tools_on_path_target_name = "_{}_tools_on_path".format(name) |
| |
| bin_dir = paths.join( |
| native.package_name(), |
| tools_on_path_target_name, |
| "lit_bin", |
| ) |
| |
| _tools_on_path( |
| name = tools_on_path_target_name, |
| testonly = True, |
| srcs = tools, |
| bin_dir = bin_dir, |
| visibility = ["//visibility:private"], |
| **kwargs |
| ) |
| |
| native_test( |
| name = name, |
| src = "@llvm-project//llvm:lit", |
| # out = name, |
| args = [ |
| "-v", |
| "--path", |
| bin_dir, |
| "$(location {})".format(test_file), |
| ] + args, |
| data = [test_file, cfg, tools_on_path_target_name] + data, |
| visibility = visibility, |
| env = env, |
| timeout = timeout, |
| **kwargs |
| ) |
| |
| def lit_test_suite( |
| name, |
| srcs, |
| cfg, |
| tools = None, |
| args = None, |
| data = None, |
| visibility = None, |
| size = "small", |
| env = None, |
| timeout = None, |
| **kwargs): |
| """Creates one lit test per source file and a test suite that bundles them. |
| |
| Args: |
| name: string. the name of the generated test suite. |
| srcs: label_list. The files which contain the lit tests. |
| cfg: label. The lit config file. It must list the file extension of |
| the files in `srcs` in config.suffixes and must be in a parent directory |
| of `srcs`. |
| tools: label list. Tools invoked in the lit RUN lines. These binaries will |
| be symlinked into a directory which is on the path. They must therefore |
| have unique basenames. |
| args: string list. Additional arguments to pass to lit. Note that the test |
| file, `-v`, and a `--path` argument for the directory to which `tools` |
| are symlinked are added automatically. |
| data: label list. Additional data dependencies of the test. Note that |
| targets in `cfg` and `tools`, as well as their data dependencies, are |
| added automatically. |
| visibility: visibility of the generated test targets and test suite. |
| size: string. size of the generated tests. |
| env: string_dict. Environment variables available during test execution. |
| See the common Bazel test attribute. |
| timeout: timeout argument passed to the individual tests. |
| **kwargs: additional keyword arguments to pass to all generated rules. |
| |
| See https://llvm.org/docs/CommandGuide/lit.html for details on lit |
| """ |
| # If there are kwargs that need to be passed to only some of the generated |
| # rules, they should be extracted into separate named arguments. |
| |
| args = args or [] |
| data = data or [] |
| tools = tools or [] |
| |
| tests = [] |
| for test_file in srcs: |
| # It's generally good practice to prefix any generated names with the |
| # macro name, but it's also nice to have the test name just match the |
| # file name. |
| test_name = "%s.test" % (test_file) |
| tests.append(test_name) |
| lit_test( |
| name = test_name, |
| test_file = test_file, |
| cfg = cfg, |
| tools = tools, |
| args = args, |
| data = data, |
| visibility = visibility, |
| env = env, |
| timeout = timeout, |
| **kwargs |
| ) |
| |
| native.test_suite( |
| name = name, |
| tests = tests, |
| **kwargs |
| ) |