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:paths.bzl", "paths") 16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:sets.bzl", "sets") 17*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 18*7594170eSAndroid Build Coastguard Worker 19*7594170eSAndroid Build Coastguard Workerdef _assert_flags_present_in_action(env, action, expected_flags): 20*7594170eSAndroid Build Coastguard Worker if action.argv == None: 21*7594170eSAndroid Build Coastguard Worker asserts.true( 22*7594170eSAndroid Build Coastguard Worker env, 23*7594170eSAndroid Build Coastguard Worker False, 24*7594170eSAndroid Build Coastguard Worker "expected %s action to have arguments, but argv was None" % ( 25*7594170eSAndroid Build Coastguard Worker action.mnemonic, 26*7594170eSAndroid Build Coastguard Worker ), 27*7594170eSAndroid Build Coastguard Worker ) 28*7594170eSAndroid Build Coastguard Worker return 29*7594170eSAndroid Build Coastguard Worker for flag in expected_flags: 30*7594170eSAndroid Build Coastguard Worker asserts.true( 31*7594170eSAndroid Build Coastguard Worker env, 32*7594170eSAndroid Build Coastguard Worker flag in action.argv, 33*7594170eSAndroid Build Coastguard Worker "%s action did not contain flag %s; argv: %s" % ( 34*7594170eSAndroid Build Coastguard Worker action.mnemonic, 35*7594170eSAndroid Build Coastguard Worker flag, 36*7594170eSAndroid Build Coastguard Worker action.argv, 37*7594170eSAndroid Build Coastguard Worker ), 38*7594170eSAndroid Build Coastguard Worker ) 39*7594170eSAndroid Build Coastguard Worker 40*7594170eSAndroid Build Coastguard Worker# Checks for the presence of a set of given flags in a set of given actions 41*7594170eSAndroid Build Coastguard Worker# non-exclusively. In other words, it confirms that the specified actions 42*7594170eSAndroid Build Coastguard Worker# contain the given flags, but does not confirm that other actions do not 43*7594170eSAndroid Build Coastguard Worker# contain them. 44*7594170eSAndroid Build Coastguard Workerdef _action_flags_present_for_mnemonic_nonexclusive_test_impl(ctx): 45*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 46*7594170eSAndroid Build Coastguard Worker 47*7594170eSAndroid Build Coastguard Worker for action in analysistest.target_actions(env): 48*7594170eSAndroid Build Coastguard Worker if action.mnemonic in ctx.attr.mnemonics: 49*7594170eSAndroid Build Coastguard Worker _assert_flags_present_in_action( 50*7594170eSAndroid Build Coastguard Worker env, 51*7594170eSAndroid Build Coastguard Worker action, 52*7594170eSAndroid Build Coastguard Worker ctx.attr.expected_flags, 53*7594170eSAndroid Build Coastguard Worker ) 54*7594170eSAndroid Build Coastguard Worker 55*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 56*7594170eSAndroid Build Coastguard Worker 57*7594170eSAndroid Build Coastguard Workeraction_flags_present_for_mnemonic_nonexclusive_test = analysistest.make( 58*7594170eSAndroid Build Coastguard Worker _action_flags_present_for_mnemonic_nonexclusive_test_impl, 59*7594170eSAndroid Build Coastguard Worker attrs = { 60*7594170eSAndroid Build Coastguard Worker "mnemonics": attr.string_list( 61*7594170eSAndroid Build Coastguard Worker doc = """ 62*7594170eSAndroid Build Coastguard Worker Actions with these mnemonics will be expected to have the flags 63*7594170eSAndroid Build Coastguard Worker specified in expected_flags 64*7594170eSAndroid Build Coastguard Worker """, 65*7594170eSAndroid Build Coastguard Worker ), 66*7594170eSAndroid Build Coastguard Worker "expected_flags": attr.string_list(doc = "The flags to be checked for"), 67*7594170eSAndroid Build Coastguard Worker }, 68*7594170eSAndroid Build Coastguard Worker) 69*7594170eSAndroid Build Coastguard Worker 70*7594170eSAndroid Build Coastguard Worker# Checks for the presence of a set of given flags in a set of given actions 71*7594170eSAndroid Build Coastguard Worker# exclusively. In other words, it confirms that *only* the specified actions 72*7594170eSAndroid Build Coastguard Worker# contain the specified flags. 73*7594170eSAndroid Build Coastguard Workerdef _action_flags_present_only_for_mnemonic_test_impl(ctx): 74*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 75*7594170eSAndroid Build Coastguard Worker 76*7594170eSAndroid Build Coastguard Worker actions = analysistest.target_actions(env) 77*7594170eSAndroid Build Coastguard Worker found_at_least_one_action = False 78*7594170eSAndroid Build Coastguard Worker for action in actions: 79*7594170eSAndroid Build Coastguard Worker if action.mnemonic in ctx.attr.mnemonics: 80*7594170eSAndroid Build Coastguard Worker found_at_least_one_action = True 81*7594170eSAndroid Build Coastguard Worker _assert_flags_present_in_action( 82*7594170eSAndroid Build Coastguard Worker env, 83*7594170eSAndroid Build Coastguard Worker action, 84*7594170eSAndroid Build Coastguard Worker ctx.attr.expected_flags, 85*7594170eSAndroid Build Coastguard Worker ) 86*7594170eSAndroid Build Coastguard Worker elif action.argv != None: 87*7594170eSAndroid Build Coastguard Worker for flag in ctx.attr.expected_flags: 88*7594170eSAndroid Build Coastguard Worker asserts.false( 89*7594170eSAndroid Build Coastguard Worker env, 90*7594170eSAndroid Build Coastguard Worker flag in action.argv, 91*7594170eSAndroid Build Coastguard Worker "%s action unexpectedly contained flag %s; argv: %s" % ( 92*7594170eSAndroid Build Coastguard Worker action.mnemonic, 93*7594170eSAndroid Build Coastguard Worker flag, 94*7594170eSAndroid Build Coastguard Worker action.argv, 95*7594170eSAndroid Build Coastguard Worker ), 96*7594170eSAndroid Build Coastguard Worker ) 97*7594170eSAndroid Build Coastguard Worker asserts.true( 98*7594170eSAndroid Build Coastguard Worker env, 99*7594170eSAndroid Build Coastguard Worker found_at_least_one_action, 100*7594170eSAndroid Build Coastguard Worker "did not find any actions with mnemonic %s, found: %s" % ( 101*7594170eSAndroid Build Coastguard Worker ctx.attr.mnemonics, 102*7594170eSAndroid Build Coastguard Worker [a.mnemonic for a in actions], 103*7594170eSAndroid Build Coastguard Worker ), 104*7594170eSAndroid Build Coastguard Worker ) 105*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 106*7594170eSAndroid Build Coastguard Worker 107*7594170eSAndroid Build Coastguard Workerdef action_flags_present_only_for_mnemonic_test_with_config_settings(config_settings = {}): 108*7594170eSAndroid Build Coastguard Worker return analysistest.make( 109*7594170eSAndroid Build Coastguard Worker _action_flags_present_only_for_mnemonic_test_impl, 110*7594170eSAndroid Build Coastguard Worker attrs = { 111*7594170eSAndroid Build Coastguard Worker "mnemonics": attr.string_list( 112*7594170eSAndroid Build Coastguard Worker doc = """ 113*7594170eSAndroid Build Coastguard Worker Actions with these mnemonics will be expected to have the flags 114*7594170eSAndroid Build Coastguard Worker specified in expected_flags 115*7594170eSAndroid Build Coastguard Worker """, 116*7594170eSAndroid Build Coastguard Worker ), 117*7594170eSAndroid Build Coastguard Worker "expected_flags": attr.string_list(doc = "The flags to be checked for"), 118*7594170eSAndroid Build Coastguard Worker }, 119*7594170eSAndroid Build Coastguard Worker config_settings = config_settings, 120*7594170eSAndroid Build Coastguard Worker ) 121*7594170eSAndroid Build Coastguard Worker 122*7594170eSAndroid Build Coastguard Workeraction_flags_present_only_for_mnemonic_test = action_flags_present_only_for_mnemonic_test_with_config_settings() 123*7594170eSAndroid Build Coastguard Worker 124*7594170eSAndroid Build Coastguard Workeraction_flags_present_only_for_mnemonic_aosp_arm64_test = action_flags_present_only_for_mnemonic_test_with_config_settings({ 125*7594170eSAndroid Build Coastguard Worker "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing", 126*7594170eSAndroid Build Coastguard Worker}) 127*7594170eSAndroid Build Coastguard Worker 128*7594170eSAndroid Build Coastguard Workeraction_flags_present_only_for_mnemonic_aosp_arm64_host_test = action_flags_present_only_for_mnemonic_test_with_config_settings({ 129*7594170eSAndroid Build Coastguard Worker "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_linux_x86_64", 130*7594170eSAndroid Build Coastguard Worker}) 131*7594170eSAndroid Build Coastguard Worker 132*7594170eSAndroid Build Coastguard Worker# Checks that a given set of flags are NOT present in a given set of actions. 133*7594170eSAndroid Build Coastguard Worker# Unlike the above test, this test does NOT confirm the absence of flags 134*7594170eSAndroid Build Coastguard Worker# *exclusively*. It does not confirm that the flags are present in actions 135*7594170eSAndroid Build Coastguard Worker# other than those specified 136*7594170eSAndroid Build Coastguard Workerdef _action_flags_absent_for_mnemonic_test_impl(ctx): 137*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 138*7594170eSAndroid Build Coastguard Worker 139*7594170eSAndroid Build Coastguard Worker actions = analysistest.target_actions(env) 140*7594170eSAndroid Build Coastguard Worker for action in actions: 141*7594170eSAndroid Build Coastguard Worker if action.mnemonic in ctx.attr.mnemonics and action.argv != None: 142*7594170eSAndroid Build Coastguard Worker for flag in ctx.attr.expected_absent_flags: 143*7594170eSAndroid Build Coastguard Worker asserts.false( 144*7594170eSAndroid Build Coastguard Worker env, 145*7594170eSAndroid Build Coastguard Worker flag in action.argv, 146*7594170eSAndroid Build Coastguard Worker "%s action unexpectedly contained flag %s; argv: %s" % ( 147*7594170eSAndroid Build Coastguard Worker action.mnemonic, 148*7594170eSAndroid Build Coastguard Worker flag, 149*7594170eSAndroid Build Coastguard Worker action.argv, 150*7594170eSAndroid Build Coastguard Worker ), 151*7594170eSAndroid Build Coastguard Worker ) 152*7594170eSAndroid Build Coastguard Worker 153*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 154*7594170eSAndroid Build Coastguard Worker 155*7594170eSAndroid Build Coastguard Workerdef action_flags_absent_for_mnemonic_test_with_config_settings(config_settings = {}): 156*7594170eSAndroid Build Coastguard Worker return analysistest.make( 157*7594170eSAndroid Build Coastguard Worker _action_flags_absent_for_mnemonic_test_impl, 158*7594170eSAndroid Build Coastguard Worker attrs = { 159*7594170eSAndroid Build Coastguard Worker "mnemonics": attr.string_list( 160*7594170eSAndroid Build Coastguard Worker doc = """ 161*7594170eSAndroid Build Coastguard Worker Actions with these mnemonics will be expected NOT to have the flags 162*7594170eSAndroid Build Coastguard Worker specificed in expected_flags 163*7594170eSAndroid Build Coastguard Worker """, 164*7594170eSAndroid Build Coastguard Worker ), 165*7594170eSAndroid Build Coastguard Worker "expected_absent_flags": attr.string_list( 166*7594170eSAndroid Build Coastguard Worker doc = """ 167*7594170eSAndroid Build Coastguard Worker The flags to be confirmed are absent from the actions in mnemonics 168*7594170eSAndroid Build Coastguard Worker """, 169*7594170eSAndroid Build Coastguard Worker ), 170*7594170eSAndroid Build Coastguard Worker }, 171*7594170eSAndroid Build Coastguard Worker config_settings = config_settings, 172*7594170eSAndroid Build Coastguard Worker ) 173*7594170eSAndroid Build Coastguard Worker 174*7594170eSAndroid Build Coastguard Workeraction_flags_absent_for_mnemonic_test = action_flags_absent_for_mnemonic_test_with_config_settings() 175*7594170eSAndroid Build Coastguard Worker 176*7594170eSAndroid Build Coastguard Workeraction_flags_absent_for_mnemonic_aosp_arm64_test = action_flags_absent_for_mnemonic_test_with_config_settings({ 177*7594170eSAndroid Build Coastguard Worker "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing", 178*7594170eSAndroid Build Coastguard Worker}) 179*7594170eSAndroid Build Coastguard Worker 180*7594170eSAndroid Build Coastguard Workeraction_flags_absent_for_mnemonic_aosp_arm64_host_test = action_flags_absent_for_mnemonic_test_with_config_settings({ 181*7594170eSAndroid Build Coastguard Worker "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_linux_x86_64", 182*7594170eSAndroid Build Coastguard Worker}) 183*7594170eSAndroid Build Coastguard Worker 184*7594170eSAndroid Build Coastguard Workerdef _input_output_verification_test_impl(ctx): 185*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 186*7594170eSAndroid Build Coastguard Worker actions = [a for a in analysistest.target_actions(env) if a.mnemonic == ctx.attr.mnemonic] 187*7594170eSAndroid Build Coastguard Worker asserts.true( 188*7594170eSAndroid Build Coastguard Worker env, 189*7594170eSAndroid Build Coastguard Worker len(actions) == 1, 190*7594170eSAndroid Build Coastguard Worker "Action not found: %s" % actions, 191*7594170eSAndroid Build Coastguard Worker ) 192*7594170eSAndroid Build Coastguard Worker package_root = ctx.label.package 193*7594170eSAndroid Build Coastguard Worker 194*7594170eSAndroid Build Coastguard Worker input_files = [paths.join(package_root, a) for a in ctx.attr.input_files] 195*7594170eSAndroid Build Coastguard Worker output_files = [paths.join(package_root, a) for a in ctx.attr.output_files] 196*7594170eSAndroid Build Coastguard Worker 197*7594170eSAndroid Build Coastguard Worker action = actions[0] 198*7594170eSAndroid Build Coastguard Worker 199*7594170eSAndroid Build Coastguard Worker if len(input_files) > 0: 200*7594170eSAndroid Build Coastguard Worker expected = sets.make( 201*7594170eSAndroid Build Coastguard Worker input_files, 202*7594170eSAndroid Build Coastguard Worker ) 203*7594170eSAndroid Build Coastguard Worker actual = sets.make([ 204*7594170eSAndroid Build Coastguard Worker file.short_path 205*7594170eSAndroid Build Coastguard Worker for file in action.inputs.to_list() 206*7594170eSAndroid Build Coastguard Worker ]) 207*7594170eSAndroid Build Coastguard Worker asserts.true( 208*7594170eSAndroid Build Coastguard Worker env, 209*7594170eSAndroid Build Coastguard Worker sets.is_subset(expected, actual), 210*7594170eSAndroid Build Coastguard Worker "Not all input files are present %s %s" % (expected, actual), 211*7594170eSAndroid Build Coastguard Worker ) 212*7594170eSAndroid Build Coastguard Worker 213*7594170eSAndroid Build Coastguard Worker if len(output_files) > 0: 214*7594170eSAndroid Build Coastguard Worker expected = sets.make( 215*7594170eSAndroid Build Coastguard Worker output_files, 216*7594170eSAndroid Build Coastguard Worker ) 217*7594170eSAndroid Build Coastguard Worker actual = sets.make([ 218*7594170eSAndroid Build Coastguard Worker file.short_path 219*7594170eSAndroid Build Coastguard Worker for file in action.outputs.to_list() 220*7594170eSAndroid Build Coastguard Worker ]) 221*7594170eSAndroid Build Coastguard Worker asserts.true( 222*7594170eSAndroid Build Coastguard Worker env, 223*7594170eSAndroid Build Coastguard Worker sets.is_equal(expected, actual), 224*7594170eSAndroid Build Coastguard Worker "Not all output files are present %s %s" % (expected, actual), 225*7594170eSAndroid Build Coastguard Worker ) 226*7594170eSAndroid Build Coastguard Worker 227*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 228*7594170eSAndroid Build Coastguard Worker 229*7594170eSAndroid Build Coastguard Workerinput_output_verification_test = analysistest.make( 230*7594170eSAndroid Build Coastguard Worker _input_output_verification_test_impl, 231*7594170eSAndroid Build Coastguard Worker attrs = { 232*7594170eSAndroid Build Coastguard Worker "mnemonic": attr.string(), 233*7594170eSAndroid Build Coastguard Worker "input_files": attr.string_list(), 234*7594170eSAndroid Build Coastguard Worker "output_files": attr.string_list(), 235*7594170eSAndroid Build Coastguard Worker }, 236*7594170eSAndroid Build Coastguard Worker) 237