xref: /aosp_15_r20/external/bazelbuild-rules_testing/tests/analysis_test_tests.bzl (revision d605057434dcabba796c020773aab68d9790ff9f)
1*d6050574SRomain Jobredeaux# Copyright 2022 The Bazel Authors. All rights reserved.
2*d6050574SRomain Jobredeaux#
3*d6050574SRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License");
4*d6050574SRomain Jobredeaux# you may not use this file except in compliance with the License.
5*d6050574SRomain Jobredeaux# You may obtain a copy of the License at
6*d6050574SRomain Jobredeaux#
7*d6050574SRomain Jobredeaux#    http://www.apache.org/licenses/LICENSE-2.0
8*d6050574SRomain Jobredeaux#
9*d6050574SRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software
10*d6050574SRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS,
11*d6050574SRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*d6050574SRomain Jobredeaux# See the License for the specific language governing permissions and
13*d6050574SRomain Jobredeaux# limitations under the License.
14*d6050574SRomain Jobredeaux
15*d6050574SRomain Jobredeaux"""Unit tests for analysis_test.bzl."""
16*d6050574SRomain Jobredeaux
17*d6050574SRomain Jobredeauxload("//lib:analysis_test.bzl", "analysis_test", "test_suite")
18*d6050574SRomain Jobredeauxload("//lib:truth.bzl", "matching")
19*d6050574SRomain Jobredeauxload("//lib:util.bzl", "TestingAspectInfo")
20*d6050574SRomain Jobredeaux
21*d6050574SRomain Jobredeaux###################################
22*d6050574SRomain Jobredeaux####### change_setting_test #######
23*d6050574SRomain Jobredeaux###################################
24*d6050574SRomain Jobredeaux
25*d6050574SRomain Jobredeaux_ChangeSettingInfo = provider(
26*d6050574SRomain Jobredeaux    doc = "min_os_version for change_setting_test",
27*d6050574SRomain Jobredeaux    fields = ["min_os_version"],
28*d6050574SRomain Jobredeaux)
29*d6050574SRomain Jobredeaux
30*d6050574SRomain Jobredeauxdef _change_setting_fake_rule(ctx):
31*d6050574SRomain Jobredeaux    return [_ChangeSettingInfo(min_os_version = ctx.fragments.cpp.minimum_os_version())]
32*d6050574SRomain Jobredeaux
33*d6050574SRomain Jobredeauxchange_setting_fake_rule = rule(
34*d6050574SRomain Jobredeaux    implementation = _change_setting_fake_rule,
35*d6050574SRomain Jobredeaux    fragments = ["cpp"],
36*d6050574SRomain Jobredeaux)
37*d6050574SRomain Jobredeaux
38*d6050574SRomain Jobredeauxdef test_change_setting(name):
39*d6050574SRomain Jobredeaux    """Test to verify that an analysis test may change configuration."""
40*d6050574SRomain Jobredeaux    change_setting_fake_rule(name = name + "_fake_target", tags = ["manual"])
41*d6050574SRomain Jobredeaux
42*d6050574SRomain Jobredeaux    analysis_test(
43*d6050574SRomain Jobredeaux        name = name,
44*d6050574SRomain Jobredeaux        target = name + "_fake_target",
45*d6050574SRomain Jobredeaux        impl = _test_change_setting,
46*d6050574SRomain Jobredeaux        config_settings = {
47*d6050574SRomain Jobredeaux            "//command_line_option:minimum_os_version": "1234.5678",
48*d6050574SRomain Jobredeaux        },
49*d6050574SRomain Jobredeaux    )
50*d6050574SRomain Jobredeaux
51*d6050574SRomain Jobredeauxdef _test_change_setting(env, target):
52*d6050574SRomain Jobredeaux    dep_min_os_version = target[_ChangeSettingInfo].min_os_version
53*d6050574SRomain Jobredeaux    env.expect.that_str(dep_min_os_version).equals("1234.5678")
54*d6050574SRomain Jobredeaux
55*d6050574SRomain Jobredeaux####################################
56*d6050574SRomain Jobredeaux####### failure_testing_test #######
57*d6050574SRomain Jobredeaux####################################
58*d6050574SRomain Jobredeaux
59*d6050574SRomain Jobredeauxdef _failure_testing_fake_rule(_ctx):
60*d6050574SRomain Jobredeaux    fail("This rule should never work")
61*d6050574SRomain Jobredeaux
62*d6050574SRomain Jobredeauxfailure_testing_fake_rule = rule(
63*d6050574SRomain Jobredeaux    implementation = _failure_testing_fake_rule,
64*d6050574SRomain Jobredeaux)
65*d6050574SRomain Jobredeaux
66*d6050574SRomain Jobredeauxdef test_failure_testing(name):
67*d6050574SRomain Jobredeaux    """Test to verify that an analysis test may verify a rule fails with fail()."""
68*d6050574SRomain Jobredeaux    failure_testing_fake_rule(name = name + "_fake_target", tags = ["manual"])
69*d6050574SRomain Jobredeaux
70*d6050574SRomain Jobredeaux    analysis_test(
71*d6050574SRomain Jobredeaux        name = name,
72*d6050574SRomain Jobredeaux        target = name + "_fake_target",
73*d6050574SRomain Jobredeaux        impl = _test_failure_testing,
74*d6050574SRomain Jobredeaux        expect_failure = True,
75*d6050574SRomain Jobredeaux    )
76*d6050574SRomain Jobredeaux
77*d6050574SRomain Jobredeauxdef _test_failure_testing(env, target):
78*d6050574SRomain Jobredeaux    env.expect.that_target(target).failures().contains_predicate(matching.contains("This rule should never work"))
79*d6050574SRomain Jobredeaux
80*d6050574SRomain Jobredeaux############################################
81*d6050574SRomain Jobredeaux####### fail_unexpected_passing_test #######
82*d6050574SRomain Jobredeaux############################################
83*d6050574SRomain Jobredeaux
84*d6050574SRomain Jobredeauxdef _fail_unexpected_passing_fake_rule(_ctx):
85*d6050574SRomain Jobredeaux    return []
86*d6050574SRomain Jobredeaux
87*d6050574SRomain Jobredeauxfail_unexpected_passing_fake_rule = rule(
88*d6050574SRomain Jobredeaux    implementation = _fail_unexpected_passing_fake_rule,
89*d6050574SRomain Jobredeaux)
90*d6050574SRomain Jobredeaux
91*d6050574SRomain Jobredeaux# @unused # TODO(ilist): add a shell test checking it fails
92*d6050574SRomain Jobredeauxdef test_fail_unexpected_passing(name):
93*d6050574SRomain Jobredeaux    """Test that fails by expecting an error that never occurs."""
94*d6050574SRomain Jobredeaux    fail_unexpected_passing_fake_rule(name = name + "_fake_target", tags = ["manual"])
95*d6050574SRomain Jobredeaux
96*d6050574SRomain Jobredeaux    analysis_test(
97*d6050574SRomain Jobredeaux        name = name,
98*d6050574SRomain Jobredeaux        target = name + "_fake_target",
99*d6050574SRomain Jobredeaux        impl = _test_fail_unexpected_passing,
100*d6050574SRomain Jobredeaux        expect_failure = True,
101*d6050574SRomain Jobredeaux    )
102*d6050574SRomain Jobredeaux
103*d6050574SRomain Jobredeauxdef _test_fail_unexpected_passing(env, target):
104*d6050574SRomain Jobredeaux    env.expect.that_target(target).failures().contains_predicate(matching.contains("Oh no, going to fail"))
105*d6050574SRomain Jobredeaux
106*d6050574SRomain Jobredeaux################################################
107*d6050574SRomain Jobredeaux####### change_setting_with_failure_test #######
108*d6050574SRomain Jobredeaux################################################
109*d6050574SRomain Jobredeauxdef _change_setting_with_failure_fake_rule(ctx):
110*d6050574SRomain Jobredeaux    if ctx.fragments.cpp.minimum_os_version() == "error_error":
111*d6050574SRomain Jobredeaux        fail("unexpected minimum_os_version!!!")
112*d6050574SRomain Jobredeaux    return []
113*d6050574SRomain Jobredeaux
114*d6050574SRomain Jobredeauxchange_setting_with_failure_fake_rule = rule(
115*d6050574SRomain Jobredeaux    implementation = _change_setting_with_failure_fake_rule,
116*d6050574SRomain Jobredeaux    fragments = ["cpp"],
117*d6050574SRomain Jobredeaux)
118*d6050574SRomain Jobredeaux
119*d6050574SRomain Jobredeauxdef test_change_setting_with_failure(name):
120*d6050574SRomain Jobredeaux    change_setting_with_failure_fake_rule(name = name + "_fake_target", tags = ["manual"])
121*d6050574SRomain Jobredeaux
122*d6050574SRomain Jobredeaux    analysis_test(
123*d6050574SRomain Jobredeaux        name = name,
124*d6050574SRomain Jobredeaux        target = name + "_fake_target",
125*d6050574SRomain Jobredeaux        impl = _test_change_setting_with_failure,
126*d6050574SRomain Jobredeaux        expect_failure = True,
127*d6050574SRomain Jobredeaux        config_settings = {
128*d6050574SRomain Jobredeaux            "//command_line_option:minimum_os_version": "error_error",
129*d6050574SRomain Jobredeaux        },
130*d6050574SRomain Jobredeaux    )
131*d6050574SRomain Jobredeaux
132*d6050574SRomain Jobredeauxdef _test_change_setting_with_failure(env, target):
133*d6050574SRomain Jobredeaux    """Test verifying failure while changing configuration."""
134*d6050574SRomain Jobredeaux    env.expect.that_target(target).failures().contains_predicate(
135*d6050574SRomain Jobredeaux        matching.contains("unexpected minimum_os_version!!!"),
136*d6050574SRomain Jobredeaux    )
137*d6050574SRomain Jobredeaux
138*d6050574SRomain Jobredeaux####################################
139*d6050574SRomain Jobredeaux####### inspect_actions_test #######
140*d6050574SRomain Jobredeaux####################################
141*d6050574SRomain Jobredeauxdef _inspect_actions_fake_rule(ctx):
142*d6050574SRomain Jobredeaux    out_file = ctx.actions.declare_file("out.txt")
143*d6050574SRomain Jobredeaux    ctx.actions.run_shell(
144*d6050574SRomain Jobredeaux        command = "echo 'hello' > %s" % out_file.basename,
145*d6050574SRomain Jobredeaux        outputs = [out_file],
146*d6050574SRomain Jobredeaux    )
147*d6050574SRomain Jobredeaux    return [DefaultInfo(files = depset([out_file]))]
148*d6050574SRomain Jobredeaux
149*d6050574SRomain Jobredeauxinspect_actions_fake_rule = rule(implementation = _inspect_actions_fake_rule)
150*d6050574SRomain Jobredeaux
151*d6050574SRomain Jobredeauxdef test_inspect_actions(name):
152*d6050574SRomain Jobredeaux    """Test verifying actions registered by a target."""
153*d6050574SRomain Jobredeaux    inspect_actions_fake_rule(name = name + "_fake_target", tags = ["manual"])
154*d6050574SRomain Jobredeaux
155*d6050574SRomain Jobredeaux    analysis_test(name = name, target = name + "_fake_target", impl = _test_inspect_actions)
156*d6050574SRomain Jobredeaux
157*d6050574SRomain Jobredeauxdef _test_inspect_actions(env, target):
158*d6050574SRomain Jobredeaux    env.expect.that_int(len(target[TestingAspectInfo].actions)).equals(1)
159*d6050574SRomain Jobredeaux    action_output = target[TestingAspectInfo].actions[0].outputs.to_list()[0]
160*d6050574SRomain Jobredeaux    env.expect.that_str(action_output.basename).equals("out.txt")
161*d6050574SRomain Jobredeaux
162*d6050574SRomain Jobredeaux####################################
163*d6050574SRomain Jobredeaux####### inspect_aspect_test #######
164*d6050574SRomain Jobredeaux####################################
165*d6050574SRomain Jobredeaux_AddedByAspectInfo = provider(
166*d6050574SRomain Jobredeaux    doc = "Example provider added by example aspect",
167*d6050574SRomain Jobredeaux    fields = {"value": "(str)"},
168*d6050574SRomain Jobredeaux)
169*d6050574SRomain Jobredeaux
170*d6050574SRomain Jobredeauxdef _example_aspect_impl(_target, _ctx):
171*d6050574SRomain Jobredeaux    return [_AddedByAspectInfo(value = "attached by aspect")]
172*d6050574SRomain Jobredeaux
173*d6050574SRomain Jobredeauxexample_aspect = aspect(implementation = _example_aspect_impl)
174*d6050574SRomain Jobredeaux
175*d6050574SRomain Jobredeauxdef _inspect_aspect_fake_rule(ctx):
176*d6050574SRomain Jobredeaux    out_file = ctx.actions.declare_file("out.txt")
177*d6050574SRomain Jobredeaux    ctx.actions.run_shell(
178*d6050574SRomain Jobredeaux        command = "echo 'hello' > %s" % out_file.basename,
179*d6050574SRomain Jobredeaux        outputs = [out_file],
180*d6050574SRomain Jobredeaux    )
181*d6050574SRomain Jobredeaux    return [DefaultInfo(files = depset([out_file]))]
182*d6050574SRomain Jobredeaux
183*d6050574SRomain Jobredeauxinspect_aspect_fake_rule = rule(implementation = _inspect_aspect_fake_rule)
184*d6050574SRomain Jobredeaux
185*d6050574SRomain Jobredeauxdef test_inspect_aspect(name):
186*d6050574SRomain Jobredeaux    """Test verifying aspect run on a target."""
187*d6050574SRomain Jobredeaux    inspect_aspect_fake_rule(name = name + "_fake_target", tags = ["manual"])
188*d6050574SRomain Jobredeaux
189*d6050574SRomain Jobredeaux    analysis_test(
190*d6050574SRomain Jobredeaux        name = name,
191*d6050574SRomain Jobredeaux        target = name + "_fake_target",
192*d6050574SRomain Jobredeaux        impl = _test_inspect_aspect,
193*d6050574SRomain Jobredeaux        extra_target_under_test_aspects = [example_aspect],
194*d6050574SRomain Jobredeaux    )
195*d6050574SRomain Jobredeaux
196*d6050574SRomain Jobredeauxdef _test_inspect_aspect(env, target):
197*d6050574SRomain Jobredeaux    env.expect.that_str(target[_AddedByAspectInfo].value).equals("attached by aspect")
198*d6050574SRomain Jobredeaux
199*d6050574SRomain Jobredeaux########################################
200*d6050574SRomain Jobredeaux####### inspect_output_dirs_test #######
201*d6050574SRomain Jobredeaux########################################
202*d6050574SRomain Jobredeaux_OutputDirInfo = provider(
203*d6050574SRomain Jobredeaux    doc = "bin_path for inspect_output_dirs_test",
204*d6050574SRomain Jobredeaux    fields = ["bin_path"],
205*d6050574SRomain Jobredeaux)
206*d6050574SRomain Jobredeaux
207*d6050574SRomain Jobredeauxdef _inspect_output_dirs_fake_rule(ctx):
208*d6050574SRomain Jobredeaux    return [_OutputDirInfo(bin_path = ctx.bin_dir.path)]
209*d6050574SRomain Jobredeaux
210*d6050574SRomain Jobredeauxinspect_output_dirs_fake_rule = rule(implementation = _inspect_output_dirs_fake_rule)
211*d6050574SRomain Jobredeaux
212*d6050574SRomain Jobredeaux########################################
213*d6050574SRomain Jobredeaux####### common_attributes_test #######
214*d6050574SRomain Jobredeaux########################################
215*d6050574SRomain Jobredeaux
216*d6050574SRomain Jobredeauxdef _test_common_attributes(name):
217*d6050574SRomain Jobredeaux    native.filegroup(name = name + "_subject")
218*d6050574SRomain Jobredeaux    _toolchain_template_vars(name = name + "_toolchain_template_vars")
219*d6050574SRomain Jobredeaux    analysis_test(
220*d6050574SRomain Jobredeaux        name = name,
221*d6050574SRomain Jobredeaux        impl = _test_common_attributes_impl,
222*d6050574SRomain Jobredeaux        target = name + "_subject",
223*d6050574SRomain Jobredeaux        attr_values = dict(
224*d6050574SRomain Jobredeaux            features = ["some-feature"],
225*d6050574SRomain Jobredeaux            tags = ["taga", "tagb"],
226*d6050574SRomain Jobredeaux            visibility = ["//visibility:private"],
227*d6050574SRomain Jobredeaux            toolchains = [name + "_toolchain_template_vars"],
228*d6050574SRomain Jobredeaux            # An empty list means "compatible with everything"
229*d6050574SRomain Jobredeaux            target_compatible_with = [],
230*d6050574SRomain Jobredeaux        ),
231*d6050574SRomain Jobredeaux    )
232*d6050574SRomain Jobredeaux
233*d6050574SRomain Jobredeauxdef _test_common_attributes_impl(env, target):
234*d6050574SRomain Jobredeaux    _ = target  # @unused
235*d6050574SRomain Jobredeaux    ctx = env.ctx
236*d6050574SRomain Jobredeaux    expect = env.expect
237*d6050574SRomain Jobredeaux
238*d6050574SRomain Jobredeaux    expect.that_collection(ctx.attr.tags).contains_at_least(["taga", "tagb"])
239*d6050574SRomain Jobredeaux
240*d6050574SRomain Jobredeaux    expect.that_collection(ctx.attr.features).contains_exactly(["some-feature"])
241*d6050574SRomain Jobredeaux
242*d6050574SRomain Jobredeaux    expect.that_collection(ctx.attr.visibility).contains_exactly([
243*d6050574SRomain Jobredeaux        Label("//visibility:private"),
244*d6050574SRomain Jobredeaux    ])
245*d6050574SRomain Jobredeaux
246*d6050574SRomain Jobredeaux    expect.that_collection(ctx.attr.target_compatible_with).contains_exactly([])
247*d6050574SRomain Jobredeaux
248*d6050574SRomain Jobredeaux    expanded = ctx.expand_make_variables("cmd", "$(key)", {})
249*d6050574SRomain Jobredeaux    expect.that_str(expanded).equals("value")
250*d6050574SRomain Jobredeaux
251*d6050574SRomain Jobredeauxdef _toolchain_template_vars_impl(ctx):
252*d6050574SRomain Jobredeaux    _ = ctx  # @unused
253*d6050574SRomain Jobredeaux    return [platform_common.TemplateVariableInfo({"key": "value"})]
254*d6050574SRomain Jobredeaux
255*d6050574SRomain Jobredeaux_toolchain_template_vars = rule(implementation = _toolchain_template_vars_impl)
256*d6050574SRomain Jobredeaux
257*d6050574SRomain Jobredeauxdef analysis_test_test_suite(name):
258*d6050574SRomain Jobredeaux    test_suite(
259*d6050574SRomain Jobredeaux        name = name,
260*d6050574SRomain Jobredeaux        tests = [
261*d6050574SRomain Jobredeaux            test_change_setting,
262*d6050574SRomain Jobredeaux            _test_common_attributes,
263*d6050574SRomain Jobredeaux            test_failure_testing,
264*d6050574SRomain Jobredeaux            test_change_setting_with_failure,
265*d6050574SRomain Jobredeaux            test_inspect_actions,
266*d6050574SRomain Jobredeaux            test_inspect_aspect,
267*d6050574SRomain Jobredeaux        ],
268*d6050574SRomain Jobredeaux    )
269