xref: /aosp_15_r20/external/bazelbuild-rules_android/test/utils/asserts.bzl (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
1*9e965d6fSRomain Jobredeaux# Copyright 2020 The Bazel Authors. All rights reserved.
2*9e965d6fSRomain Jobredeaux#
3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License");
4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License.
5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at
6*9e965d6fSRomain Jobredeaux#
7*9e965d6fSRomain Jobredeaux#    http://www.apache.org/licenses/LICENSE-2.0
8*9e965d6fSRomain Jobredeaux#
9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software
10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS,
11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and
13*9e965d6fSRomain Jobredeaux# limitations under the License.
14*9e965d6fSRomain Jobredeaux
15*9e965d6fSRomain Jobredeaux"""Bazel testing library asserts."""
16*9e965d6fSRomain Jobredeaux
17*9e965d6fSRomain Jobredeauxload(
18*9e965d6fSRomain Jobredeaux    "//rules:providers.bzl",
19*9e965d6fSRomain Jobredeaux    "ResourcesNodeInfo",
20*9e965d6fSRomain Jobredeaux    "StarlarkAndroidResourcesInfo",
21*9e965d6fSRomain Jobredeaux)
22*9e965d6fSRomain Jobredeaux
23*9e965d6fSRomain Jobredeaux_ATTRS = dict(
24*9e965d6fSRomain Jobredeaux    expected_default_info = attr.string_list_dict(),
25*9e965d6fSRomain Jobredeaux    expected_java_info = attr.string_list_dict(),
26*9e965d6fSRomain Jobredeaux    expected_proguard_spec_provider = attr.string_list_dict(),
27*9e965d6fSRomain Jobredeaux    expected_starlark_android_resources_info = attr.label(),
28*9e965d6fSRomain Jobredeaux    expected_output_group_info = attr.string_list_dict(),
29*9e965d6fSRomain Jobredeaux    expected_native_libs_info = attr.label(),
30*9e965d6fSRomain Jobredeaux    expected_generated_extension_registry_provider = attr.string_list_dict(),
31*9e965d6fSRomain Jobredeaux)
32*9e965d6fSRomain Jobredeaux
33*9e965d6fSRomain Jobredeauxdef _expected_resources_node_info_impl(ctx):
34*9e965d6fSRomain Jobredeaux    return [
35*9e965d6fSRomain Jobredeaux        ResourcesNodeInfo(
36*9e965d6fSRomain Jobredeaux            label = ctx.attr.label.label,
37*9e965d6fSRomain Jobredeaux            assets = ctx.files.assets,
38*9e965d6fSRomain Jobredeaux            assets_dir = ctx.attr.assets_dir,
39*9e965d6fSRomain Jobredeaux            assets_symbols = ctx.attr.assets_symbols if ctx.attr.assets_symbols else None,
40*9e965d6fSRomain Jobredeaux            compiled_assets = ctx.attr.compiled_assets if ctx.attr.compiled_assets else None,
41*9e965d6fSRomain Jobredeaux            compiled_resources = ctx.attr.compiled_resources if ctx.attr.compiled_resources else None,
42*9e965d6fSRomain Jobredeaux            r_txt = ctx.attr.r_txt if ctx.attr.r_txt else None,
43*9e965d6fSRomain Jobredeaux            manifest = ctx.attr.manifest if ctx.attr.manifest else None,
44*9e965d6fSRomain Jobredeaux            exports_manifest = ctx.attr.exports_manifest,
45*9e965d6fSRomain Jobredeaux        ),
46*9e965d6fSRomain Jobredeaux    ]
47*9e965d6fSRomain Jobredeaux
48*9e965d6fSRomain Jobredeaux_expected_resources_node_info = rule(
49*9e965d6fSRomain Jobredeaux    implementation = _expected_resources_node_info_impl,
50*9e965d6fSRomain Jobredeaux    attrs = dict(
51*9e965d6fSRomain Jobredeaux        label = attr.label(),
52*9e965d6fSRomain Jobredeaux        assets = attr.label_list(allow_files = True),
53*9e965d6fSRomain Jobredeaux        assets_dir = attr.string(),
54*9e965d6fSRomain Jobredeaux        assets_symbols = attr.string(),
55*9e965d6fSRomain Jobredeaux        compiled_assets = attr.string(),
56*9e965d6fSRomain Jobredeaux        compiled_resources = attr.string(),
57*9e965d6fSRomain Jobredeaux        r_txt = attr.string(),
58*9e965d6fSRomain Jobredeaux        manifest = attr.string(),
59*9e965d6fSRomain Jobredeaux        exports_manifest = attr.bool(default = False),
60*9e965d6fSRomain Jobredeaux    ),
61*9e965d6fSRomain Jobredeaux)
62*9e965d6fSRomain Jobredeaux
63*9e965d6fSRomain Jobredeauxdef ExpectedResourcesNodeInfo(
64*9e965d6fSRomain Jobredeaux        label,
65*9e965d6fSRomain Jobredeaux        assets = [],
66*9e965d6fSRomain Jobredeaux        assets_dir = "",
67*9e965d6fSRomain Jobredeaux        assets_symbols = None,
68*9e965d6fSRomain Jobredeaux        compiled_assets = None,
69*9e965d6fSRomain Jobredeaux        compiled_resources = None,
70*9e965d6fSRomain Jobredeaux        r_txt = None,
71*9e965d6fSRomain Jobredeaux        manifest = None,
72*9e965d6fSRomain Jobredeaux        exports_manifest = False,
73*9e965d6fSRomain Jobredeaux        name = "unused"):  # appease linter
74*9e965d6fSRomain Jobredeaux    name = label + str(assets) + assets_dir + str(assets_symbols) + str(compiled_resources) + str(exports_manifest)
75*9e965d6fSRomain Jobredeaux    name = ":" + "".join([c for c in name.elems() if c != ":"])
76*9e965d6fSRomain Jobredeaux
77*9e965d6fSRomain Jobredeaux    _expected_resources_node_info(
78*9e965d6fSRomain Jobredeaux        name = name[1:],
79*9e965d6fSRomain Jobredeaux        label = label,
80*9e965d6fSRomain Jobredeaux        assets = assets,
81*9e965d6fSRomain Jobredeaux        assets_dir = assets_dir,
82*9e965d6fSRomain Jobredeaux        assets_symbols = assets_symbols,
83*9e965d6fSRomain Jobredeaux        compiled_assets = compiled_assets,
84*9e965d6fSRomain Jobredeaux        compiled_resources = compiled_resources,
85*9e965d6fSRomain Jobredeaux        r_txt = r_txt,
86*9e965d6fSRomain Jobredeaux        manifest = manifest,
87*9e965d6fSRomain Jobredeaux        exports_manifest = exports_manifest,
88*9e965d6fSRomain Jobredeaux    )
89*9e965d6fSRomain Jobredeaux    return name
90*9e965d6fSRomain Jobredeaux
91*9e965d6fSRomain Jobredeauxdef _expected_starlark_android_resources_info_impl(ctx):
92*9e965d6fSRomain Jobredeaux    return [
93*9e965d6fSRomain Jobredeaux        StarlarkAndroidResourcesInfo(
94*9e965d6fSRomain Jobredeaux            direct_resources_nodes = [node[ResourcesNodeInfo] for node in ctx.attr.direct_resources_nodes],
95*9e965d6fSRomain Jobredeaux            transitive_resources_nodes = [node[ResourcesNodeInfo] for node in ctx.attr.transitive_resources_nodes],
96*9e965d6fSRomain Jobredeaux            transitive_assets = ctx.attr.transitive_assets,
97*9e965d6fSRomain Jobredeaux            transitive_assets_symbols = ctx.attr.transitive_assets_symbols,
98*9e965d6fSRomain Jobredeaux            transitive_compiled_resources = ctx.attr.transitive_compiled_resources,
99*9e965d6fSRomain Jobredeaux            packages_to_r_txts = ctx.attr.packages_to_r_txts,
100*9e965d6fSRomain Jobredeaux        ),
101*9e965d6fSRomain Jobredeaux    ]
102*9e965d6fSRomain Jobredeaux
103*9e965d6fSRomain Jobredeaux_expected_starlark_android_resources_info = rule(
104*9e965d6fSRomain Jobredeaux    implementation = _expected_starlark_android_resources_info_impl,
105*9e965d6fSRomain Jobredeaux    attrs = dict(
106*9e965d6fSRomain Jobredeaux        direct_resources_nodes = attr.label_list(
107*9e965d6fSRomain Jobredeaux            providers = [ResourcesNodeInfo],
108*9e965d6fSRomain Jobredeaux        ),
109*9e965d6fSRomain Jobredeaux        transitive_resources_nodes = attr.label_list(
110*9e965d6fSRomain Jobredeaux            providers = [ResourcesNodeInfo],
111*9e965d6fSRomain Jobredeaux        ),
112*9e965d6fSRomain Jobredeaux        transitive_assets = attr.string_list(),
113*9e965d6fSRomain Jobredeaux        transitive_assets_symbols = attr.string_list(),
114*9e965d6fSRomain Jobredeaux        transitive_compiled_resources = attr.string_list(),
115*9e965d6fSRomain Jobredeaux        packages_to_r_txts = attr.string_list_dict(),
116*9e965d6fSRomain Jobredeaux    ),
117*9e965d6fSRomain Jobredeaux)
118*9e965d6fSRomain Jobredeaux
119*9e965d6fSRomain Jobredeauxdef ExpectedStarlarkAndroidResourcesInfo(
120*9e965d6fSRomain Jobredeaux        direct_resources_nodes = None,
121*9e965d6fSRomain Jobredeaux        transitive_resources_nodes = [],
122*9e965d6fSRomain Jobredeaux        transitive_assets = [],
123*9e965d6fSRomain Jobredeaux        transitive_assets_symbols = [],
124*9e965d6fSRomain Jobredeaux        transitive_compiled_resources = [],
125*9e965d6fSRomain Jobredeaux        packages_to_r_txts = {},
126*9e965d6fSRomain Jobredeaux        name = "unused"):  # appease linter
127*9e965d6fSRomain Jobredeaux    name = (str(direct_resources_nodes) + str(transitive_resources_nodes) + str(transitive_assets) +
128*9e965d6fSRomain Jobredeaux            str(transitive_assets_symbols) + str(transitive_compiled_resources))
129*9e965d6fSRomain Jobredeaux    name = ":" + "".join([c for c in name.elems() if c not in [":", "\\"]])
130*9e965d6fSRomain Jobredeaux    _expected_starlark_android_resources_info(
131*9e965d6fSRomain Jobredeaux        name = name[1:],
132*9e965d6fSRomain Jobredeaux        direct_resources_nodes = direct_resources_nodes,
133*9e965d6fSRomain Jobredeaux        transitive_resources_nodes = transitive_resources_nodes,
134*9e965d6fSRomain Jobredeaux        transitive_assets = transitive_assets,
135*9e965d6fSRomain Jobredeaux        transitive_assets_symbols = transitive_assets_symbols,
136*9e965d6fSRomain Jobredeaux        transitive_compiled_resources = transitive_compiled_resources,
137*9e965d6fSRomain Jobredeaux        packages_to_r_txts = packages_to_r_txts,
138*9e965d6fSRomain Jobredeaux    )
139*9e965d6fSRomain Jobredeaux    return name
140*9e965d6fSRomain Jobredeaux
141*9e965d6fSRomain Jobredeauxdef _build_expected_resources_node_info(string):
142*9e965d6fSRomain Jobredeaux    parts = string.split(":")
143*9e965d6fSRomain Jobredeaux    if len(parts) != 5:
144*9e965d6fSRomain Jobredeaux        fail("Error: malformed resources_node_info string: %s" % string)
145*9e965d6fSRomain Jobredeaux    return dict(
146*9e965d6fSRomain Jobredeaux        label = parts[0],
147*9e965d6fSRomain Jobredeaux        assets = parts[1].split(",") if parts[1] else [],
148*9e965d6fSRomain Jobredeaux        assets_dir = parts[2],
149*9e965d6fSRomain Jobredeaux        assets_symbols = parts[3],
150*9e965d6fSRomain Jobredeaux        compiled_resources = parts[4],
151*9e965d6fSRomain Jobredeaux    )
152*9e965d6fSRomain Jobredeaux
153*9e965d6fSRomain Jobredeauxdef _expected_android_binary_native_libs_info_impl(ctx):
154*9e965d6fSRomain Jobredeaux    return _ExpectedAndroidBinaryNativeInfo(
155*9e965d6fSRomain Jobredeaux        transitive_native_libs = ctx.attr.transitive_native_libs,
156*9e965d6fSRomain Jobredeaux        native_libs_name = ctx.attr.native_libs_name,
157*9e965d6fSRomain Jobredeaux        native_libs = ctx.attr.native_libs,
158*9e965d6fSRomain Jobredeaux    )
159*9e965d6fSRomain Jobredeaux
160*9e965d6fSRomain Jobredeaux_expected_android_binary_native_libs_info = rule(
161*9e965d6fSRomain Jobredeaux    implementation = _expected_android_binary_native_libs_info_impl,
162*9e965d6fSRomain Jobredeaux    attrs = {
163*9e965d6fSRomain Jobredeaux        "transitive_native_libs": attr.string_list(),
164*9e965d6fSRomain Jobredeaux        "native_libs_name": attr.string(),
165*9e965d6fSRomain Jobredeaux        "native_libs": attr.string_list_dict(),
166*9e965d6fSRomain Jobredeaux    },
167*9e965d6fSRomain Jobredeaux)
168*9e965d6fSRomain Jobredeaux
169*9e965d6fSRomain Jobredeauxdef ExpectedAndroidBinaryNativeLibsInfo(**kwargs):
170*9e965d6fSRomain Jobredeaux    name = "".join([str(kwargs[param]) for param in kwargs])
171*9e965d6fSRomain Jobredeaux    name = ":" + "".join([c for c in name.elems() if c not in [" ", "[", "]", ":", "\\", "{", "\""]])
172*9e965d6fSRomain Jobredeaux    _expected_android_binary_native_libs_info(name = name[1:], **kwargs)
173*9e965d6fSRomain Jobredeaux    return name
174*9e965d6fSRomain Jobredeaux
175*9e965d6fSRomain Jobredeaux_ExpectedAndroidBinaryNativeInfo = provider(
176*9e965d6fSRomain Jobredeaux    "Test provider to compare native deps info",
177*9e965d6fSRomain Jobredeaux    fields = ["native_libs", "native_libs_name", "transitive_native_libs"],
178*9e965d6fSRomain Jobredeaux)
179*9e965d6fSRomain Jobredeaux
180*9e965d6fSRomain Jobredeauxdef _assert_native_libs_info(expected, actual):
181*9e965d6fSRomain Jobredeaux    expected = expected[_ExpectedAndroidBinaryNativeInfo]
182*9e965d6fSRomain Jobredeaux    if expected.native_libs_name:
183*9e965d6fSRomain Jobredeaux        _assert_file(
184*9e965d6fSRomain Jobredeaux            expected.native_libs_name,
185*9e965d6fSRomain Jobredeaux            actual.native_libs_name,
186*9e965d6fSRomain Jobredeaux            "AndroidBinaryNativeInfo.native_libs_name",
187*9e965d6fSRomain Jobredeaux        )
188*9e965d6fSRomain Jobredeaux    for config in expected.native_libs:
189*9e965d6fSRomain Jobredeaux        if config not in actual.native_libs:
190*9e965d6fSRomain Jobredeaux            fail("Error for AndroidBinaryNativeInfo.native_libs: expected key %s was not found" % config)
191*9e965d6fSRomain Jobredeaux        _assert_files(
192*9e965d6fSRomain Jobredeaux            expected.native_libs[config],
193*9e965d6fSRomain Jobredeaux            actual.native_libs[config].to_list(),
194*9e965d6fSRomain Jobredeaux            "AndroidBinaryNativeInfo.native_libs." + config,
195*9e965d6fSRomain Jobredeaux        )
196*9e965d6fSRomain Jobredeaux    _assert_files(
197*9e965d6fSRomain Jobredeaux        expected.transitive_native_libs,
198*9e965d6fSRomain Jobredeaux        actual.transitive_native_libs.to_list(),
199*9e965d6fSRomain Jobredeaux        "AndroidBinaryNativeInfo.transitive_native_libs",
200*9e965d6fSRomain Jobredeaux    )
201*9e965d6fSRomain Jobredeaux
202*9e965d6fSRomain Jobredeauxdef _assert_files(expected_file_names, actual_files, error_msg_field_name):
203*9e965d6fSRomain Jobredeaux    """Asserts that expected file names and actual list of files is equal.
204*9e965d6fSRomain Jobredeaux
205*9e965d6fSRomain Jobredeaux    Args:
206*9e965d6fSRomain Jobredeaux      expected_file_names: The expected names of file basenames (no path),
207*9e965d6fSRomain Jobredeaux      actual_files: The actual list of files produced.
208*9e965d6fSRomain Jobredeaux      error_msg_field_name: The field the actual list of files is from.
209*9e965d6fSRomain Jobredeaux    """
210*9e965d6fSRomain Jobredeaux    actual_file_names = [f.basename for f in actual_files]
211*9e965d6fSRomain Jobredeaux    if sorted(actual_file_names) == sorted(expected_file_names):
212*9e965d6fSRomain Jobredeaux        return
213*9e965d6fSRomain Jobredeaux    fail("""Error for %s, expected and actual file names are not the same:
214*9e965d6fSRomain Jobredeauxexpected file names: %s
215*9e965d6fSRomain Jobredeauxactual files: %s
216*9e965d6fSRomain Jobredeaux""" % (error_msg_field_name, expected_file_names, actual_files))
217*9e965d6fSRomain Jobredeaux
218*9e965d6fSRomain Jobredeauxdef _assert_file_objects(expected_files, actual_files, error_msg_field_name):
219*9e965d6fSRomain Jobredeaux    if sorted([f.basename for f in expected_files]) == sorted([f.basename for f in actual_files]):
220*9e965d6fSRomain Jobredeaux        return
221*9e965d6fSRomain Jobredeaux    fail("""Error for %s, expected and actual file names are not the same:
222*9e965d6fSRomain Jobredeauxexpected file names: %s
223*9e965d6fSRomain Jobredeauxactual files: %s
224*9e965d6fSRomain Jobredeaux""" % (error_msg_field_name, expected_files, actual_files))
225*9e965d6fSRomain Jobredeaux
226*9e965d6fSRomain Jobredeauxdef _assert_file_depset(expected_file_paths, actual_depset, error_msg_field_name, ignore_label_prefix = ""):
227*9e965d6fSRomain Jobredeaux    """Asserts that expected file short_paths and actual depset of files is equal.
228*9e965d6fSRomain Jobredeaux
229*9e965d6fSRomain Jobredeaux    Args:
230*9e965d6fSRomain Jobredeaux      expected_file_paths: The expected file short_paths in depset order.
231*9e965d6fSRomain Jobredeaux      actual_depset: The actual depset produced.
232*9e965d6fSRomain Jobredeaux      error_msg_field_name: The field the actual depset is from.
233*9e965d6fSRomain Jobredeaux      ignore_label_prefix: Path prefix to ignore on actual file short_paths.
234*9e965d6fSRomain Jobredeaux    """
235*9e965d6fSRomain Jobredeaux    actual_paths = []  # = [f.short_path for f in actual_depset.to_list()]
236*9e965d6fSRomain Jobredeaux    for f in actual_depset.to_list():
237*9e965d6fSRomain Jobredeaux        path = f.short_path
238*9e965d6fSRomain Jobredeaux        if path.startswith(ignore_label_prefix):
239*9e965d6fSRomain Jobredeaux            path = path[len(ignore_label_prefix):]
240*9e965d6fSRomain Jobredeaux        actual_paths.append(path)
241*9e965d6fSRomain Jobredeaux
242*9e965d6fSRomain Jobredeaux    if len(expected_file_paths) != len(actual_paths):
243*9e965d6fSRomain Jobredeaux        fail("""Error for %s, expected %d items, got %d items
244*9e965d6fSRomain Jobredeauxexpected: %s
245*9e965d6fSRomain Jobredeauxactual: %s""" % (
246*9e965d6fSRomain Jobredeaux            error_msg_field_name,
247*9e965d6fSRomain Jobredeaux            len(expected_file_paths),
248*9e965d6fSRomain Jobredeaux            len(actual_paths),
249*9e965d6fSRomain Jobredeaux            expected_file_paths,
250*9e965d6fSRomain Jobredeaux            actual_paths,
251*9e965d6fSRomain Jobredeaux        ))
252*9e965d6fSRomain Jobredeaux    for i in range(len(expected_file_paths)):
253*9e965d6fSRomain Jobredeaux        if expected_file_paths[i] != actual_paths[i]:
254*9e965d6fSRomain Jobredeaux            fail("""Error for %s, actual file depset ordering does not match expected ordering:
255*9e965d6fSRomain Jobredeauxexpected ordering: %s
256*9e965d6fSRomain Jobredeauxactual ordering: %s
257*9e965d6fSRomain Jobredeaux""" % (error_msg_field_name, expected_file_paths, actual_paths))
258*9e965d6fSRomain Jobredeaux
259*9e965d6fSRomain Jobredeauxdef _assert_empty(contents, error_msg_field_name):
260*9e965d6fSRomain Jobredeaux    """Asserts that the given is empty."""
261*9e965d6fSRomain Jobredeaux    if len(contents) == 0:
262*9e965d6fSRomain Jobredeaux        return
263*9e965d6fSRomain Jobredeaux    fail("Error %s is not empty: %s" % (error_msg_field_name, contents))
264*9e965d6fSRomain Jobredeaux
265*9e965d6fSRomain Jobredeauxdef _assert_none(content, error_msg_field_name):
266*9e965d6fSRomain Jobredeaux    """Asserts that the given is None."""
267*9e965d6fSRomain Jobredeaux    if content == None:
268*9e965d6fSRomain Jobredeaux        return
269*9e965d6fSRomain Jobredeaux    fail("Error %s is not None: %s" % (error_msg_field_name, content))
270*9e965d6fSRomain Jobredeaux
271*9e965d6fSRomain Jobredeauxdef _assert_java_info(expected, actual):
272*9e965d6fSRomain Jobredeaux    """Asserts that expected matches actual JavaInfo.
273*9e965d6fSRomain Jobredeaux
274*9e965d6fSRomain Jobredeaux    Args:
275*9e965d6fSRomain Jobredeaux      expected: A dict containing fields of a JavaInfo that are compared against
276*9e965d6fSRomain Jobredeaux        the actual given JavaInfo.
277*9e965d6fSRomain Jobredeaux      actual: A JavaInfo.
278*9e965d6fSRomain Jobredeaux    """
279*9e965d6fSRomain Jobredeaux    for key in expected.keys():
280*9e965d6fSRomain Jobredeaux        if not hasattr(actual, key):
281*9e965d6fSRomain Jobredeaux            fail("Actual JavaInfo does not have attribute %s:\n%s" % (key, actual))
282*9e965d6fSRomain Jobredeaux        actual_attr = getattr(actual, key)
283*9e965d6fSRomain Jobredeaux        expected_attr = expected[key]
284*9e965d6fSRomain Jobredeaux
285*9e965d6fSRomain Jobredeaux        # files based asserts.
286*9e965d6fSRomain Jobredeaux        if key in [
287*9e965d6fSRomain Jobredeaux            "compile_jars",
288*9e965d6fSRomain Jobredeaux            "runtime_output_jars",
289*9e965d6fSRomain Jobredeaux            "source_jars",
290*9e965d6fSRomain Jobredeaux            "transitive_compile_time_jars",
291*9e965d6fSRomain Jobredeaux            "transitive_runtime_jars",
292*9e965d6fSRomain Jobredeaux            "transitive_source_jars",
293*9e965d6fSRomain Jobredeaux        ]:
294*9e965d6fSRomain Jobredeaux            files = \
295*9e965d6fSRomain Jobredeaux                actual_attr if type(actual_attr) == "list" else actual_attr.to_list()
296*9e965d6fSRomain Jobredeaux            _assert_files(expected_attr, files, "JavaInfo.%s" % key)
297*9e965d6fSRomain Jobredeaux        else:
298*9e965d6fSRomain Jobredeaux            fail("Error validation of JavaInfo.%s not implemented." % key)
299*9e965d6fSRomain Jobredeaux
300*9e965d6fSRomain Jobredeauxdef _assert_default_info(
301*9e965d6fSRomain Jobredeaux        expected,
302*9e965d6fSRomain Jobredeaux        actual):
303*9e965d6fSRomain Jobredeaux    """Asserts that the DefaultInfo contains the expected values."""
304*9e965d6fSRomain Jobredeaux    if not expected:
305*9e965d6fSRomain Jobredeaux        return
306*9e965d6fSRomain Jobredeaux
307*9e965d6fSRomain Jobredeaux    # DefaultInfo.data_runfiles Assertions
308*9e965d6fSRomain Jobredeaux    _assert_empty(
309*9e965d6fSRomain Jobredeaux        actual.data_runfiles.empty_filenames.to_list(),
310*9e965d6fSRomain Jobredeaux        "DefaultInfo.data_runfiles.empty_filenames",
311*9e965d6fSRomain Jobredeaux    )
312*9e965d6fSRomain Jobredeaux    _assert_files(
313*9e965d6fSRomain Jobredeaux        expected["runfiles"],
314*9e965d6fSRomain Jobredeaux        actual.data_runfiles.files.to_list(),
315*9e965d6fSRomain Jobredeaux        "DefaultInfo.data_runfiles.files",
316*9e965d6fSRomain Jobredeaux    )
317*9e965d6fSRomain Jobredeaux    _assert_empty(
318*9e965d6fSRomain Jobredeaux        actual.data_runfiles.symlinks.to_list(),
319*9e965d6fSRomain Jobredeaux        "DefaultInfo.data_runfiles.symlinks",
320*9e965d6fSRomain Jobredeaux    )
321*9e965d6fSRomain Jobredeaux
322*9e965d6fSRomain Jobredeaux    # DefaultInfo.default_runfile Assertions
323*9e965d6fSRomain Jobredeaux    _assert_empty(
324*9e965d6fSRomain Jobredeaux        actual.default_runfiles.empty_filenames.to_list(),
325*9e965d6fSRomain Jobredeaux        "DefaultInfo.default_runfiles.empty_filenames",
326*9e965d6fSRomain Jobredeaux    )
327*9e965d6fSRomain Jobredeaux    _assert_files(
328*9e965d6fSRomain Jobredeaux        expected["runfiles"],
329*9e965d6fSRomain Jobredeaux        actual.default_runfiles.files.to_list(),
330*9e965d6fSRomain Jobredeaux        "DefaultInfo.default_runfiles.files",
331*9e965d6fSRomain Jobredeaux    )
332*9e965d6fSRomain Jobredeaux    _assert_empty(
333*9e965d6fSRomain Jobredeaux        actual.default_runfiles.symlinks.to_list(),
334*9e965d6fSRomain Jobredeaux        "DefaultInfo.default_runfiles.symlinks",
335*9e965d6fSRomain Jobredeaux    )
336*9e965d6fSRomain Jobredeaux
337*9e965d6fSRomain Jobredeaux    # DefaultInfo.files Assertion
338*9e965d6fSRomain Jobredeaux    _assert_files(
339*9e965d6fSRomain Jobredeaux        expected["files"],
340*9e965d6fSRomain Jobredeaux        actual.files.to_list(),
341*9e965d6fSRomain Jobredeaux        "DefaultInfo.files",
342*9e965d6fSRomain Jobredeaux    )
343*9e965d6fSRomain Jobredeaux
344*9e965d6fSRomain Jobredeaux    # DefaultInfo.files_to_run Assertions
345*9e965d6fSRomain Jobredeaux    _assert_none(
346*9e965d6fSRomain Jobredeaux        actual.files_to_run.executable,
347*9e965d6fSRomain Jobredeaux        "DefaultInfo.files_to_run.executable",
348*9e965d6fSRomain Jobredeaux    )
349*9e965d6fSRomain Jobredeaux    _assert_none(
350*9e965d6fSRomain Jobredeaux        actual.files_to_run.runfiles_manifest,
351*9e965d6fSRomain Jobredeaux        "DefaultInfo.files_to_run.runfiles_manifest",
352*9e965d6fSRomain Jobredeaux    )
353*9e965d6fSRomain Jobredeaux
354*9e965d6fSRomain Jobredeauxdef _assert_proguard_spec_provider(expected, actual):
355*9e965d6fSRomain Jobredeaux    """Asserts that expected matches actual ProguardSpecProvider.
356*9e965d6fSRomain Jobredeaux
357*9e965d6fSRomain Jobredeaux    Args:
358*9e965d6fSRomain Jobredeaux      expected: A dict containing fields of a ProguardSpecProvider that are
359*9e965d6fSRomain Jobredeaux        compared against the actual given ProguardSpecProvider.
360*9e965d6fSRomain Jobredeaux      actual: A ProguardSpecProvider.
361*9e965d6fSRomain Jobredeaux    """
362*9e965d6fSRomain Jobredeaux    for key in expected.keys():
363*9e965d6fSRomain Jobredeaux        if not hasattr(actual, key):
364*9e965d6fSRomain Jobredeaux            fail("Actual ProguardSpecProvider does not have attribute %s:\n%s" % (key, actual))
365*9e965d6fSRomain Jobredeaux        actual_attr = getattr(actual, key)
366*9e965d6fSRomain Jobredeaux        expected_attr = expected[key]
367*9e965d6fSRomain Jobredeaux        if key in ["specs"]:
368*9e965d6fSRomain Jobredeaux            _assert_files(
369*9e965d6fSRomain Jobredeaux                expected_attr,
370*9e965d6fSRomain Jobredeaux                actual_attr.to_list(),
371*9e965d6fSRomain Jobredeaux                "ProguardSpecProvider.%s" % key,
372*9e965d6fSRomain Jobredeaux            )
373*9e965d6fSRomain Jobredeaux        else:
374*9e965d6fSRomain Jobredeaux            fail("Error validation of ProguardSpecProvider.%s not implemented." % key)
375*9e965d6fSRomain Jobredeaux
376*9e965d6fSRomain Jobredeauxdef _assert_string(expected, actual, error_msg):
377*9e965d6fSRomain Jobredeaux    if type(actual) != "string":
378*9e965d6fSRomain Jobredeaux        fail("Error for %s, actual value not of type string, got %s" % (error_msg, type(actual)))
379*9e965d6fSRomain Jobredeaux    if actual != expected:
380*9e965d6fSRomain Jobredeaux        fail("""Error for %s, expected and actual values are not the same:
381*9e965d6fSRomain Jobredeauxexpected value: %s
382*9e965d6fSRomain Jobredeauxactual value: %s
383*9e965d6fSRomain Jobredeaux""" % (error_msg, expected, actual))
384*9e965d6fSRomain Jobredeaux
385*9e965d6fSRomain Jobredeauxdef _assert_file(expected, actual, error_msg_field_name):
386*9e965d6fSRomain Jobredeaux    if actual == None and expected == None:
387*9e965d6fSRomain Jobredeaux        return
388*9e965d6fSRomain Jobredeaux
389*9e965d6fSRomain Jobredeaux    if actual == None and expected != None:
390*9e965d6fSRomain Jobredeaux        fail("Error at %s, expected %s but got None" % (error_msg_field_name, expected))
391*9e965d6fSRomain Jobredeaux
392*9e965d6fSRomain Jobredeaux    if type(actual) != "File":
393*9e965d6fSRomain Jobredeaux        fail("Error at %s, expected a File but got %s" % (error_msg_field_name, type(actual)))
394*9e965d6fSRomain Jobredeaux
395*9e965d6fSRomain Jobredeaux    if actual != None and expected == None:
396*9e965d6fSRomain Jobredeaux        fail("Error at %s, expected None but got %s" % (error_msg_field_name, actual.short_path))
397*9e965d6fSRomain Jobredeaux
398*9e965d6fSRomain Jobredeaux    ignore_label_prefix = actual.owner.package + "/"
399*9e965d6fSRomain Jobredeaux    actual_path = actual.short_path
400*9e965d6fSRomain Jobredeaux    if actual_path.startswith(ignore_label_prefix):
401*9e965d6fSRomain Jobredeaux        actual_path = actual_path[len(ignore_label_prefix):]
402*9e965d6fSRomain Jobredeaux    _assert_string(expected, actual_path, error_msg_field_name)
403*9e965d6fSRomain Jobredeaux
404*9e965d6fSRomain Jobredeauxdef _assert_resources_node_info(expected, actual):
405*9e965d6fSRomain Jobredeaux    if type(actual.label) != "Label":
406*9e965d6fSRomain Jobredeaux        fail("Error for ResourcesNodeInfo.label, expected type Label, actual type is %s" % type(actual.label))
407*9e965d6fSRomain Jobredeaux    _assert_string(expected.label.name, actual.label.name, "ResourcesNodeInfo.label.name")
408*9e965d6fSRomain Jobredeaux
409*9e965d6fSRomain Jobredeaux    if type(actual.assets) != "depset":
410*9e965d6fSRomain Jobredeaux        fail("Error for ResourcesNodeInfo.assets, expected type depset, actual type is %s" % type(actual.assets))
411*9e965d6fSRomain Jobredeaux
412*9e965d6fSRomain Jobredeaux    # TODO(djwhang): Align _assert_file_objects and _assert_file_depset to work
413*9e965d6fSRomain Jobredeaux    # in a similar manner. For now, we will just call to_list() as this field
414*9e965d6fSRomain Jobredeaux    # was list prior to this change.
415*9e965d6fSRomain Jobredeaux    _assert_file_objects(expected.assets, actual.assets.to_list(), "ResourcesNodeInfo.assets")
416*9e965d6fSRomain Jobredeaux
417*9e965d6fSRomain Jobredeaux    _assert_string(expected.assets_dir, actual.assets_dir, "ResourcesNodeInfo.assets_dir")
418*9e965d6fSRomain Jobredeaux
419*9e965d6fSRomain Jobredeaux    _assert_file(
420*9e965d6fSRomain Jobredeaux        expected.assets_symbols,
421*9e965d6fSRomain Jobredeaux        actual.assets_symbols,
422*9e965d6fSRomain Jobredeaux        "ResourcesNodeInfo.assets_symbols",
423*9e965d6fSRomain Jobredeaux    )
424*9e965d6fSRomain Jobredeaux
425*9e965d6fSRomain Jobredeaux    _assert_file(
426*9e965d6fSRomain Jobredeaux        expected.compiled_assets,
427*9e965d6fSRomain Jobredeaux        actual.compiled_assets,
428*9e965d6fSRomain Jobredeaux        "ResourcesNodeInfo.compiled_assets",
429*9e965d6fSRomain Jobredeaux    )
430*9e965d6fSRomain Jobredeaux
431*9e965d6fSRomain Jobredeaux    _assert_file(
432*9e965d6fSRomain Jobredeaux        expected.compiled_resources,
433*9e965d6fSRomain Jobredeaux        actual.compiled_resources,
434*9e965d6fSRomain Jobredeaux        "ResourcesNodeInfo.compiled_resources",
435*9e965d6fSRomain Jobredeaux    )
436*9e965d6fSRomain Jobredeaux
437*9e965d6fSRomain Jobredeaux    _assert_file(
438*9e965d6fSRomain Jobredeaux        expected.r_txt,
439*9e965d6fSRomain Jobredeaux        actual.r_txt,
440*9e965d6fSRomain Jobredeaux        "ResourcesNodeInfo.r_txt",
441*9e965d6fSRomain Jobredeaux    )
442*9e965d6fSRomain Jobredeaux
443*9e965d6fSRomain Jobredeaux    _assert_file(
444*9e965d6fSRomain Jobredeaux        expected.manifest,
445*9e965d6fSRomain Jobredeaux        actual.manifest,
446*9e965d6fSRomain Jobredeaux        "ResourcesNodeInfo.manifest",
447*9e965d6fSRomain Jobredeaux    )
448*9e965d6fSRomain Jobredeaux
449*9e965d6fSRomain Jobredeaux    if type(actual.exports_manifest) != "bool":
450*9e965d6fSRomain Jobredeaux        fail("Error for ResourcesNodeInfo.exports_manifest, expected type bool, actual type is %s" % type(actual.exports_manifest))
451*9e965d6fSRomain Jobredeaux    if expected.exports_manifest != actual.exports_manifest:
452*9e965d6fSRomain Jobredeaux        fail("""Error for ResourcesNodeInfo.exports_manifest, expected and actual values are not the same:
453*9e965d6fSRomain Jobredeauxexpected value: %s
454*9e965d6fSRomain Jobredeauxactual value: %s
455*9e965d6fSRomain Jobredeaux""" % (expected.exports_manifest, actual.exports_manifest))
456*9e965d6fSRomain Jobredeaux
457*9e965d6fSRomain Jobredeauxdef _assert_resources_node_info_depset(expected_resources_node_infos, actual_depset, error_msg):
458*9e965d6fSRomain Jobredeaux    actual_resources_node_infos = actual_depset.to_list()
459*9e965d6fSRomain Jobredeaux    if len(expected_resources_node_infos) != len(actual_resources_node_infos):
460*9e965d6fSRomain Jobredeaux        fail(
461*9e965d6fSRomain Jobredeaux            "Error for StarlarkAndroidResourcesInfo.%s, expected size of list to be %d, got %d:\nExpected: %s\nActual: %s" %
462*9e965d6fSRomain Jobredeaux            (
463*9e965d6fSRomain Jobredeaux                error_msg,
464*9e965d6fSRomain Jobredeaux                len(expected_resources_node_infos),
465*9e965d6fSRomain Jobredeaux                len(actual_resources_node_infos),
466*9e965d6fSRomain Jobredeaux                [node.label for node in expected_resources_node_infos],
467*9e965d6fSRomain Jobredeaux                [node.label for node in actual_resources_node_infos],
468*9e965d6fSRomain Jobredeaux            ),
469*9e965d6fSRomain Jobredeaux        )
470*9e965d6fSRomain Jobredeaux    for i in range(len(actual_resources_node_infos)):
471*9e965d6fSRomain Jobredeaux        _assert_resources_node_info(expected_resources_node_infos[i], actual_resources_node_infos[i])
472*9e965d6fSRomain Jobredeaux
473*9e965d6fSRomain Jobredeauxdef _assert_starlark_android_resources_info(expected, actual, label_under_test):
474*9e965d6fSRomain Jobredeaux    _assert_resources_node_info_depset(
475*9e965d6fSRomain Jobredeaux        expected.direct_resources_nodes,
476*9e965d6fSRomain Jobredeaux        actual.direct_resources_nodes,
477*9e965d6fSRomain Jobredeaux        "direct_resources_nodes",
478*9e965d6fSRomain Jobredeaux    )
479*9e965d6fSRomain Jobredeaux
480*9e965d6fSRomain Jobredeaux    _assert_resources_node_info_depset(
481*9e965d6fSRomain Jobredeaux        expected.transitive_resources_nodes,
482*9e965d6fSRomain Jobredeaux        actual.transitive_resources_nodes,
483*9e965d6fSRomain Jobredeaux        "transitive_resources_nodes",
484*9e965d6fSRomain Jobredeaux    )
485*9e965d6fSRomain Jobredeaux
486*9e965d6fSRomain Jobredeaux    # Use the package from the target under test to shrink actual paths being compared down to the
487*9e965d6fSRomain Jobredeaux    # name of the target.
488*9e965d6fSRomain Jobredeaux    ignore_label_prefix = label_under_test.package + "/"
489*9e965d6fSRomain Jobredeaux
490*9e965d6fSRomain Jobredeaux    _assert_file_depset(
491*9e965d6fSRomain Jobredeaux        expected.transitive_assets,
492*9e965d6fSRomain Jobredeaux        actual.transitive_assets,
493*9e965d6fSRomain Jobredeaux        "StarlarkAndroidResourcesInfo.transitive_assets",
494*9e965d6fSRomain Jobredeaux        ignore_label_prefix,
495*9e965d6fSRomain Jobredeaux    )
496*9e965d6fSRomain Jobredeaux    _assert_file_depset(
497*9e965d6fSRomain Jobredeaux        expected.transitive_assets_symbols,
498*9e965d6fSRomain Jobredeaux        actual.transitive_assets_symbols,
499*9e965d6fSRomain Jobredeaux        "StarlarkAndroidResourcesInfo.transitive_assets_symbols",
500*9e965d6fSRomain Jobredeaux        ignore_label_prefix,
501*9e965d6fSRomain Jobredeaux    )
502*9e965d6fSRomain Jobredeaux    _assert_file_depset(
503*9e965d6fSRomain Jobredeaux        expected.transitive_compiled_resources,
504*9e965d6fSRomain Jobredeaux        actual.transitive_compiled_resources,
505*9e965d6fSRomain Jobredeaux        "StarlarkAndroidResourcesInfo.transitive_compiled_resources",
506*9e965d6fSRomain Jobredeaux        ignore_label_prefix,
507*9e965d6fSRomain Jobredeaux    )
508*9e965d6fSRomain Jobredeaux    for pkg, value in expected.packages_to_r_txts.items():
509*9e965d6fSRomain Jobredeaux        if pkg in actual.packages_to_r_txts:
510*9e965d6fSRomain Jobredeaux            _assert_file_depset(
511*9e965d6fSRomain Jobredeaux                value,
512*9e965d6fSRomain Jobredeaux                actual.packages_to_r_txts[pkg],
513*9e965d6fSRomain Jobredeaux                "StarlarkAndroidResourcesInfo.packages_to_r_txts[%s]" % pkg,
514*9e965d6fSRomain Jobredeaux                ignore_label_prefix,
515*9e965d6fSRomain Jobredeaux            )
516*9e965d6fSRomain Jobredeaux        else:
517*9e965d6fSRomain Jobredeaux            fail("Error for StarlarkAndroidResourceInfo.packages_to_r_txts, expected key %s was not found" % pkg)
518*9e965d6fSRomain Jobredeaux
519*9e965d6fSRomain Jobredeaux_R_CLASS_ATTRS = dict(
520*9e965d6fSRomain Jobredeaux    _r_class_check = attr.label(
521*9e965d6fSRomain Jobredeaux        default = "//test/utils/java/com/google:RClassChecker_deploy.jar",
522*9e965d6fSRomain Jobredeaux        executable = True,
523*9e965d6fSRomain Jobredeaux        allow_files = True,
524*9e965d6fSRomain Jobredeaux        cfg = "exec",
525*9e965d6fSRomain Jobredeaux    ),
526*9e965d6fSRomain Jobredeaux    expected_r_class_fields = attr.string_list(),
527*9e965d6fSRomain Jobredeaux)
528*9e965d6fSRomain Jobredeaux
529*9e965d6fSRomain Jobredeauxdef _assert_output_group_info(expected, actual):
530*9e965d6fSRomain Jobredeaux    for key in expected:
531*9e965d6fSRomain Jobredeaux        actual_attr = getattr(actual, key, None)
532*9e965d6fSRomain Jobredeaux        if actual_attr == None:  # both empty depset and list will fail.
533*9e965d6fSRomain Jobredeaux            fail("%s is not defined in OutputGroupInfo: %s" % (key, actual))
534*9e965d6fSRomain Jobredeaux        _assert_files(
535*9e965d6fSRomain Jobredeaux            expected[key],
536*9e965d6fSRomain Jobredeaux            actual_attr.to_list(),
537*9e965d6fSRomain Jobredeaux            "OutputGroupInfo." + key,
538*9e965d6fSRomain Jobredeaux        )
539*9e965d6fSRomain Jobredeaux
540*9e965d6fSRomain Jobredeauxdef _assert_generated_extension_registry_provider(expected, actual):
541*9e965d6fSRomain Jobredeaux    if expected and not actual:
542*9e965d6fSRomain Jobredeaux        fail("GeneratedExtensionRegistryProvider was expected but not found!")
543*9e965d6fSRomain Jobredeaux    for key in expected:
544*9e965d6fSRomain Jobredeaux        actual_attr = getattr(actual, key, None)
545*9e965d6fSRomain Jobredeaux        if actual_attr == None:  # both empty depset and list will fail.
546*9e965d6fSRomain Jobredeaux            fail("%s is not defined in OutputGroupInfo: %s" % (key, actual))
547*9e965d6fSRomain Jobredeaux
548*9e965d6fSRomain Jobredeaux        _assert_files(
549*9e965d6fSRomain Jobredeaux            expected[key],
550*9e965d6fSRomain Jobredeaux            [actual_attr] if type(actual_attr) != "depset" else actual_attr.to_list(),
551*9e965d6fSRomain Jobredeaux            "GeneratedExtensionRegistryProvider." + key,
552*9e965d6fSRomain Jobredeaux        )
553*9e965d6fSRomain Jobredeaux
554*9e965d6fSRomain Jobredeauxdef _is_suffix_sublist(full, suffixes):
555*9e965d6fSRomain Jobredeaux    """Returns whether suffixes is a sublist of suffixes of full."""
556*9e965d6fSRomain Jobredeaux    for (fi, _) in enumerate(full):
557*9e965d6fSRomain Jobredeaux        sublist_match = True
558*9e965d6fSRomain Jobredeaux        for (si, sv) in enumerate(suffixes):
559*9e965d6fSRomain Jobredeaux            if (fi + si >= len(full)) or not full[fi + si].endswith(sv):
560*9e965d6fSRomain Jobredeaux                sublist_match = False
561*9e965d6fSRomain Jobredeaux                break
562*9e965d6fSRomain Jobredeaux        if sublist_match:
563*9e965d6fSRomain Jobredeaux            return True
564*9e965d6fSRomain Jobredeaux    return False
565*9e965d6fSRomain Jobredeaux
566*9e965d6fSRomain Jobredeauxdef _check_actions(inspect, actions):
567*9e965d6fSRomain Jobredeaux    for mnemonic, expected_argvs in inspect.items():
568*9e965d6fSRomain Jobredeaux        # Action mnemonic is not unique, even in the context of a target, hence
569*9e965d6fSRomain Jobredeaux        # it is necessary to find all actions and compare argv. If there are no
570*9e965d6fSRomain Jobredeaux        # matches among the actions that match the mnemonic, fail and present
571*9e965d6fSRomain Jobredeaux        # all the possible actions that could have matched.
572*9e965d6fSRomain Jobredeaux        mnemonic_matching_actions = []
573*9e965d6fSRomain Jobredeaux        mnemonic_match = False
574*9e965d6fSRomain Jobredeaux        for _, value in actions.by_file.items():
575*9e965d6fSRomain Jobredeaux            # TODO(b/130571505): Remove this after SpawnActionTemplate is supported in Starlark
576*9e965d6fSRomain Jobredeaux            if not (hasattr(value, "mnemonic") and hasattr(value, "argv")):
577*9e965d6fSRomain Jobredeaux                continue
578*9e965d6fSRomain Jobredeaux
579*9e965d6fSRomain Jobredeaux            if mnemonic != value.mnemonic:
580*9e965d6fSRomain Jobredeaux                continue
581*9e965d6fSRomain Jobredeaux            mnemonic_match = True
582*9e965d6fSRomain Jobredeaux
583*9e965d6fSRomain Jobredeaux            if _is_suffix_sublist(value.argv, expected_argvs):
584*9e965d6fSRomain Jobredeaux                # When there is a match, clear the actions stored for displaying
585*9e965d6fSRomain Jobredeaux                # an error messaage.
586*9e965d6fSRomain Jobredeaux                mnemonic_matching_actions = []
587*9e965d6fSRomain Jobredeaux                break
588*9e965d6fSRomain Jobredeaux            else:
589*9e965d6fSRomain Jobredeaux                mnemonic_matching_actions.append(value)
590*9e965d6fSRomain Jobredeaux
591*9e965d6fSRomain Jobredeaux        if not mnemonic_match:
592*9e965d6fSRomain Jobredeaux            fail("%s action not found." % mnemonic)
593*9e965d6fSRomain Jobredeaux        if mnemonic_matching_actions:
594*9e965d6fSRomain Jobredeaux            # If there are mnemonic_matching_actions, then the argvs did not
595*9e965d6fSRomain Jobredeaux            # align. Fail but show the other actions that were created.
596*9e965d6fSRomain Jobredeaux            error_message = (
597*9e965d6fSRomain Jobredeaux                "%s with the following argv not found: %s\nSimilar actions:\n" %
598*9e965d6fSRomain Jobredeaux                (mnemonic, expected_argvs)
599*9e965d6fSRomain Jobredeaux            )
600*9e965d6fSRomain Jobredeaux            for i, action in enumerate(mnemonic_matching_actions):
601*9e965d6fSRomain Jobredeaux                error_message += (
602*9e965d6fSRomain Jobredeaux                    "%d. Progress Message: %s\n   Argv:             %s\n\n" %
603*9e965d6fSRomain Jobredeaux                    (i + 1, action, action.argv)
604*9e965d6fSRomain Jobredeaux                )
605*9e965d6fSRomain Jobredeaux            fail(error_message)
606*9e965d6fSRomain Jobredeaux
607*9e965d6fSRomain Jobredeaux_ACTIONS_ATTRS = dict(
608*9e965d6fSRomain Jobredeaux    inspect_actions = attr.string_list_dict(),
609*9e965d6fSRomain Jobredeaux)
610*9e965d6fSRomain Jobredeaux
611*9e965d6fSRomain Jobredeauxasserts = struct(
612*9e965d6fSRomain Jobredeaux    provider = struct(
613*9e965d6fSRomain Jobredeaux        attrs = _ATTRS,
614*9e965d6fSRomain Jobredeaux        default_info = _assert_default_info,
615*9e965d6fSRomain Jobredeaux        java_info = _assert_java_info,
616*9e965d6fSRomain Jobredeaux        proguard_spec_provider = _assert_proguard_spec_provider,
617*9e965d6fSRomain Jobredeaux        starlark_android_resources_info = _assert_starlark_android_resources_info,
618*9e965d6fSRomain Jobredeaux        output_group_info = _assert_output_group_info,
619*9e965d6fSRomain Jobredeaux        native_libs_info = _assert_native_libs_info,
620*9e965d6fSRomain Jobredeaux        generated_extension_registry_provider = _assert_generated_extension_registry_provider,
621*9e965d6fSRomain Jobredeaux    ),
622*9e965d6fSRomain Jobredeaux    files = _assert_files,
623*9e965d6fSRomain Jobredeaux    r_class = struct(
624*9e965d6fSRomain Jobredeaux        attrs = _R_CLASS_ATTRS,
625*9e965d6fSRomain Jobredeaux    ),
626*9e965d6fSRomain Jobredeaux    actions = struct(
627*9e965d6fSRomain Jobredeaux        attrs = _ACTIONS_ATTRS,
628*9e965d6fSRomain Jobredeaux        check_actions = _check_actions,
629*9e965d6fSRomain Jobredeaux    ),
630*9e965d6fSRomain Jobredeaux)
631