1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:new_sets.bzl", "sets") 16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 17*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 18*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:gensrcs.bzl", "gensrcs") 19*7594170eSAndroid Build Coastguard Worker 20*7594170eSAndroid Build Coastguard WorkerSRCS = [ 21*7594170eSAndroid Build Coastguard Worker "texts/src1.txt", 22*7594170eSAndroid Build Coastguard Worker "texts/src2.txt", 23*7594170eSAndroid Build Coastguard Worker "src3.txt", 24*7594170eSAndroid Build Coastguard Worker] 25*7594170eSAndroid Build Coastguard Worker 26*7594170eSAndroid Build Coastguard WorkerOUTPUT_EXTENSION = "out" 27*7594170eSAndroid Build Coastguard Worker 28*7594170eSAndroid Build Coastguard WorkerEXPECTED_OUTS = [ 29*7594170eSAndroid Build Coastguard Worker "texts/src1.out", 30*7594170eSAndroid Build Coastguard Worker "texts/src2.out", 31*7594170eSAndroid Build Coastguard Worker "src3.out", 32*7594170eSAndroid Build Coastguard Worker] 33*7594170eSAndroid Build Coastguard Worker 34*7594170eSAndroid Build Coastguard Worker# ==== Check the actions created by gensrcs ==== 35*7594170eSAndroid Build Coastguard Worker 36*7594170eSAndroid Build Coastguard Workerdef _test_actions_impl(ctx): 37*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 38*7594170eSAndroid Build Coastguard Worker target = analysistest.target_under_test(env) 39*7594170eSAndroid Build Coastguard Worker actions = analysistest.target_actions(env) 40*7594170eSAndroid Build Coastguard Worker 41*7594170eSAndroid Build Coastguard Worker # Expect an action for each pair of input/output file 42*7594170eSAndroid Build Coastguard Worker asserts.equals(env, expected = len(SRCS), actual = len(actions)) 43*7594170eSAndroid Build Coastguard Worker 44*7594170eSAndroid Build Coastguard Worker package = target.label.package 45*7594170eSAndroid Build Coastguard Worker data_paths = [paths.join(package, d) for d in ctx.attr.data] 46*7594170eSAndroid Build Coastguard Worker data_set = sets.make(data_paths) 47*7594170eSAndroid Build Coastguard Worker for action in actions: 48*7594170eSAndroid Build Coastguard Worker for d in data_paths: 49*7594170eSAndroid Build Coastguard Worker asserts.true( 50*7594170eSAndroid Build Coastguard Worker env, 51*7594170eSAndroid Build Coastguard Worker d in " ".join(action.argv), 52*7594170eSAndroid Build Coastguard Worker "Expected data file %s to be in command %s" % (d, action.argv), 53*7594170eSAndroid Build Coastguard Worker ) 54*7594170eSAndroid Build Coastguard Worker inputs = sets.make([i.path for i in action.inputs.to_list()]) 55*7594170eSAndroid Build Coastguard Worker asserts.true( 56*7594170eSAndroid Build Coastguard Worker env, 57*7594170eSAndroid Build Coastguard Worker sets.is_subset(data_set, inputs), 58*7594170eSAndroid Build Coastguard Worker "Expected %s to be a subset of all inputs %s" % (data_set, inputs), 59*7594170eSAndroid Build Coastguard Worker ) 60*7594170eSAndroid Build Coastguard Worker 61*7594170eSAndroid Build Coastguard Worker asserts.set_equals( 62*7594170eSAndroid Build Coastguard Worker env, 63*7594170eSAndroid Build Coastguard Worker sets.make([ 64*7594170eSAndroid Build Coastguard Worker # given an input file build/bazel/rules/texts/src1.txt 65*7594170eSAndroid Build Coastguard Worker # the corresponding output file is 66*7594170eSAndroid Build Coastguard Worker # <GENDIR>/build/bazel/rules/build/bazel/rules/texts/src1.out 67*7594170eSAndroid Build Coastguard Worker # the second "build/bazel/rules" is to accomodate the srcs from 68*7594170eSAndroid Build Coastguard Worker # external package 69*7594170eSAndroid Build Coastguard Worker paths.join( 70*7594170eSAndroid Build Coastguard Worker ctx.genfiles_dir.path, 71*7594170eSAndroid Build Coastguard Worker "build/bazel/rules", 72*7594170eSAndroid Build Coastguard Worker "build/bazel/rules", 73*7594170eSAndroid Build Coastguard Worker out, 74*7594170eSAndroid Build Coastguard Worker ) 75*7594170eSAndroid Build Coastguard Worker for out in EXPECTED_OUTS 76*7594170eSAndroid Build Coastguard Worker ]), 77*7594170eSAndroid Build Coastguard Worker sets.make([file.path for file in target.files.to_list()]), 78*7594170eSAndroid Build Coastguard Worker ) 79*7594170eSAndroid Build Coastguard Worker 80*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 81*7594170eSAndroid Build Coastguard Worker 82*7594170eSAndroid Build Coastguard Workeractions_test = analysistest.make( 83*7594170eSAndroid Build Coastguard Worker _test_actions_impl, 84*7594170eSAndroid Build Coastguard Worker attrs = { 85*7594170eSAndroid Build Coastguard Worker "data": attr.string_list(), 86*7594170eSAndroid Build Coastguard Worker }, 87*7594170eSAndroid Build Coastguard Worker) 88*7594170eSAndroid Build Coastguard Worker 89*7594170eSAndroid Build Coastguard Workerdef _test_actions(): 90*7594170eSAndroid Build Coastguard Worker name = "gensrcs_output_paths" 91*7594170eSAndroid Build Coastguard Worker test_name = name + "_test" 92*7594170eSAndroid Build Coastguard Worker data = ["foo/bar.txt", "baz.txt"] 93*7594170eSAndroid Build Coastguard Worker 94*7594170eSAndroid Build Coastguard Worker # Rule under test 95*7594170eSAndroid Build Coastguard Worker gensrcs( 96*7594170eSAndroid Build Coastguard Worker name = name, 97*7594170eSAndroid Build Coastguard Worker cmd = "cat $(SRC) > $(OUT) && cat $(location foo/bar.txt) >> $(OUT) && cat $(location baz.txt) >> $(OUT)", 98*7594170eSAndroid Build Coastguard Worker srcs = SRCS, 99*7594170eSAndroid Build Coastguard Worker output_extension = OUTPUT_EXTENSION, 100*7594170eSAndroid Build Coastguard Worker data = data, 101*7594170eSAndroid Build Coastguard Worker tags = ["manual"], # make sure it's not built using `:all` 102*7594170eSAndroid Build Coastguard Worker ) 103*7594170eSAndroid Build Coastguard Worker 104*7594170eSAndroid Build Coastguard Worker actions_test( 105*7594170eSAndroid Build Coastguard Worker name = test_name, 106*7594170eSAndroid Build Coastguard Worker target_under_test = name, 107*7594170eSAndroid Build Coastguard Worker data = data, 108*7594170eSAndroid Build Coastguard Worker ) 109*7594170eSAndroid Build Coastguard Worker return test_name 110*7594170eSAndroid Build Coastguard Worker 111*7594170eSAndroid Build Coastguard Worker# ==== Check the output file when out_extension is unset ==== 112*7594170eSAndroid Build Coastguard Worker 113*7594170eSAndroid Build Coastguard Workerdef _test_unset_output_extension_impl(ctx): 114*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 115*7594170eSAndroid Build Coastguard Worker 116*7594170eSAndroid Build Coastguard Worker actions = analysistest.target_actions(env) 117*7594170eSAndroid Build Coastguard Worker asserts.equals(env, expected = 1, actual = len(actions)) 118*7594170eSAndroid Build Coastguard Worker action = actions[0] 119*7594170eSAndroid Build Coastguard Worker asserts.equals( 120*7594170eSAndroid Build Coastguard Worker env, 121*7594170eSAndroid Build Coastguard Worker expected = "input.", 122*7594170eSAndroid Build Coastguard Worker actual = action.outputs.to_list()[0].basename, 123*7594170eSAndroid Build Coastguard Worker ) 124*7594170eSAndroid Build Coastguard Worker 125*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 126*7594170eSAndroid Build Coastguard Worker 127*7594170eSAndroid Build Coastguard Workerunset_output_extension_test = analysistest.make(_test_unset_output_extension_impl) 128*7594170eSAndroid Build Coastguard Worker 129*7594170eSAndroid Build Coastguard Workerdef _test_unset_output_extension(): 130*7594170eSAndroid Build Coastguard Worker name = "unset_output_extension" 131*7594170eSAndroid Build Coastguard Worker test_name = name + "_test" 132*7594170eSAndroid Build Coastguard Worker 133*7594170eSAndroid Build Coastguard Worker # Rule under test 134*7594170eSAndroid Build Coastguard Worker gensrcs( 135*7594170eSAndroid Build Coastguard Worker name = "TSTSS", 136*7594170eSAndroid Build Coastguard Worker cmd = "cat $(SRC) > $(OUT)", 137*7594170eSAndroid Build Coastguard Worker srcs = ["input.txt"], 138*7594170eSAndroid Build Coastguard Worker tags = ["manual"], # make sure it's not built using `:all` 139*7594170eSAndroid Build Coastguard Worker ) 140*7594170eSAndroid Build Coastguard Worker 141*7594170eSAndroid Build Coastguard Worker unset_output_extension_test( 142*7594170eSAndroid Build Coastguard Worker name = test_name, 143*7594170eSAndroid Build Coastguard Worker target_under_test = "TSTSS", 144*7594170eSAndroid Build Coastguard Worker ) 145*7594170eSAndroid Build Coastguard Worker return test_name 146*7594170eSAndroid Build Coastguard Worker 147*7594170eSAndroid Build Coastguard WorkerTOOL_FILE_NAME = "out.sh" 148*7594170eSAndroid Build Coastguard Worker 149*7594170eSAndroid Build Coastguard Workerdef _test_gensrcs_tool_builds_for_host_impl(ctx): 150*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 151*7594170eSAndroid Build Coastguard Worker actions = analysistest.target_actions(env) 152*7594170eSAndroid Build Coastguard Worker asserts.equals(env, expected = 1, actual = len(actions), msg = "expected actions") 153*7594170eSAndroid Build Coastguard Worker 154*7594170eSAndroid Build Coastguard Worker action = actions[0] 155*7594170eSAndroid Build Coastguard Worker inputs = action.inputs.to_list() 156*7594170eSAndroid Build Coastguard Worker asserts.equals(env, expected = 2, actual = len(inputs), msg = "expected inputs") 157*7594170eSAndroid Build Coastguard Worker 158*7594170eSAndroid Build Coastguard Worker input_map = {} 159*7594170eSAndroid Build Coastguard Worker for i in inputs: 160*7594170eSAndroid Build Coastguard Worker input_map[i.basename] = i 161*7594170eSAndroid Build Coastguard Worker tool = input_map[TOOL_FILE_NAME] 162*7594170eSAndroid Build Coastguard Worker asserts.true( 163*7594170eSAndroid Build Coastguard Worker env, 164*7594170eSAndroid Build Coastguard Worker # because we set --experimental_platform_in_output_dir, we expect the 165*7594170eSAndroid Build Coastguard Worker # platform to be in the output path of a generated file 166*7594170eSAndroid Build Coastguard Worker "linux" in tool.path, # host platform 167*7594170eSAndroid Build Coastguard Worker "expected 'linux' in tool path, got '%s'" % tool.path, 168*7594170eSAndroid Build Coastguard Worker ) 169*7594170eSAndroid Build Coastguard Worker 170*7594170eSAndroid Build Coastguard Worker outputs = action.outputs.to_list() 171*7594170eSAndroid Build Coastguard Worker asserts.equals(env, expected = 1, actual = len(outputs), msg = "expected outputs %s" % outputs) 172*7594170eSAndroid Build Coastguard Worker output = outputs[0] 173*7594170eSAndroid Build Coastguard Worker asserts.true( 174*7594170eSAndroid Build Coastguard Worker env, 175*7594170eSAndroid Build Coastguard Worker # because we set --experimental_platform_in_output_dir, we expect the 176*7594170eSAndroid Build Coastguard Worker # platform to be in the output path of a generated file. However, the platform 177*7594170eSAndroid Build Coastguard Worker # will be the android product name, like aosp_arm, so we can't check if anything 178*7594170eSAndroid Build Coastguard Worker # in particular is in the path. Check that linux is not in the path instead. 179*7594170eSAndroid Build Coastguard Worker "linux" not in output.path, # target platform 180*7594170eSAndroid Build Coastguard Worker "expected 'linux' to not be in output path, got '%s'" % output.path, 181*7594170eSAndroid Build Coastguard Worker ) 182*7594170eSAndroid Build Coastguard Worker 183*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 184*7594170eSAndroid Build Coastguard Worker 185*7594170eSAndroid Build Coastguard Worker__gensrcs_tool_builds_for_host_test = analysistest.make( 186*7594170eSAndroid Build Coastguard Worker _test_gensrcs_tool_builds_for_host_impl, 187*7594170eSAndroid Build Coastguard Worker) 188*7594170eSAndroid Build Coastguard Worker 189*7594170eSAndroid Build Coastguard Workerdef _gensrcs_tool_builds_for_host_test(**kwargs): 190*7594170eSAndroid Build Coastguard Worker __gensrcs_tool_builds_for_host_test( 191*7594170eSAndroid Build Coastguard Worker target_compatible_with = ["//build/bazel_common_rules/platforms/os:android"], # ensure target != host so there is a transition 192*7594170eSAndroid Build Coastguard Worker **kwargs 193*7594170eSAndroid Build Coastguard Worker ) 194*7594170eSAndroid Build Coastguard Worker 195*7594170eSAndroid Build Coastguard Workerdef _test_gensrcs_tool_builds_for_host(): 196*7594170eSAndroid Build Coastguard Worker native.genrule( 197*7594170eSAndroid Build Coastguard Worker name = "gensrcs_test_bin", 198*7594170eSAndroid Build Coastguard Worker outs = [TOOL_FILE_NAME], 199*7594170eSAndroid Build Coastguard Worker executable = True, 200*7594170eSAndroid Build Coastguard Worker cmd = "touch $@", 201*7594170eSAndroid Build Coastguard Worker target_compatible_with = select({ 202*7594170eSAndroid Build Coastguard Worker # only supported OS is that specified as host_platform 203*7594170eSAndroid Build Coastguard Worker "//build/bazel_common_rules/platforms/os:linux": [], 204*7594170eSAndroid Build Coastguard Worker "//conditions:default": ["@platforms//:incompatible"], 205*7594170eSAndroid Build Coastguard Worker }), 206*7594170eSAndroid Build Coastguard Worker tags = ["manual"], 207*7594170eSAndroid Build Coastguard Worker ) 208*7594170eSAndroid Build Coastguard Worker 209*7594170eSAndroid Build Coastguard Worker gensrcs( 210*7594170eSAndroid Build Coastguard Worker name = "gensrcs_test_tool_builds_for_host", 211*7594170eSAndroid Build Coastguard Worker tools = [":gensrcs_test_bin"], 212*7594170eSAndroid Build Coastguard Worker srcs = ["input.txt"], 213*7594170eSAndroid Build Coastguard Worker output_extension = OUTPUT_EXTENSION, 214*7594170eSAndroid Build Coastguard Worker cmd = "", 215*7594170eSAndroid Build Coastguard Worker tags = ["manual"], 216*7594170eSAndroid Build Coastguard Worker ) 217*7594170eSAndroid Build Coastguard Worker 218*7594170eSAndroid Build Coastguard Worker test_name = "gensrcs_tools_build_for_host_test" 219*7594170eSAndroid Build Coastguard Worker _gensrcs_tool_builds_for_host_test( 220*7594170eSAndroid Build Coastguard Worker name = test_name, 221*7594170eSAndroid Build Coastguard Worker target_under_test = ":gensrcs_test_tool_builds_for_host", 222*7594170eSAndroid Build Coastguard Worker ) 223*7594170eSAndroid Build Coastguard Worker return test_name 224*7594170eSAndroid Build Coastguard Worker 225*7594170eSAndroid Build Coastguard Workerdef gensrcs_tests_suite(name): 226*7594170eSAndroid Build Coastguard Worker """Creates test targets for gensrcs.bzl""" 227*7594170eSAndroid Build Coastguard Worker native.test_suite( 228*7594170eSAndroid Build Coastguard Worker name = name, 229*7594170eSAndroid Build Coastguard Worker tests = [ 230*7594170eSAndroid Build Coastguard Worker _test_actions(), 231*7594170eSAndroid Build Coastguard Worker _test_unset_output_extension(), 232*7594170eSAndroid Build Coastguard Worker _test_gensrcs_tool_builds_for_host(), 233*7594170eSAndroid Build Coastguard Worker ], 234*7594170eSAndroid Build Coastguard Worker ) 235