xref: /aosp_15_r20/build/bazel/rules/test_common/flags.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
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