| # 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 | |
| ) |