1# Copyright (C) 2025 The Android Open Source Project 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 15""" 16This file defines `build_and_run_tests` rule 17""" 18 19load("@rules_shell//shell:sh_test.bzl", "sh_test") 20 21def _build_and_run_impl(ctx): 22 # Executable file from the attribute. 23 executable = ctx.executable.executable 24 25 # Output log file. 26 logfile = ctx.actions.declare_file("%s.txt" % ctx.attr.name) 27 28 ctx.actions.run_shell( 29 inputs = [executable] + ctx.files.data, 30 outputs = [logfile], 31 progress_message = "Running test %s" % executable.short_path, 32 command = """\ 33 BIN="%s" && \ 34 OUT="%s" && \ 35 ($BIN > $OUT || \ 36 if [ $? == 0 ]; then 37 true 38 else 39 echo "\n%s failed." && cat $OUT && false 40 fi) 41""" % (executable.path, logfile.path, executable.short_path), 42 ) 43 44 return [DefaultInfo(files = depset([logfile]))] 45 46build_and_run = rule( 47 implementation = _build_and_run_impl, 48 attrs = { 49 "executable": attr.label( 50 executable = True, 51 cfg = "exec", 52 allow_files = True, 53 mandatory = True, 54 ), 55 "data": attr.label_list( 56 allow_files = True, 57 allow_empty = True, 58 ), 59 }, 60) 61 62# TODO(b/382503065): This is a temporary workaround due to presubmit infra not blocking on test 63# failures and only on build failures. Removed once the issue is solved. 64def build_and_run_tests(name, tests, data): 65 """Create an `sh_test` target that run a set of unittests during build time. 66 67 Args: 68 name (String): name of the rust_library target. 69 tests (List of strings): List of test target. 70 data (List of strings): Runtime data needed by the tests. 71 """ 72 73 all_tests = [] 74 for idx, test in enumerate(tests): 75 subtest_name = "{}_subtest_{}".format(name, idx) 76 build_and_run( 77 name = subtest_name, 78 testonly = True, 79 executable = test, 80 data = data, 81 ) 82 83 all_tests.append(":{}".format(subtest_name)) 84 85 sh_test( 86 name = name, 87 srcs = ["@gbl//tests:noop.sh"], 88 data = all_tests, 89 ) 90