1# Copyright (C) 2022 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("@bazel_skylib//lib:new_sets.bzl", "sets")
16load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
17load("@soong_injection//apex_toolchain:constants.bzl", "default_manifest_version")
18load("//build/bazel/platforms:platform_utils.bzl", "platforms")
19load("//build/bazel/rules:common.bzl", "get_dep_targets")
20load("//build/bazel/rules:prebuilt_file.bzl", "prebuilt_file")
21load("//build/bazel/rules:sh_binary.bzl", "sh_binary")
22load("//build/bazel/rules/aidl:aidl_interface.bzl", "aidl_interface")
23load("//build/bazel/rules/android:android_app_certificate.bzl", "android_app_certificate")
24load("//build/bazel/rules/cc:cc_binary.bzl", "cc_binary")
25load("//build/bazel/rules/cc:cc_library_headers.bzl", "cc_library_headers")
26load("//build/bazel/rules/cc:cc_library_shared.bzl", "cc_library_shared")
27load("//build/bazel/rules/cc:cc_library_static.bzl", "cc_library_static")
28load("//build/bazel/rules/cc:cc_stub_library.bzl", "cc_stub_suite")
29load("//build/bazel/rules/test_common:flags.bzl", "action_flags_present_only_for_mnemonic_test")
30load("//build/bazel/rules/test_common:rules.bzl", "expect_failure_test", "target_under_test_exist_test")
31load(":apex_deps_validation.bzl", "ApexDepsInfo", "apex_dep_infos_to_allowlist_strings")
32load(":apex_info.bzl", "ApexInfo", "ApexMkInfo")
33load(":apex_test_helpers.bzl", "test_apex")
34
35ActionArgsInfo = provider(
36    fields = {
37        "argv": "The link action arguments.",
38    },
39)
40
41def _canned_fs_config_test(ctx):
42    env = analysistest.begin(ctx)
43    actions = analysistest.target_actions(env)
44
45    found_canned_fs_config_action = False
46
47    def pretty_print_list(the_list):
48        if not the_list:
49            return "[]"
50        result = "[\n"
51        for item in the_list:
52            result += "  \"%s\",\n" % item
53        return result + "]"
54
55    if ctx.attr.expected_extra_cat:
56        append_custom_fs_config = [a for a in actions if a.mnemonic == "AppendCustomFsConfig"]
57        asserts.true(env, len(append_custom_fs_config) == 1, "could not find the AppendCustomFsConfig action")
58        a = append_custom_fs_config[0]
59        args = a.argv[2].split(" ")  # first 2 are "/bin/bash" and "-c"
60        asserts.equals(env, args[0], "cat")
61        asserts.true(env, args[1].endswith("_canned_fs_config.txt"))
62        asserts.true(env, args[2].endswith(ctx.attr.expected_extra_cat), "expected %s, but got %s" % (ctx.attr.expected_extra_cat, args[2]))
63        asserts.equals(env, args[3], ">")
64        asserts.true(env, args[4].endswith("_combined_canned_fs_config.txt"))
65
66    for a in actions:
67        if a.mnemonic != "FileWrite":
68            # The canned_fs_config uses ctx.actions.write.
69            continue
70
71        outputs = a.outputs.to_list()
72        if len(outputs) != 1:
73            continue
74        if not outputs[0].basename.endswith("_canned_fs_config.txt"):
75            continue
76
77        found_canned_fs_config_action = True
78
79        # Don't sort -- the order is significant.
80        actual_entries = a.content.split("\n")
81        replacement = "64" if platforms.get_target_bitness(ctx.attr._platform_utils) == 64 else ""
82        expected_entries = [x.replace("{64_OR_BLANK}", replacement) for x in ctx.attr.expected_entries]
83        asserts.equals(env, pretty_print_list(expected_entries), pretty_print_list(actual_entries))
84
85        break
86
87    # Ensures that we actually found the canned_fs_config.txt generation action.
88    asserts.true(env, found_canned_fs_config_action, "did not find the canned fs config generating action")
89
90    return analysistest.end(env)
91
92canned_fs_config_test = analysistest.make(
93    _canned_fs_config_test,
94    attrs = {
95        "expected_entries": attr.string_list(
96            doc = "Expected lines in the canned_fs_config.txt",
97        ),
98        "expected_extra_cat": attr.string(
99            doc = "Filename of the custom canned fs config to be found in the AppendCustomFsConfig action",
100        ),
101        "_platform_utils": attr.label(
102            default = Label("//build/bazel/platforms:platform_utils"),
103        ),
104    },
105)
106
107def _test_canned_fs_config_basic():
108    name = "apex_canned_fs_config_basic"
109    test_name = name + "_test"
110
111    test_apex(name = name)
112
113    canned_fs_config_test(
114        name = test_name,
115        target_under_test = name,
116        expected_entries = [
117            "/ 1000 1000 0755",
118            "/apex_manifest.json 1000 1000 0644",
119            "/apex_manifest.pb 1000 1000 0644",
120            "",  # ends with a newline
121        ],
122    )
123
124    return test_name
125
126def _test_canned_fs_config_custom():
127    name = "apex_canned_fs_config_custom"
128    test_name = name + "_test"
129
130    native.genrule(
131        name = name + ".custom_config",
132        outs = [name + ".custom.config"],
133        cmd = "echo -e \"/2.bin 0 1000 0750\n/1.bin 0 1000 0777\n\" > $@",
134    )
135
136    test_apex(
137        name = name,
138        canned_fs_config = name + "_custom.config",
139    )
140
141    canned_fs_config_test(
142        name = test_name,
143        target_under_test = name,
144        expected_entries = [
145            "/ 1000 1000 0755",
146            "/apex_manifest.json 1000 1000 0644",
147            "/apex_manifest.pb 1000 1000 0644",
148            "",  # ends with a newline
149            # unfortunately, due to bazel analysis not being able to read the
150            # contents of inputs (i.e. dynamic dependencies), we cannot test for
151            # the contents of the custom config here. but, we can test that the
152            # custom config is concatenated in the action command with
153            # 'expected_extra_cat' below.
154        ],
155        expected_extra_cat = name + "_custom.config",
156    )
157
158    return test_name
159
160def _test_canned_fs_config_binaries():
161    name = "apex_canned_fs_config_binaries"
162    test_name = name + "_test"
163
164    sh_binary(
165        name = "bin_sh",
166        srcs = ["bin.sh"],
167        tags = ["manual"],
168    )
169
170    cc_binary(
171        name = "bin_cc",
172        srcs = ["bin.cc"],
173        tags = ["manual"],
174    )
175
176    test_apex(
177        name = name,
178        binaries = ["bin_sh", "bin_cc"],
179    )
180
181    canned_fs_config_test(
182        name = test_name,
183        target_under_test = name,
184        expected_entries = [
185            "/ 1000 1000 0755",
186            "/apex_manifest.json 1000 1000 0644",
187            "/apex_manifest.pb 1000 1000 0644",
188            "/lib{64_OR_BLANK}/libc++.so 1000 1000 0644",
189            "/bin/bin_cc 0 2000 0755",
190            "/bin/bin_sh 0 2000 0755",
191            "/bin 0 2000 0755",
192            "/lib{64_OR_BLANK} 0 2000 0755",
193            "",  # ends with a newline
194        ],
195        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android"],
196    )
197
198    return test_name
199
200def _test_canned_fs_config_native_shared_libs_arm():
201    name = "apex_canned_fs_config_native_shared_libs_arm"
202    test_name = name + "_test"
203
204    cc_library_shared(
205        name = name + "_lib_cc",
206        srcs = [name + "_lib.cc"],
207        tags = ["manual"],
208    )
209
210    cc_library_shared(
211        name = name + "_lib2_cc",
212        srcs = [name + "_lib2.cc"],
213        tags = ["manual"],
214    )
215
216    test_apex(
217        name = name,
218        native_shared_libs_32 = [name + "_lib_cc"],
219        native_shared_libs_64 = [name + "_lib2_cc"],
220    )
221
222    canned_fs_config_test(
223        name = test_name,
224        target_under_test = name,
225        expected_entries = [
226            "/ 1000 1000 0755",
227            "/apex_manifest.json 1000 1000 0644",
228            "/apex_manifest.pb 1000 1000 0644",
229            "/lib/apex_canned_fs_config_native_shared_libs_arm_lib_cc.so 1000 1000 0644",
230            "/lib/libc++.so 1000 1000 0644",
231            "/lib 0 2000 0755",
232            "",  # ends with a newline
233        ],
234        target_compatible_with = ["//build/bazel_common_rules/platforms/arch:arm"],
235    )
236
237    return test_name
238
239def _test_canned_fs_config_native_shared_libs_arm64():
240    name = "apex_canned_fs_config_native_shared_libs_arm64"
241    test_name = name + "_test"
242
243    cc_library_shared(
244        name = name + "_lib_cc",
245        srcs = [name + "_lib.cc"],
246        tags = ["manual"],
247    )
248
249    cc_library_shared(
250        name = name + "_lib2_cc",
251        srcs = [name + "_lib2.cc"],
252        tags = ["manual"],
253    )
254
255    test_apex(
256        name = name,
257        native_shared_libs_32 = [name + "_lib_cc"],
258        native_shared_libs_64 = [name + "_lib2_cc"],
259    )
260
261    canned_fs_config_test(
262        name = test_name,
263        target_under_test = name,
264        expected_entries = [
265            "/ 1000 1000 0755",
266            "/apex_manifest.json 1000 1000 0644",
267            "/apex_manifest.pb 1000 1000 0644",
268            "/lib/apex_canned_fs_config_native_shared_libs_arm64_lib_cc.so 1000 1000 0644",
269            "/lib/libc++.so 1000 1000 0644",
270            "/lib64/apex_canned_fs_config_native_shared_libs_arm64_lib2_cc.so 1000 1000 0644",
271            "/lib64/libc++.so 1000 1000 0644",
272            "/lib 0 2000 0755",
273            "/lib64 0 2000 0755",
274            "",  # ends with a newline
275        ],
276        target_compatible_with = ["//build/bazel_common_rules/platforms/arch:arm64"],
277    )
278
279    return test_name
280
281def _test_canned_fs_config_prebuilts():
282    name = "apex_canned_fs_config_prebuilts"
283    test_name = name + "_test"
284
285    prebuilt_file(
286        name = "file",
287        src = "file.txt",
288        dir = "etc",
289        tags = ["manual"],
290    )
291
292    prebuilt_file(
293        name = "nested_file_in_dir",
294        src = "file2.txt",
295        dir = "etc/nested",
296        tags = ["manual"],
297    )
298
299    prebuilt_file(
300        name = "renamed_file_in_dir",
301        src = "file3.txt",
302        dir = "etc",
303        filename = "renamed_file3.txt",
304        tags = ["manual"],
305    )
306
307    test_apex(
308        name = name,
309        prebuilts = [
310            ":file",
311            ":nested_file_in_dir",
312            ":renamed_file_in_dir",
313        ],
314    )
315
316    canned_fs_config_test(
317        name = test_name,
318        target_under_test = name,
319        expected_entries = [
320            "/ 1000 1000 0755",
321            "/apex_manifest.json 1000 1000 0644",
322            "/apex_manifest.pb 1000 1000 0644",
323            "/etc/file 1000 1000 0644",
324            "/etc/nested/nested_file_in_dir 1000 1000 0644",
325            "/etc/renamed_file3.txt 1000 1000 0644",
326            "/etc 0 2000 0755",
327            "/etc/nested 0 2000 0755",
328            "",  # ends with a newline
329        ],
330    )
331
332    return test_name
333
334def _test_canned_fs_config_prebuilts_sort_order():
335    name = "apex_canned_fs_config_prebuilts_sort_order"
336    test_name = name + "_test"
337
338    prebuilt_file(
339        name = "file_a",
340        src = "file_a.txt",
341        dir = "etc/a",
342        tags = ["manual"],
343    )
344
345    prebuilt_file(
346        name = "file_b",
347        src = "file_b.txt",
348        dir = "etc/b",
349        tags = ["manual"],
350    )
351
352    prebuilt_file(
353        name = "file_a_c",
354        src = "file_a_c.txt",
355        dir = "etc/a/c",
356        tags = ["manual"],
357    )
358
359    test_apex(
360        name = name,
361        prebuilts = [
362            ":file_a",
363            ":file_b",
364            ":file_a_c",
365        ],
366    )
367
368    canned_fs_config_test(
369        name = test_name,
370        target_under_test = name,
371        expected_entries = [
372            "/ 1000 1000 0755",
373            "/apex_manifest.json 1000 1000 0644",
374            "/apex_manifest.pb 1000 1000 0644",
375            "/etc/a/c/file_a_c 1000 1000 0644",
376            "/etc/a/file_a 1000 1000 0644",
377            "/etc/b/file_b 1000 1000 0644",
378            "/etc 0 2000 0755",
379            "/etc/a 0 2000 0755",
380            "/etc/a/c 0 2000 0755",
381            "/etc/b 0 2000 0755",
382            "",  # ends with a newline
383        ],
384    )
385
386    return test_name
387
388def _test_canned_fs_config_runtime_deps():
389    name = "apex_canned_fs_config_runtime_deps"
390    test_name = name + "_test"
391
392    cc_library_shared(
393        name = name + "_runtime_dep_3",
394        srcs = ["lib2.cc"],
395        tags = ["manual"],
396    )
397
398    cc_library_static(
399        name = name + "_static_lib",
400        srcs = ["lib3.cc"],
401        runtime_deps = [name + "_runtime_dep_3"],
402        tags = ["manual"],
403    )
404
405    cc_library_shared(
406        name = name + "_runtime_dep_2",
407        srcs = ["lib2.cc"],
408        tags = ["manual"],
409    )
410
411    cc_library_shared(
412        name = name + "_runtime_dep_1",
413        srcs = ["lib.cc"],
414        runtime_deps = [name + "_runtime_dep_2"],
415        tags = ["manual"],
416    )
417
418    cc_binary(
419        name = name + "_bin_cc",
420        srcs = ["bin.cc"],
421        runtime_deps = [name + "_runtime_dep_1"],
422        deps = [name + "_static_lib"],
423        tags = ["manual"],
424    )
425
426    test_apex(
427        name = name,
428        binaries = [name + "_bin_cc"],
429    )
430
431    canned_fs_config_test(
432        name = test_name,
433        target_under_test = name,
434        expected_entries = [
435            "/ 1000 1000 0755",
436            "/apex_manifest.json 1000 1000 0644",
437            "/apex_manifest.pb 1000 1000 0644",
438            "/lib{64_OR_BLANK}/%s_runtime_dep_1.so 1000 1000 0644" % name,
439            "/lib{64_OR_BLANK}/%s_runtime_dep_2.so 1000 1000 0644" % name,
440            "/lib{64_OR_BLANK}/libc++.so 1000 1000 0644",
441            "/bin/%s_bin_cc 0 2000 0755" % name,
442            "/bin 0 2000 0755",
443            "/lib{64_OR_BLANK} 0 2000 0755",
444            "",  # ends with a newline
445        ],
446        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android"],
447    )
448
449    return test_name
450
451def _apex_manifest_test(ctx):
452    env = analysistest.begin(ctx)
453    actions = analysistest.target_actions(env)
454
455    conv_apex_manifest_action = [a for a in actions if a.mnemonic == "ConvApexManifest"][0]
456
457    apexer_action = [a for a in actions if a.mnemonic == "Apexer"][0]
458    argv = apexer_action.argv[:-1] + apexer_action.argv[-1].split(" ")
459    manifest_index = argv.index("--manifest")
460    manifest_path = argv[manifest_index + 1]
461
462    asserts.equals(
463        env,
464        conv_apex_manifest_action.outputs.to_list()[0].path,
465        manifest_path,
466        "the generated apex manifest protobuf is used as input to apexer",
467    )
468    asserts.true(
469        env,
470        manifest_path.endswith(".pb"),
471        "the generated apex manifest should be a .pb file",
472    )
473
474    if ctx.attr.expected_min_sdk_version != "":
475        flag_index = argv.index("--min_sdk_version")
476        min_sdk_version_argv = argv[flag_index + 1]
477        asserts.equals(
478            env,
479            ctx.attr.expected_min_sdk_version,
480            min_sdk_version_argv,
481        )
482
483    return analysistest.end(env)
484
485apex_manifest_test_attr = dict(
486    impl = _apex_manifest_test,
487    attrs = {
488        "expected_min_sdk_version": attr.string(),
489    },
490)
491
492apex_manifest_test = analysistest.make(
493    **apex_manifest_test_attr
494)
495
496apex_manifest_global_min_sdk_current_test = analysistest.make(
497    config_settings = {
498        "@//build/bazel/rules/apex:unbundled_build_target_sdk_with_api_fingerprint": False,
499    },
500    **apex_manifest_test_attr
501)
502
503apex_manifest_global_min_sdk_override_tiramisu_test = analysistest.make(
504    config_settings = {
505        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_min_sdk_version_override_tiramisu",
506        "@//build/bazel/rules/apex:unbundled_build_target_sdk_with_api_fingerprint": False,
507    },
508    **apex_manifest_test_attr
509)
510
511def _test_apex_manifest():
512    name = "apex_manifest"
513    test_name = name + "_test"
514
515    test_apex(name = name)
516
517    apex_manifest_test(
518        name = test_name,
519        target_under_test = name,
520    )
521
522    return test_name
523
524def _test_apex_manifest_min_sdk_version():
525    name = "apex_manifest_min_sdk_version"
526    test_name = name + "_test"
527
528    test_apex(
529        name = name,
530        min_sdk_version = "30",
531    )
532
533    apex_manifest_test(
534        name = test_name,
535        target_under_test = name,
536        expected_min_sdk_version = "30",
537    )
538
539    return test_name
540
541def _test_apex_manifest_min_sdk_version_current():
542    name = "apex_manifest_min_sdk_version_current"
543    test_name = name + "_test"
544
545    test_apex(
546        name = name,
547        min_sdk_version = "current",
548    )
549
550    # this test verifies min_sdk_version without use_api_fingerprint
551    apex_manifest_global_min_sdk_current_test(
552        name = test_name,
553        target_under_test = name,
554        expected_min_sdk_version = "10000",
555    )
556
557    return test_name
558
559def _test_apex_manifest_min_sdk_version_override():
560    name = "apex_manifest_min_sdk_version_override"
561    test_name = name + "_test"
562
563    test_apex(
564        name = name,
565        min_sdk_version = "30",
566    )
567
568    # this test verifies min_sdk_version without use_api_fingerprint
569    apex_manifest_global_min_sdk_override_tiramisu_test(
570        name = test_name,
571        target_under_test = name,
572        expected_min_sdk_version = "33",  # overriden to 33
573    )
574
575    return test_name
576
577def _apex_native_libs_requires_provides_test(ctx):
578    env = analysistest.begin(ctx)
579    target_under_test = analysistest.target_under_test(env)
580    asserts.equals(
581        env,
582        [t.label for t in ctx.attr.requires_native_libs],  # expected
583        target_under_test[ApexInfo].requires_native_libs,  # actual
584        "did not get expected requires_native_libs",
585    )
586    asserts.equals(
587        env,
588        [t.label for t in ctx.attr.provides_native_libs],
589        target_under_test[ApexInfo].provides_native_libs,
590        "did not get expected provides_native_libs",
591    )
592    asserts.equals(
593        env,
594        ctx.attr.make_modules_to_install,
595        target_under_test[ApexMkInfo].make_modules_to_install,
596        "did not get expected make_modules_to_install",
597    )
598
599    # Compare the argv of the jsonmodify action that updates the apex
600    # manifest with information about provided and required libs.
601    actions = analysistest.target_actions(env)
602    action = [a for a in actions if a.mnemonic == "ApexManifestModify"][0]
603    requires_argv_index = action.argv.index("requireNativeLibs") + 1
604    provides_argv_index = action.argv.index("provideNativeLibs") + 1
605
606    for idx, requires in enumerate(ctx.attr.requires_native_libs):
607        asserts.equals(
608            env,
609            requires.label.name + ".so",  # expected
610            action.argv[requires_argv_index + idx],  # actual
611        )
612
613    for idx, provides in enumerate(ctx.attr.provides_native_libs):
614        asserts.equals(
615            env,
616            provides.label.name + ".so",
617            action.argv[provides_argv_index + idx],
618        )
619
620    return analysistest.end(env)
621
622apex_native_libs_requires_provides_test = analysistest.make(
623    _apex_native_libs_requires_provides_test,
624    attrs = {
625        "make_modules_to_install": attr.string_list(doc = "make module names that should be installed to system"),
626        "provides_argv": attr.string_list(),
627        "provides_native_libs": attr.label_list(doc = "bazel target names of libs provided for dynamic linking"),
628        "requires_argv": attr.string_list(),
629        "requires_native_libs": attr.label_list(doc = "bazel target names of libs required for dynamic linking"),
630    },
631)
632
633def _test_apex_manifest_dependencies_nodep():
634    name = "apex_manifest_dependencies_nodep"
635    test_name = name + "_test"
636
637    cc_library_shared(
638        name = name + "_lib_nodep",
639        stl = "none",
640        system_dynamic_deps = [],
641        tags = ["manual"],
642    )
643
644    test_apex(
645        name = name,
646        native_shared_libs_32 = [name + "_lib_nodep"],
647        native_shared_libs_64 = [name + "_lib_nodep"],
648    )
649
650    apex_native_libs_requires_provides_test(
651        name = test_name,
652        target_under_test = name,
653        requires_native_libs = [],
654        provides_native_libs = [],
655        make_modules_to_install = [],
656    )
657
658    return test_name
659
660def _test_apex_manifest_dependencies_cc_library_shared_bionic_deps():
661    name = "apex_manifest_dependencies_cc_library_shared_bionic_deps"
662    test_name = name + "_test"
663
664    cc_library_shared(
665        name = name + "_lib",
666        # implicit bionic system_dynamic_deps
667        tags = ["manual"],
668    )
669
670    test_apex(
671        name = name,
672        native_shared_libs_32 = [name + "_lib"],
673        native_shared_libs_64 = [name + "_lib"],
674    )
675
676    apex_native_libs_requires_provides_test(
677        name = test_name,
678        target_under_test = name,
679        requires_native_libs = [
680            "//bionic/libc",
681            "//bionic/libdl",
682            "//bionic/libm",
683        ],
684        provides_native_libs = [],
685        make_modules_to_install = [],
686    )
687
688    return test_name
689
690def _test_apex_manifest_dependencies_cc_binary_bionic_deps():
691    name = "apex_manifest_dependencies_cc_binary_bionic_deps"
692    test_name = name + "_test"
693
694    cc_binary(
695        name = name + "_bin",
696        # implicit bionic system_deps
697        tags = ["manual"],
698    )
699
700    test_apex(
701        name = name,
702        binaries = [name + "_bin"],
703    )
704
705    apex_native_libs_requires_provides_test(
706        name = test_name,
707        target_under_test = name,
708        requires_native_libs = [
709            "//bionic/libc",
710            "//bionic/libdl",
711            "//bionic/libm",
712        ],
713        provides_native_libs = [],
714        make_modules_to_install = [],
715    )
716
717    return test_name
718
719def _test_apex_manifest_dependencies_requires():
720    name = "apex_manifest_dependencies_requires"
721    test_name = name + "_test"
722
723    cc_library_shared(
724        name = name + "_lib_with_dep",
725        system_dynamic_deps = [],
726        stl = "none",
727        implementation_dynamic_deps = select({
728            "//build/bazel/rules/apex:android-in_apex": [name + "_libfoo_stub_libs_current"],
729            "//build/bazel/rules/apex:android-non_apex": [name + "_libfoo"],
730        }),
731        tags = ["manual"],
732        stubs_symbol_file = name + "_lib_with_dep" + ".map.txt",
733    )
734
735    native.genrule(
736        name = name + "_genrule_lib_with_dep_map_txt",
737        outs = [name + "_lib_with_dep.map.txt"],
738        cmd = "touch $@",
739        tags = ["manual"],
740    )
741
742    cc_stub_suite(
743        name = name + "_lib_with_dep_stub_libs",
744        soname = name + "_lib_with_dep.so",
745        source_library_label = ":" + name + "_lib_with_dep",
746        symbol_file = name + "_lib_with_dep.map.txt",
747        versions = ["30"],
748    )
749
750    cc_library_shared(
751        name = name + "_libfoo",
752        system_dynamic_deps = [],
753        stl = "none",
754        tags = ["manual"],
755        stubs_symbol_file = name + "_libfoo" + ".map.txt",
756    )
757
758    native.genrule(
759        name = name + "_genrule_libfoo_map_txt",
760        outs = [name + "_libfoo.map.txt"],
761        cmd = "touch $@",
762        tags = ["manual"],
763    )
764
765    cc_stub_suite(
766        name = name + "_libfoo_stub_libs",
767        soname = name + "_libfoo.so",
768        source_library_label = ":" + name + "_libfoo",
769        symbol_file = name + "_libfoo.map.txt",
770        versions = ["30"],
771    )
772
773    test_apex(
774        name = name,
775        native_shared_libs_32 = [name + "_lib_with_dep"],
776        native_shared_libs_64 = [name + "_lib_with_dep"],
777    )
778
779    apex_native_libs_requires_provides_test(
780        name = test_name,
781        target_under_test = name,
782        requires_native_libs = [name + "_libfoo"],
783        provides_native_libs = [name + "_lib_with_dep"],
784        make_modules_to_install = [name + "_libfoo"],
785        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android"],
786    )
787
788    return test_name
789
790def _test_apex_manifest_dependencies_provides():
791    name = "apex_manifest_dependencies_provides"
792    test_name = name + "_test"
793
794    cc_library_shared(
795        name = name + "_libfoo",
796        system_dynamic_deps = [],
797        stl = "none",
798        tags = ["manual"],
799        stubs_symbol_file = name + "_libfoo" + ".map.txt",
800    )
801
802    native.genrule(
803        name = name + "_genrule_libfoo_map_txt",
804        outs = [name + "_libfoo.map.txt"],
805        cmd = "touch $@",
806        tags = ["manual"],
807    )
808
809    cc_stub_suite(
810        name = name + "_libfoo_stub_libs",
811        soname = name + "_libfoo.so",
812        source_library_label = ":" + name + "_libfoo",
813        symbol_file = name + "_libfoo.map.txt",
814        versions = ["30"],
815    )
816
817    test_apex(
818        name = name,
819        native_shared_libs_32 = [name + "_libfoo"],
820        native_shared_libs_64 = [name + "_libfoo"],
821    )
822
823    apex_native_libs_requires_provides_test(
824        name = test_name,
825        target_under_test = name,
826        requires_native_libs = [],
827        provides_native_libs = [name + "_libfoo"],
828        make_modules_to_install = [],
829    )
830
831    return test_name
832
833def _test_apex_manifest_dependencies_selfcontained():
834    name = "apex_manifest_dependencies_selfcontained"
835    test_name = name + "_test"
836
837    cc_library_shared(
838        name = name + "_lib_with_dep",
839        system_dynamic_deps = [],
840        stl = "none",
841        implementation_dynamic_deps = select({
842            "//build/bazel/rules/apex:android-in_apex": [name + "_libfoo_stub_libs_current"],
843            "//build/bazel/rules/apex:android-non_apex": [name + "_libfoo"],
844        }),
845        tags = ["manual"],
846        stubs_symbol_file = name + "_lib_with_dep" + ".map.txt",
847    )
848
849    native.genrule(
850        name = name + "_genrule_lib-with_dep_map_txt",
851        outs = [name + "_lib_with_dep.map.txt"],
852        cmd = "touch $@",
853        tags = ["manual"],
854    )
855
856    cc_stub_suite(
857        name = name + "_lib_with_dep_stub_libs",
858        soname = name + "_lib_with_dep.so",
859        source_library_label = ":" + name + "_lib_with_dep",
860        symbol_file = name + "_lib_with_dep.map.txt",
861        versions = ["30"],
862    )
863
864    cc_library_shared(
865        name = name + "_libfoo",
866        system_dynamic_deps = [],
867        stl = "none",
868        tags = ["manual"],
869        stubs_symbol_file = name + "_libfoo" + ".map.txt",
870    )
871
872    native.genrule(
873        name = name + "_genrule_libfoo_map_txt",
874        outs = [name + "_libfoo.map.txt"],
875        cmd = "touch $@",
876        tags = ["manual"],
877    )
878
879    cc_stub_suite(
880        name = name + "_libfoo_stub_libs",
881        soname = name + "_libfoo.so",
882        source_library_label = ":" + name + "_libfoo",
883        symbol_file = name + "_libfoo.map.txt",
884        versions = ["30"],
885    )
886
887    test_apex(
888        name = name,
889        native_shared_libs_32 = [
890            name + "_lib_with_dep",
891            name + "_libfoo",
892        ],
893        native_shared_libs_64 = [
894            name + "_lib_with_dep",
895            name + "_libfoo",
896        ],
897    )
898
899    apex_native_libs_requires_provides_test(
900        name = test_name,
901        target_under_test = name,
902        requires_native_libs = [],
903        provides_native_libs = [
904            name + "_lib_with_dep",
905            name + "_libfoo",
906        ],
907        make_modules_to_install = [],
908        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android"],
909    )
910
911    return test_name
912
913def _test_apex_manifest_dependencies_cc_binary():
914    name = "apex_manifest_dependencies_cc_binary"
915    test_name = name + "_test"
916
917    cc_binary(
918        name = name + "_bin",
919        stl = "none",
920        system_deps = [],
921        dynamic_deps = [
922            name + "_lib_with_dep",
923        ] + select({
924            "//build/bazel/rules/apex:android-in_apex": [name + "_librequires2_stub_libs_current"],
925            "//build/bazel/rules/apex:android-non_apex": [name + "_librequires2"],
926        }),
927        tags = ["manual"],
928    )
929
930    cc_library_shared(
931        name = name + "_lib_with_dep",
932        system_dynamic_deps = [],
933        stl = "none",
934        implementation_dynamic_deps = select({
935            "//build/bazel/rules/apex:android-in_apex": [name + "_librequires_stub_libs_current"],
936            "//build/bazel/rules/apex:android-non_apex": [name + "_librequires"],
937        }),
938        tags = ["manual"],
939    )
940
941    cc_library_shared(
942        name = name + "_librequires",
943        system_dynamic_deps = [],
944        stl = "none",
945        tags = ["manual"],
946        stubs_symbol_file = name + "_librequires" + ".map.txt",
947    )
948
949    native.genrule(
950        name = name + "_genrule_librequires_map_txt",
951        outs = [name + "_librequires.map.txt"],
952        cmd = "touch $@",
953        tags = ["manual"],
954    )
955
956    cc_stub_suite(
957        name = name + "_librequires_stub_libs",
958        soname = name + "_librequires.so",
959        source_library_label = ":" + name + "_librequires",
960        symbol_file = name + "_librequires.map.txt",
961        versions = ["30"],
962    )
963
964    cc_library_shared(
965        name = name + "_librequires2",
966        system_dynamic_deps = [],
967        stl = "none",
968        tags = ["manual"],
969        stubs_symbol_file = name + "_librequires2.map.txt",
970    )
971
972    native.genrule(
973        name = name + "_genrule_librequires2_map_txt",
974        outs = [name + "_librequires2.map.txt"],
975        cmd = "touch $@",
976        tags = ["manual"],
977    )
978
979    cc_stub_suite(
980        name = name + "_librequires2_stub_libs",
981        soname = name + "_librequires2.so",
982        source_library_label = ":" + name + "_librequires2",
983        symbol_file = name + "_librequires2.map.txt",
984        versions = ["30"],
985    )
986
987    test_apex(
988        name = name,
989        binaries = [name + "_bin"],
990    )
991
992    apex_native_libs_requires_provides_test(
993        name = test_name,
994        target_under_test = name,
995        requires_native_libs = [
996            name + "_librequires",
997            name + "_librequires2",
998        ],
999        make_modules_to_install = [
1000            name + "_librequires",
1001            name + "_librequires2",
1002        ],
1003        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android"],
1004    )
1005
1006    return test_name
1007
1008def _action_args_test(ctx):
1009    env = analysistest.begin(ctx)
1010    actions = analysistest.target_actions(env)
1011
1012    action = [a for a in actions if a.mnemonic == ctx.attr.action_mnemonic][0]
1013    argv = action.argv[:-1] + action.argv[-1].split(" ")
1014    flag_idx = argv.index(ctx.attr.expected_args[0])
1015
1016    for i, expected_arg in enumerate(ctx.attr.expected_args):
1017        asserts.equals(
1018            env,
1019            expected_arg,
1020            argv[flag_idx + i],
1021        )
1022
1023    return analysistest.end(env)
1024
1025_action_args_test_attrs = {
1026    "action_mnemonic": attr.string(mandatory = True),
1027    "expected_args": attr.string_list(mandatory = True),
1028}
1029
1030action_args_test = analysistest.make(
1031    _action_args_test,
1032    attrs = _action_args_test_attrs,
1033)
1034
1035def _test_logging_parent_flag():
1036    name = "logging_parent"
1037    test_name = name + "_test"
1038
1039    test_apex(
1040        name = name,
1041        logging_parent = "logging.parent",
1042    )
1043
1044    action_args_test(
1045        name = test_name,
1046        target_under_test = name,
1047        action_mnemonic = "Apexer",
1048        expected_args = [
1049            "--logging_parent",
1050            "logging.parent",
1051        ],
1052    )
1053
1054    return test_name
1055
1056def _test_default_apex_manifest_version():
1057    name = "default_apex_manifest_version"
1058    test_name = name + "_test"
1059
1060    test_apex(
1061        name = name,
1062    )
1063
1064    action_args_test(
1065        name = test_name,
1066        target_under_test = name,
1067        action_mnemonic = "ApexManifestModify",
1068        expected_args = [
1069            "-se",
1070            "version",
1071            "0",
1072            str(default_manifest_version),
1073        ],
1074    )
1075
1076    return test_name
1077
1078action_args_with_overrides_test = analysistest.make(
1079    _action_args_test,
1080    attrs = _action_args_test_attrs,
1081    config_settings = {
1082        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_with_overrides_and_app_cert",
1083    },
1084)
1085
1086def _test_package_name():
1087    name = "package_name"
1088    test_name = name + "_test"
1089
1090    test_apex(
1091        name = name,
1092        package_name = "my.package.name",
1093    )
1094
1095    action_args_test(
1096        name = test_name,
1097        target_under_test = name,
1098        action_mnemonic = "Apexer",
1099        expected_args = [
1100            "--override_apk_package_name",
1101            "my.package.name",
1102        ],
1103    )
1104
1105    return test_name
1106
1107def _test_package_name_override_from_config():
1108    name = "package_name_override_from_config"
1109    test_name = name + "_test"
1110
1111    test_apex(name = name)
1112
1113    action_args_with_overrides_test(
1114        name = test_name,
1115        target_under_test = name,
1116        action_mnemonic = "Apexer",
1117        expected_args = [
1118            "--override_apk_package_name",
1119            "another.package",
1120        ],
1121    )
1122
1123    return test_name
1124
1125action_args_with_override_apex_manifest_default_version_test = analysistest.make(
1126    _action_args_test,
1127    attrs = _action_args_test_attrs,
1128    # Wouldn't it be nice if it's possible to set the config_setting from the test callsite..
1129    config_settings = {
1130        "@//build/bazel/rules/apex:override_apex_manifest_default_version": "1234567890",
1131    },
1132)
1133
1134def _test_override_apex_manifest_version():
1135    name = "override_apex_manifest_version"
1136    test_name = name + "_test"
1137
1138    test_apex(
1139        name = name,
1140    )
1141
1142    action_args_with_override_apex_manifest_default_version_test(
1143        name = test_name,
1144        target_under_test = name,
1145        action_mnemonic = "ApexManifestModify",
1146        expected_args = [
1147            "-se",
1148            "version",
1149            "0",
1150            "1234567890",
1151        ],
1152    )
1153
1154    return test_name
1155
1156def _file_contexts_args_test(ctx):
1157    env = analysistest.begin(ctx)
1158    actions = analysistest.target_actions(env)
1159
1160    file_contexts_action = [a for a in actions if a.mnemonic == "GenerateApexFileContexts"][0]
1161
1162    # GenerateApexFileContexts is a run_shell action.
1163    # ["/bin/bash", "c", "<args>"]
1164    cmd = file_contexts_action.argv[2]
1165
1166    for expected_arg in ctx.attr.expected_args:
1167        asserts.true(
1168            env,
1169            expected_arg in cmd,
1170            "failed to find '%s' in '%s'" % (expected_arg, cmd),
1171        )
1172
1173    return analysistest.end(env)
1174
1175file_contexts_args_test = analysistest.make(
1176    _file_contexts_args_test,
1177    attrs = {
1178        "expected_args": attr.string_list(mandatory = True),
1179    },
1180)
1181
1182def _test_generate_file_contexts():
1183    name = "apex_manifest_pb_file_contexts"
1184    test_name = name + "_test"
1185
1186    test_apex(
1187        name = name,
1188    )
1189
1190    file_contexts_args_test(
1191        name = test_name,
1192        target_under_test = name,
1193        expected_args = [
1194            "/apex_manifest\\\\.pb u:object_r:system_file:s0",
1195            "/ u:object_r:system_file:s0",
1196        ],
1197    )
1198
1199    return test_name
1200
1201def _min_sdk_version_failure_test_impl(ctx):
1202    env = analysistest.begin(ctx)
1203
1204    asserts.expect_failure(
1205        env,
1206        "min_sdk_version %s cannot be lower than the dep's min_sdk_version %s" %
1207        (ctx.attr.apex_min, ctx.attr.dep_min),
1208    )
1209
1210    return analysistest.end(env)
1211
1212min_sdk_version_failure_test = analysistest.make(
1213    _min_sdk_version_failure_test_impl,
1214    expect_failure = True,
1215    attrs = {
1216        "apex_min": attr.string(),
1217        "dep_min": attr.string(),
1218    },
1219)
1220
1221def _test_min_sdk_version_failure():
1222    name = "min_sdk_version_failure"
1223    test_name = name + "_test"
1224
1225    cc_library_shared(
1226        name = name + "_lib_cc",
1227        srcs = [name + "_lib.cc"],
1228        tags = ["manual"],
1229        min_sdk_version = "32",
1230    )
1231
1232    test_apex(
1233        name = name,
1234        native_shared_libs_32 = [name + "_lib_cc"],
1235        min_sdk_version = "30",
1236    )
1237
1238    min_sdk_version_failure_test(
1239        name = test_name,
1240        target_under_test = name,
1241        apex_min = "30",
1242        dep_min = "32",
1243    )
1244
1245    return test_name
1246
1247def _test_min_sdk_version_failure_transitive():
1248    name = "min_sdk_version_failure_transitive"
1249    test_name = name + "_test"
1250
1251    cc_library_shared(
1252        name = name + "_lib_cc",
1253        dynamic_deps = [name + "_lib2_cc"],
1254        tags = ["manual"],
1255    )
1256
1257    cc_library_shared(
1258        name = name + "_lib2_cc",
1259        srcs = [name + "_lib2.cc"],
1260        tags = ["manual"],
1261        min_sdk_version = "32",
1262    )
1263
1264    test_apex(
1265        name = name,
1266        native_shared_libs_32 = [name + "_lib_cc"],
1267        min_sdk_version = "30",
1268    )
1269
1270    min_sdk_version_failure_test(
1271        name = test_name,
1272        target_under_test = name,
1273        apex_min = "30",
1274        dep_min = "32",
1275    )
1276
1277    return test_name
1278
1279def _apex_certificate_test(ctx):
1280    env = analysistest.begin(ctx)
1281    target_under_test = analysistest.target_under_test(env)
1282    container_key_info = target_under_test[ApexInfo].container_key_info
1283
1284    asserts.equals(env, ctx.attr.expected_pem_path, container_key_info.pem.path)
1285    asserts.equals(env, ctx.attr.expected_pk8_path, container_key_info.pk8.path)
1286
1287    return analysistest.end(env)
1288
1289apex_certificate_test = analysistest.make(
1290    _apex_certificate_test,
1291    attrs = {
1292        "expected_pem_path": attr.string(),
1293        "expected_pk8_path": attr.string(),
1294    },
1295)
1296
1297apex_certificate_with_overrides_test = analysistest.make(
1298    _apex_certificate_test,
1299    attrs = {
1300        "expected_pem_path": attr.string(),
1301        "expected_pk8_path": attr.string(),
1302    },
1303    config_settings = {
1304        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_with_overrides_and_app_cert",
1305    },
1306)
1307
1308def _test_apex_certificate_none():
1309    name = "apex_certificate_none"
1310    test_name = name + "_test"
1311
1312    test_apex(
1313        name = name,
1314        certificate = None,
1315    )
1316
1317    apex_certificate_test(
1318        name = test_name,
1319        target_under_test = name,
1320        expected_pem_path = "build/make/target/product/security/testkey.x509.pem",
1321        expected_pk8_path = "build/make/target/product/security/testkey.pk8",
1322    )
1323
1324    return test_name
1325
1326def _test_apex_certificate_name():
1327    name = "apex_certificate_name"
1328    test_name = name + "_test"
1329
1330    test_apex(
1331        name = name,
1332        certificate = None,
1333        certificate_name = "shared",  # use something other than testkey
1334    )
1335
1336    apex_certificate_test(
1337        name = test_name,
1338        target_under_test = name,
1339        expected_pem_path = "build/make/target/product/security/shared.x509.pem",
1340        expected_pk8_path = "build/make/target/product/security/shared.pk8",
1341    )
1342
1343    return test_name
1344
1345def _test_apex_certificate_label():
1346    name = "apex_certificate_label"
1347    test_name = name + "_test"
1348
1349    android_app_certificate(
1350        name = name + "_cert",
1351        certificate = name,
1352        tags = ["manual"],
1353    )
1354
1355    test_apex(
1356        name = name,
1357        certificate = name + "_cert",
1358    )
1359
1360    apex_certificate_test(
1361        name = test_name,
1362        target_under_test = name,
1363        expected_pem_path = "build/bazel/rules/apex/apex_certificate_label.x509.pem",
1364        expected_pk8_path = "build/bazel/rules/apex/apex_certificate_label.pk8",
1365    )
1366
1367    return test_name
1368
1369def _test_apex_certificate_label_with_overrides():
1370    name = "apex_certificate_label_with_overrides"
1371    test_name = name + "_test"
1372
1373    android_app_certificate(
1374        name = name + "_cert",
1375        certificate = name,
1376        tags = ["manual"],
1377    )
1378
1379    android_app_certificate(
1380        name = name + "_another_cert",
1381        certificate = name + "_another_cert",
1382        tags = ["manual"],
1383    )
1384
1385    test_apex(
1386        name = name,
1387        certificate = name + "_cert",
1388    )
1389
1390    apex_certificate_with_overrides_test(
1391        name = test_name,
1392        target_under_test = name,
1393        expected_pem_path = "build/bazel/rules/apex/apex_certificate_label_with_overrides_another_cert.x509.pem",
1394        expected_pk8_path = "build/bazel/rules/apex/apex_certificate_label_with_overrides_another_cert.pk8",
1395    )
1396
1397    return test_name
1398
1399def _min_sdk_version_apex_inherit_test_impl(ctx):
1400    env = analysistest.begin(ctx)
1401    target_under_test = analysistest.target_under_test(env)
1402    argv = target_under_test[ActionArgsInfo].argv
1403
1404    found = False
1405    for arg in argv:
1406        if arg.startswith("--target="):
1407            found = True
1408            asserts.true(
1409                env,
1410                arg.endswith(ctx.attr.apex_min),
1411                "Incorrect --target flag: %s %s" % (arg, ctx.attr.apex_min),
1412            )
1413
1414    asserts.true(
1415        env,
1416        found,
1417        "No --target flag found: %s" % argv,
1418    )
1419
1420    return analysistest.end(env)
1421
1422def _feature_check_aspect_impl(target, ctx):
1423    rules_propagate_src = [
1424        "_bssl_hash_injection",
1425        "stripped_shared_library",
1426        "versioned_shared_library",
1427    ]
1428
1429    argv = []
1430    if ctx.rule.kind == "cc_shared_library" and target.label.name == ctx.attr.cc_target:
1431        link_actions = [a for a in target.actions if a.mnemonic == "CppLink"]
1432        argv = link_actions[0].argv
1433    elif ctx.rule.kind in rules_propagate_src and hasattr(ctx.rule.attr, "src"):
1434        argv = ctx.rule.attr.src[ActionArgsInfo].argv
1435    elif ctx.rule.kind == "_cc_library_shared_proxy" and hasattr(ctx.rule.attr, "shared"):
1436        argv = ctx.rule.attr.shared[0][ActionArgsInfo].argv
1437    elif ctx.rule.kind == "_apex" and hasattr(ctx.rule.attr, "native_shared_libs_32"):
1438        argv = ctx.rule.attr.native_shared_libs_32[0][ActionArgsInfo].argv
1439
1440    return [
1441        ActionArgsInfo(
1442            argv = argv,
1443        ),
1444    ]
1445
1446feature_check_aspect = aspect(
1447    implementation = _feature_check_aspect_impl,
1448    attrs = {
1449        "cc_target": attr.string(values = [
1450            # This has to mirror the test impl library names
1451            "min_sdk_version_apex_inherit_lib_cc_unstripped",
1452            "min_sdk_version_apex_inherit_override_min_sdk_tiramisu_lib_cc_unstripped",
1453        ]),
1454    },
1455    attr_aspects = ["native_shared_libs_32", "shared", "src"],
1456)
1457
1458min_sdk_version_apex_inherit_test_attrs = dict(
1459    impl = _min_sdk_version_apex_inherit_test_impl,
1460    attrs = {
1461        "apex_min": attr.string(),
1462        "cc_target": attr.string(),
1463    },
1464    # We need to use aspect to examine the dependencies' actions of the apex
1465    # target as the result of the transition, checking the dependencies directly
1466    # using names will give you the info before the transition takes effect.
1467    extra_target_under_test_aspects = [feature_check_aspect],
1468)
1469
1470min_sdk_version_apex_inherit_test = analysistest.make(
1471    **min_sdk_version_apex_inherit_test_attrs
1472)
1473
1474min_sdk_version_apex_inherit_override_min_sdk_tiramisu_test = analysistest.make(
1475    config_settings = {
1476        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_min_sdk_version_override_tiramisu",
1477    },
1478    **min_sdk_version_apex_inherit_test_attrs
1479)
1480
1481def _test_min_sdk_version_apex_inherit():
1482    name = "min_sdk_version_apex_inherit"
1483    test_name = name + "_test"
1484    cc_name = name + "_lib_cc"
1485    apex_min = "29"
1486
1487    cc_library_shared(
1488        name = cc_name,
1489        srcs = [name + "_lib.cc"],
1490        tags = ["manual"],
1491        min_sdk_version = "apex_inherit",
1492    )
1493
1494    test_apex(
1495        name = name,
1496        native_shared_libs_32 = [cc_name],
1497        min_sdk_version = apex_min,
1498    )
1499
1500    min_sdk_version_apex_inherit_test(
1501        name = test_name,
1502        target_under_test = name,
1503        apex_min = apex_min,
1504        cc_target = cc_name + "_unstripped",
1505    )
1506
1507    return test_name
1508
1509def _test_min_sdk_version_apex_inherit_override_min_sdk_tiramisu():
1510    name = "min_sdk_version_apex_inherit_override_min_sdk_tiramisu"
1511    test_name = name + "_test"
1512    cc_name = name + "_lib_cc"
1513
1514    cc_library_shared(
1515        name = cc_name,
1516        srcs = [name + "_lib.cc"],
1517        tags = ["manual"],
1518        min_sdk_version = "apex_inherit",
1519    )
1520
1521    test_apex(
1522        name = name,
1523        native_shared_libs_32 = [cc_name],
1524        min_sdk_version = "29",
1525    )
1526
1527    min_sdk_version_apex_inherit_override_min_sdk_tiramisu_test(
1528        name = test_name,
1529        target_under_test = name,
1530        apex_min = "33",  # the apex transition forced the apex min_sdk_version to be 33
1531        cc_target = cc_name + "_unstripped",
1532    )
1533
1534    return test_name
1535
1536def _apex_provides_base_zip_files_test_impl(ctx):
1537    env = analysistest.begin(ctx)
1538    target_under_test = analysistest.target_under_test(env)
1539
1540    # The particular name of the file isn't important as it just gets zipped with the other apex files for other architectures
1541    asserts.true(
1542        env,
1543        target_under_test[ApexInfo].base_file != None,
1544        "Expected base_file to exist, but found None %s" % target_under_test[ApexInfo].base_file,
1545    )
1546
1547    asserts.equals(
1548        env,
1549        target_under_test[ApexInfo].base_with_config_zip.basename,
1550        # name is important here because the file gets disted and then referenced by name
1551        ctx.attr.apex_name + ".apex-base.zip",
1552        "Expected base file with config zip to have name ending with , but found %s" % target_under_test[ApexInfo].base_with_config_zip.basename,
1553    )
1554
1555    return analysistest.end(env)
1556
1557apex_provides_base_zip_files_test = analysistest.make(
1558    _apex_provides_base_zip_files_test_impl,
1559    attrs = {
1560        "apex_name": attr.string(),
1561    },
1562)
1563
1564def _test_apex_provides_base_zip_files():
1565    name = "apex_provides_base_zip_files"
1566    test_name = name + "_test"
1567
1568    test_apex(name = name)
1569
1570    apex_provides_base_zip_files_test(
1571        name = test_name,
1572        target_under_test = name,
1573        apex_name = name,
1574    )
1575
1576    return test_name
1577
1578def _apex_testonly_with_manifest_test_impl(ctx):
1579    env = analysistest.begin(ctx)
1580    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "Apexer"]
1581    asserts.true(
1582        env,
1583        len(actions) == 1,
1584        "No apexer action found: %s" % actions,
1585    )
1586    argv = actions[0].argv
1587
1588    asserts.false(
1589        env,
1590        "--test_only" in argv,
1591        "Calling apexer with --test_only when manifest file is specified: %s" % argv,
1592    )
1593
1594    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "MarkAndroidManifestTestOnly"]
1595    asserts.true(
1596        env,
1597        len(actions) == 1,
1598        "No MarkAndroidManifestTestOnly action found: %s" % actions,
1599    )
1600    argv = actions[0].argv
1601
1602    asserts.true(
1603        env,
1604        "--test-only" in argv,
1605        "Calling manifest_fixer without --test-only: %s" % argv,
1606    )
1607
1608    return analysistest.end(env)
1609
1610apex_testonly_with_manifest_test = analysistest.make(
1611    _apex_testonly_with_manifest_test_impl,
1612)
1613
1614def _test_apex_testonly_with_manifest():
1615    name = "apex_testonly_with_manifest"
1616    test_name = name + "_test"
1617
1618    cc_library_shared(
1619        name = name + "_lib_cc",
1620        srcs = [name + "_lib.cc"],
1621        tags = ["manual"],
1622        min_sdk_version = "32",
1623    )
1624
1625    test_apex(
1626        name = name,
1627        native_shared_libs_32 = [name + "_lib_cc"],
1628        # This will not cause the validation failure because it is testonly.
1629        min_sdk_version = "30",
1630        testonly = True,
1631        tests = [name + "_cc_test"],
1632        android_manifest = "AndroidManifest.xml",
1633    )
1634
1635    # It shouldn't complain about the min_sdk_version of the dep is too low.
1636    apex_testonly_with_manifest_test(
1637        name = test_name,
1638        target_under_test = name,
1639    )
1640
1641    return test_name
1642
1643def _apex_testonly_without_manifest_test_impl(ctx):
1644    env = analysistest.begin(ctx)
1645    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "Apexer"]
1646    asserts.true(
1647        env,
1648        len(actions) == 1,
1649        "No apexer action found: %s" % actions,
1650    )
1651    argv = actions[0].argv[:-1] + actions[0].argv[-1].split(" ")
1652
1653    asserts.true(
1654        env,
1655        "--test_only" in argv,
1656        "Calling apexer without --test_only when manifest file is not specified: %s" % argv,
1657    )
1658
1659    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "MarkAndroidManifestTestOnly"]
1660    asserts.true(
1661        env,
1662        len(actions) == 0,
1663        "MarkAndroidManifestTestOnly shouldn't be called when manifest file is not specified: %s" % actions,
1664    )
1665
1666    return analysistest.end(env)
1667
1668apex_testonly_without_manifest_test = analysistest.make(
1669    _apex_testonly_without_manifest_test_impl,
1670)
1671
1672def _test_apex_testonly_without_manifest():
1673    name = "apex_testonly_without_manifest"
1674    test_name = name + "_test"
1675
1676    test_apex(
1677        name = name,
1678        testonly = True,
1679    )
1680
1681    apex_testonly_without_manifest_test(
1682        name = test_name,
1683        target_under_test = name,
1684    )
1685
1686    return test_name
1687
1688def _apex_backing_file_test(ctx):
1689    env = analysistest.begin(ctx)
1690    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "FileWrite" and a.outputs.to_list()[0].basename.endswith("_backing.txt")]
1691    asserts.true(
1692        env,
1693        len(actions) == 1,
1694        "No FileWrite action found for creating <apex>_backing.txt file: %s" % actions,
1695    )
1696
1697    asserts.equals(env, ctx.attr.expected_content, actions[0].content)
1698    return analysistest.end(env)
1699
1700apex_backing_file_test = analysistest.make(
1701    _apex_backing_file_test,
1702    attrs = {
1703        "expected_content": attr.string(),
1704    },
1705)
1706
1707def _test_apex_backing_file():
1708    name = "apex_backing_file"
1709    test_name = name + "_test"
1710
1711    cc_library_shared(
1712        name = name + "_lib_cc",
1713        srcs = [name + "_lib.cc"],
1714        tags = ["manual"],
1715    )
1716
1717    test_apex(
1718        name = name,
1719        native_shared_libs_32 = [name + "_lib_cc"],
1720        android_manifest = "AndroidManifest.xml",
1721    )
1722
1723    apex_backing_file_test(
1724        name = test_name,
1725        target_under_test = name,
1726        expected_content = "apex_backing_file_lib_cc.so libc++.so\n",
1727    )
1728
1729    return test_name
1730
1731def _apex_installed_files_test(ctx):
1732    env = analysistest.begin(ctx)
1733    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "GenerateApexInstalledFileList"]
1734    asserts.true(
1735        env,
1736        len(actions) == 1,
1737        "No GenerateApexInstalledFileList action found for creating <apex>-installed-files.txt file: %s" % actions,
1738    )
1739
1740    asserts.equals(
1741        env,
1742        len(ctx.attr.expected_inputs),
1743        len(actions[0].inputs.to_list()),
1744        "Expected inputs length: %d, actual inputs length: %d" % (len(ctx.attr.expected_inputs), len(actions[0].inputs.to_list())),
1745    )
1746    for file in actions[0].inputs.to_list():
1747        asserts.true(
1748            env,
1749            file.basename in ctx.attr.expected_inputs,
1750            "Unexpected input: %s" % file.basename,
1751        )
1752    asserts.equals(env, ctx.attr.expected_output, actions[0].outputs.to_list()[0].basename)
1753    return analysistest.end(env)
1754
1755apex_installed_files_test = analysistest.make(
1756    _apex_installed_files_test,
1757    attrs = {
1758        "expected_inputs": attr.string_list(),
1759        "expected_output": attr.string(),
1760    },
1761)
1762
1763def _test_apex_installed_files():
1764    name = "apex_installed_files"
1765    test_name = name + "_test"
1766
1767    cc_library_shared(
1768        name = name + "_lib_cc",
1769        srcs = [name + "_lib.cc"],
1770        tags = ["manual"],
1771    )
1772
1773    test_apex(
1774        name = name,
1775        native_shared_libs_32 = [name + "_lib_cc"],
1776        android_manifest = "AndroidManifest.xml",
1777    )
1778
1779    apex_installed_files_test(
1780        name = test_name,
1781        target_under_test = name,
1782        expected_inputs = ["libc++.so", "apex_installed_files_lib_cc.so"],
1783        expected_output = "apex_installed_files-installed-files.txt",
1784    )
1785
1786    return test_name
1787
1788def _apex_symbols_used_by_apex_test(ctx):
1789    env = analysistest.begin(ctx)
1790    target_under_test = analysistest.target_under_test(env)
1791    actual = target_under_test[ApexInfo].symbols_used_by_apex
1792
1793    asserts.equals(env, ctx.attr.expected_path, actual.short_path)
1794
1795    return analysistest.end(env)
1796
1797apex_symbols_used_by_apex_test = analysistest.make(
1798    _apex_symbols_used_by_apex_test,
1799    attrs = {
1800        "expected_path": attr.string(),
1801    },
1802)
1803
1804def _test_apex_symbols_used_by_apex():
1805    name = "apex_with_symbols_used_by_apex"
1806    test_name = name + "_test"
1807
1808    test_apex(
1809        name = name,
1810    )
1811
1812    apex_symbols_used_by_apex_test(
1813        name = test_name,
1814        target_under_test = name,
1815        expected_path = "build/bazel/rules/apex/apex_with_symbols_used_by_apex_using.txt",
1816    )
1817
1818    return test_name
1819
1820def _apex_java_symbols_used_by_apex_test(ctx):
1821    env = analysistest.begin(ctx)
1822    target_under_test = analysistest.target_under_test(env)
1823    actual = target_under_test[ApexInfo].java_symbols_used_by_apex
1824
1825    asserts.equals(env, ctx.attr.expected_path, actual.short_path)
1826
1827    return analysistest.end(env)
1828
1829apex_java_symbols_used_by_apex_test = analysistest.make(
1830    _apex_java_symbols_used_by_apex_test,
1831    attrs = {
1832        "expected_path": attr.string(),
1833    },
1834)
1835
1836def _test_apex_java_symbols_used_by_apex():
1837    name = "apex_with_java_symbols_used_by_apex"
1838    test_name = name + "_test"
1839
1840    test_apex(
1841        name = name,
1842    )
1843
1844    apex_java_symbols_used_by_apex_test(
1845        name = test_name,
1846        target_under_test = name,
1847        expected_path = "build/bazel/rules/apex/apex_with_java_symbols_used_by_apex_using.xml",
1848    )
1849
1850    return test_name
1851
1852def _generate_notice_file_test(ctx):
1853    env = analysistest.begin(ctx)
1854    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "GenerateNoticeFile"]
1855    asserts.true(
1856        env,
1857        len(actions) == 1,
1858        "apex target should have a single GenerateNoticeFile action, found %s" % actions,
1859    )
1860    input_json = [f for f in actions[0].inputs.to_list() if f.basename.endswith("_licenses.json")]
1861    asserts.true(
1862        env,
1863        len(input_json) == 1,
1864        "apex GenerateNoticeFile should have a single input *_license.json file, got %s" % input_json,
1865    )
1866    outs = actions[0].outputs.to_list()
1867    asserts.true(
1868        env,
1869        len(outs) == 1 and outs[0].basename == "NOTICE.html.gz",
1870        "apex GenerateNoticeFile should generate a single NOTICE.html.gz file, got %s" % [o.short_path for o in outs],
1871    )
1872    return analysistest.end(env)
1873
1874apex_generate_notice_file_test = analysistest.make(_generate_notice_file_test)
1875
1876def _test_apex_generate_notice_file():
1877    name = "apex_notice_file"
1878    test_name = name + "_test"
1879    test_apex(name = name)
1880    apex_generate_notice_file_test(name = test_name, target_under_test = name)
1881    return test_name
1882
1883def _analysis_success_test(ctx):
1884    env = analysistest.begin(ctx)
1885
1886    # An empty analysis test that just ensures the target_under_test can be analyzed.
1887    return analysistest.end(env)
1888
1889analysis_success_test = analysistest.make(_analysis_success_test)
1890
1891def _test_apex_available():
1892    name = "apex_available"
1893    test_name = name + "_test"
1894    static_lib_name = name + "_lib_cc_static"
1895    lib_headers_name = name + "_lib_cc_headers"
1896
1897    cc_library_static(
1898        name = static_lib_name,
1899        srcs = ["src.cc"],
1900        tags = [
1901            "manual",
1902            "apex_available_checked_manual_for_testing",
1903            # anyapex.
1904            "apex_available=//apex_available:anyapex",
1905        ],
1906    )
1907    cc_library_headers(
1908        name = lib_headers_name,
1909        export_absolute_includes = ["include_dir"],
1910        tags = [
1911            "manual",
1912            "apex_available_checked_manual_for_testing",
1913            "apex_available=//apex_available:anyapex",
1914        ],
1915    )
1916    cc_library_shared(
1917        name = name + "_lib_cc",
1918        srcs = [name + "_lib.cc"],
1919        deps = [
1920            static_lib_name,
1921            lib_headers_name,
1922        ],
1923        tags = [
1924            "manual",
1925            "apex_available_checked_manual_for_testing",
1926            # Explicit name.
1927            "apex_available=" + name,
1928        ],
1929    )
1930    cc_library_shared(
1931        name = name + "_lib2_cc",
1932        srcs = [name + "_lib2.cc"],
1933        tags = [
1934            "manual",
1935            "apex_available_checked_manual_for_testing",
1936            # anyapex.
1937            "apex_available=//apex_available:anyapex",
1938        ],
1939    )
1940    test_apex(
1941        name = name,
1942        native_shared_libs_32 = [
1943            name + "_lib_cc",
1944            name + "_lib2_cc",
1945        ],
1946        android_manifest = "AndroidManifest.xml",
1947    )
1948
1949    analysis_success_test(
1950        name = test_name,
1951        target_under_test = name,
1952    )
1953
1954    return test_name
1955
1956def _test_apex_available_failure():
1957    name = "apex_available_failure"
1958    test_name = name + "_test"
1959    static_lib_name = name + "_lib_cc_static"
1960    lib_headers_name = name + "_lib_cc_headers"
1961
1962    cc_library_static(
1963        name = static_lib_name,
1964        srcs = ["src.cc"],
1965        tags = [
1966            "manual",
1967            "apex_available_checked_manual_for_testing",
1968        ],
1969    )
1970    cc_library_headers(
1971        name = lib_headers_name,
1972        export_absolute_includes = ["include_dir"],
1973        tags = [
1974            "manual",
1975            "apex_available_checked_manual_for_testing",
1976        ],
1977    )
1978    cc_library_shared(
1979        name = name + "_lib_cc",
1980        srcs = [name + "_lib.cc"],
1981        deps = [
1982            static_lib_name,
1983            lib_headers_name,
1984        ],
1985        tags = [
1986            "manual",
1987            "apex_available_checked_manual_for_testing",
1988        ],
1989    )
1990    cc_library_shared(
1991        name = name + "_lib2_cc",
1992        srcs = [name + "_lib2.cc"],
1993        tags = [
1994            "manual",
1995            "apex_available_checked_manual_for_testing",
1996            # anyapex.
1997            "apex_available=//apex_available:anyapex",
1998        ],
1999    )
2000    test_apex(
2001        name = name,
2002        native_shared_libs_32 = [
2003            name + "_lib_cc",
2004            name + "_lib2_cc",
2005        ],
2006        android_manifest = "AndroidManifest.xml",
2007    )
2008
2009    expect_failure_test(
2010        name = test_name,
2011        target_under_test = name,
2012        failure_message = """
2013Error in fail: `@//build/bazel/rules/apex:apex_available_failure` apex has transitive dependencies that do not include the apex in their apex_available tags:
2014    @//build/bazel/rules/apex:apex_available_failure_lib_cc_static; apex_available tags: []
2015    @//build/bazel/rules/apex:apex_available_failure_lib_cc_headers; apex_available tags: []
2016    @//build/bazel/rules/apex:apex_available_failure_lib_cc; apex_available tags: []""",
2017    )
2018    return test_name
2019
2020def _test_apex_available_with_base_apex():
2021    name = "apex_available_with_base_apex"
2022    test_name = name + "_test"
2023
2024    cc_library_shared(
2025        name = name + "_lib_cc",
2026        srcs = [name + "_lib.cc"],
2027        tags = [
2028            "manual",
2029            "apex_available_checked_manual_for_testing",
2030            # Explicit name.
2031            "apex_available=" + name + "_base",
2032        ],
2033    )
2034
2035    cc_library_shared(
2036        name = name + "_lib2_cc",
2037        srcs = [name + "_lib2.cc"],
2038        tags = [
2039            "manual",
2040            "apex_available_checked_manual_for_testing",
2041            # anyapex.
2042            "apex_available=//apex_available:anyapex",
2043        ],
2044    )
2045
2046    test_apex(
2047        name = name,
2048        native_shared_libs_32 = [
2049            name + "_lib_cc",
2050            name + "_lib2_cc",
2051        ],
2052        base_apex_name = name + "_base",
2053        android_manifest = "AndroidManifest.xml",
2054    )
2055
2056    analysis_success_test(
2057        name = test_name,
2058        target_under_test = name,
2059    )
2060
2061    return test_name
2062
2063def _apex_deps_validation_test_impl(ctx):
2064    env = analysistest.begin(ctx)
2065
2066    target_under_test = analysistest.target_under_test(env)
2067    asserts.new_set_equals(
2068        env,
2069        sets.make(ctx.attr.allowed_deps_manifest + ctx.attr._default_apex_deps),
2070        sets.make(apex_dep_infos_to_allowlist_strings(
2071            target_under_test[ApexDepsInfo].transitive_deps.to_list(),
2072        )),
2073    )
2074
2075    return analysistest.end(env)
2076
2077_apex_deps_validation_test = analysistest.make(
2078    _apex_deps_validation_test_impl,
2079    attrs = {
2080        "allowed_deps_manifest": attr.string_list(),
2081        "_default_apex_deps": attr.string_list(
2082            default = [
2083                "libc_llndk_headers(minSdkVersion:apex_inherit)",
2084                "libc_headers(minSdkVersion:apex_inherit)",
2085                "libc++abi(minSdkVersion:apex_inherit)",
2086                "libc++_static(minSdkVersion:apex_inherit)",
2087                "libc++(minSdkVersion:apex_inherit)",
2088                "libc++demangle(minSdkVersion:apex_inherit)",
2089            ],
2090        ),
2091    },
2092    config_settings = {
2093        "@//build/bazel/rules/apex:unsafe_disable_apex_allowed_deps_check": True,
2094    },
2095)
2096
2097def _test_apex_deps_validation():
2098    name = "apex_deps_validation"
2099    test_name = name + "_test"
2100
2101    aidl_interface_name = name + "_aidl_interface"
2102    aidl_interface(
2103        name = aidl_interface_name,
2104        ndk_config = {
2105            "enabled": True,
2106            "min_sdk_version": "28",
2107        },
2108        srcs = ["Foo.aidl"],
2109        tags = [
2110            "manual",
2111            "apex_available_checked_manual_for_testing",
2112            "apex_available=" + name,
2113            "apex_available=//apex_available:platform",
2114        ],
2115    )
2116
2117    specific_apex_available_name = name + "_specific_apex_available"
2118    cc_library_shared(
2119        name = specific_apex_available_name,
2120        srcs = [name + "_lib.cc"],
2121        tags = [
2122            "manual",
2123            "apex_available_checked_manual_for_testing",
2124            "apex_available=" + name,
2125            "apex_available=//apex_available:platform",
2126        ],
2127        min_sdk_version = "30",
2128    )
2129
2130    any_apex_available_name = name + "_any_apex_available"
2131    cc_library_shared(
2132        name = any_apex_available_name,
2133        srcs = [name + "_lib.cc"],
2134        implementation_dynamic_deps = [aidl_interface_name + "-V1-ndk"],
2135        tags = [
2136            "manual",
2137            "apex_available_checked_manual_for_testing",
2138            "apex_available=//apex_available:anyapex",
2139            "apex_available=//apex_available:platform",
2140        ],
2141        min_sdk_version = "30",
2142    )
2143
2144    no_platform_available_name = name + "_no_platform_available"
2145    cc_library_shared(
2146        name = no_platform_available_name,
2147        srcs = [name + "_lib.cc"],
2148        tags = [
2149            "manual",
2150            "apex_available_checked_manual_for_testing",
2151            "apex_available=//apex_available:anyapex",
2152        ],
2153        min_sdk_version = "30",
2154    )
2155
2156    no_platform_available_transitive_dep_name = name + "_no_platform_available_transitive_dep"
2157    cc_library_shared(
2158        name = no_platform_available_transitive_dep_name,
2159        srcs = [name + "_lib.cc"],
2160        tags = [
2161            "manual",
2162            "apex_available_checked_manual_for_testing",
2163            "apex_available=//apex_available:anyapex",
2164        ],
2165        min_sdk_version = "30",
2166    )
2167
2168    platform_available_but_dep_with_no_platform_available_name = name + "_shared_platform_available_but_dep_with_no_platform_available"
2169    cc_library_shared(
2170        name = platform_available_but_dep_with_no_platform_available_name,
2171        srcs = [name + "_lib.cc"],
2172        deps = [no_platform_available_transitive_dep_name],
2173        tags = [
2174            "manual",
2175            "apex_available_checked_manual_for_testing",
2176            "apex_available=//apex_available:anyapex",
2177            "apex_available=//apex_available:platform",
2178        ],
2179        min_sdk_version = "30",
2180    )
2181
2182    test_apex(
2183        name = name,
2184        native_shared_libs_32 = [
2185            specific_apex_available_name,
2186            any_apex_available_name,
2187            no_platform_available_name,
2188            platform_available_but_dep_with_no_platform_available_name,
2189        ],
2190        android_manifest = "AndroidManifest.xml",
2191        min_sdk_version = "30",
2192    )
2193
2194    _apex_deps_validation_test(
2195        name = test_name,
2196        target_under_test = name,
2197        allowed_deps_manifest = [
2198            specific_apex_available_name + "(minSdkVersion:30)",
2199            any_apex_available_name + "(minSdkVersion:30)",
2200            platform_available_but_dep_with_no_platform_available_name + "(minSdkVersion:30)",
2201            aidl_interface_name + "-V1-ndk(minSdkVersion:28)",
2202            "jni_headers(minSdkVersion:29)",
2203        ],
2204        tags = ["manual"],
2205    )
2206
2207    return test_name
2208
2209_MarchInfo = provider(fields = {"march": "list of march values found in the cc deps of this apex"})
2210
2211def _apex_transition_test(ctx):
2212    env = analysistest.begin(ctx)
2213    target_under_test = analysistest.target_under_test(env)
2214    march_values = target_under_test[_MarchInfo].march
2215
2216    asserts.equals(env, ctx.attr.expected, march_values.to_list())
2217
2218    return analysistest.end(env)
2219
2220def _cc_compile_test_aspect_impl(target, ctx):
2221    transitive_march = []
2222    for attr_deps in get_dep_targets(ctx.rule.attr, predicate = lambda target: _MarchInfo in target).values():
2223        for dep in attr_deps:
2224            transitive_march.append(dep[_MarchInfo].march)
2225    march_values = []
2226    if (target.label.name).startswith("apex_transition_lib"):
2227        for a in target.actions:
2228            if a.mnemonic == "CppCompile":
2229                march_values += [arg for arg in a.argv if "march" in arg]
2230    return [
2231        _MarchInfo(
2232            march = depset(
2233                direct = march_values,
2234                transitive = transitive_march,
2235            ),
2236        ),
2237    ]
2238
2239_cc_compile_test_aspect = aspect(
2240    implementation = _cc_compile_test_aspect_impl,
2241    attr_aspects = ["*"],
2242)
2243
2244apex_transition_test = analysistest.make(
2245    _apex_transition_test,
2246    attrs = {
2247        "expected": attr.string_list(),
2248    },
2249    extra_target_under_test_aspects = [_cc_compile_test_aspect],
2250)
2251
2252def _test_apex_transition():
2253    name = "apex_transition"
2254    test_name = name + "_test"
2255
2256    cc_library_shared(
2257        name = name + "_lib_cc",
2258        srcs = [name + "_lib.cc"],
2259        tags = ["manual"],
2260    )
2261
2262    cc_library_shared(
2263        name = name + "_lib2_cc",
2264        srcs = [name + "_lib2.cc"],
2265        tags = ["manual"],
2266    )
2267
2268    test_apex(
2269        name = name,
2270        native_shared_libs_32 = [name + "_lib_cc"],
2271        native_shared_libs_64 = [name + "_lib2_cc"],
2272        android_manifest = "AndroidManifest.xml",
2273    )
2274
2275    apex_transition_test(
2276        name = test_name + "_32",
2277        target_under_test = name,
2278        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android", "//build/bazel_common_rules/platforms/arch:arm"],
2279        expected = ["-march=armv7-a"],
2280    )
2281
2282    apex_transition_test(
2283        name = test_name + "_64",
2284        target_under_test = name,
2285        target_compatible_with = ["//build/bazel_common_rules/platforms/os:android", "//build/bazel_common_rules/platforms/arch:arm64"],
2286        expected = ["-march=armv8-a"],
2287    )
2288
2289    return [test_name + "_32", test_name + "_64"]
2290
2291def _test_no_static_linking_for_stubs_lib():
2292    name = "no_static_linking_for_stubs_lib"
2293    test_name = name + "_test"
2294
2295    cc_library_static(
2296        name = name + "_static_unavailable_to_apex",
2297        tags = [
2298            "apex_available_checked_manual_for_testing",
2299            "manual",
2300        ],
2301    )
2302
2303    cc_library_shared(
2304        name = name + "_shared",
2305        deps = [name + "_static_unavailable_to_apex"],
2306        tags = [
2307            "apex_available=" + name,
2308            "apex_available_checked_manual_for_testing",
2309            "manual",
2310        ],
2311    )
2312
2313    test_apex(
2314        name = name,
2315        native_shared_libs_32 = [name + "_shared"],
2316    )
2317
2318    expect_failure_test(
2319        name = test_name,
2320        target_under_test = name,
2321        failure_message = """
2322Error in fail: `@//build/bazel/rules/apex:no_static_linking_for_stubs_lib` apex has transitive dependencies that do not include the apex in their apex_available tags:
2323    @//build/bazel/rules/apex:no_static_linking_for_stubs_lib_static_unavailable_to_apex; apex_available tags: []""",
2324    )
2325
2326    return test_name
2327
2328def _test_directly_included_stubs_lib_with_indirectly_static_variant():
2329    name = "directly_included_stubs_lib_with_indirectly_static_variant"
2330    test_name = name + "_test"
2331
2332    cc_binary(
2333        name = name + "bar",
2334        deps = [name + "_shared_bp2build_cc_library_static"],
2335        tags = [
2336            "apex_available=" + name,
2337            "apex_available_checked_manual_for_testing",
2338            "manual",
2339        ],
2340    )
2341
2342    cc_library_shared(
2343        name = name + "foo",
2344        deps = [name + "_shared_bp2build_cc_library_static"],
2345        tags = [
2346            "apex_available=" + name,
2347            "apex_available_checked_manual_for_testing",
2348            "manual",
2349        ],
2350    )
2351
2352    # This target is unavailable to apex but is allowed to be required by
2353    # cc_binary bar and cc_library_shared foo because its shared variant
2354    # is directly in the apex
2355    cc_library_static(
2356        name = name + "_shared_bp2build_cc_library_static",
2357        tags = [
2358            "apex_available_checked_manual_for_testing",
2359            "manual",
2360        ],
2361    )
2362
2363    cc_library_shared(
2364        name = name + "_shared",
2365        tags = [
2366            "apex_available=" + name,
2367            "apex_available_checked_manual_for_testing",
2368            "manual",
2369        ],
2370    )
2371
2372    test_apex(
2373        name = name,
2374        native_shared_libs_32 = [name + "_shared", name + "foo"],
2375        binaries = [name + "bar"],
2376    )
2377
2378    target_under_test_exist_test(
2379        name = test_name,
2380        target_under_test = name,
2381    )
2382
2383    return test_name
2384
2385def cc_library_shared_with_stubs(name):
2386    cc_library_shared(
2387        name = name,
2388        system_dynamic_deps = [],
2389        stl = "none",
2390        tags = ["manual"],
2391        stubs_symbol_file = name + ".map.txt",
2392    )
2393
2394    native.genrule(
2395        name = name + "_genrule_map_txt",
2396        outs = [name + ".map.txt"],
2397        cmd = "touch $@",
2398        tags = ["manual"],
2399    )
2400
2401    cc_stub_suite(
2402        name = name + "_stub_libs",
2403        soname = name + ".so",
2404        source_library_label = ":" + name,
2405        symbol_file = name + ".map.txt",
2406        versions = ["30"],
2407        tags = ["manual"],
2408    )
2409
2410    return [
2411        name,
2412        name + "_stub_libs",
2413    ]
2414
2415def _apex_in_unbundled_build_test(ctx):
2416    env = analysistest.begin(ctx)
2417    target_under_test = analysistest.target_under_test(env)
2418    mk_modules_to_install = target_under_test[ApexMkInfo].make_modules_to_install
2419    asserts.true(
2420        env,
2421        "apex_in_unbundled_build_libfoo" not in mk_modules_to_install,
2422        "stub libs apex_in_unbundled_build_libfoo should not be propagated " +
2423        "to make for installation in unbundled mode",
2424    )
2425    return analysistest.end(env)
2426
2427apex_in_unbundled_build_test = analysistest.make(
2428    _apex_in_unbundled_build_test,
2429    config_settings = {
2430        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_unbundled_build",
2431    },
2432)
2433
2434def _test_apex_in_unbundled_build():
2435    name = "apex_in_unbundled_build"
2436    test_name = name + "_test"
2437
2438    [cc_library_shared_name, cc_stub_suite_name] = cc_library_shared_with_stubs(name + "_libfoo")
2439
2440    cc_binary(
2441        name = name + "_bar",
2442        tags = [
2443            "apex_available=" + name,
2444            "apex_available_checked_manual_for_testing",
2445            "manual",
2446        ],
2447        dynamic_deps = select({
2448            "//build/bazel/rules/apex:android-in_apex": [cc_stub_suite_name + "_current"],
2449            "//build/bazel/rules/apex:android-non_apex": [cc_library_shared_name],
2450        }),
2451    )
2452
2453    test_apex(
2454        name = name,
2455        binaries = [name + "_bar"],
2456    )
2457
2458    apex_in_unbundled_build_test(
2459        name = test_name,
2460        target_under_test = name,
2461    )
2462
2463    return test_name
2464
2465def _apex_in_bundled_build_test(ctx):
2466    env = analysistest.begin(ctx)
2467    target_under_test = analysistest.target_under_test(env)
2468    mk_modules_to_install = target_under_test[ApexMkInfo].make_modules_to_install
2469    asserts.true(
2470        env,
2471        "apex_in_bundled_build_libfoo" in mk_modules_to_install,
2472        "stub libs apex_in_unbundled_build_libfoo should be propagated " +
2473        "to make for installation in unbundled mode",
2474    )
2475
2476    return analysistest.end(env)
2477
2478apex_in_bundled_build_test = analysistest.make(
2479    _apex_in_bundled_build_test,
2480    config_settings = {
2481        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing",
2482    },
2483)
2484
2485def _test_apex_in_bundled_build():
2486    name = "apex_in_bundled_build"
2487    test_name = name + "_test"
2488
2489    [cc_library_shared_name, cc_stub_suite_name] = cc_library_shared_with_stubs(name + "_libfoo")
2490
2491    cc_binary(
2492        name = name + "_bar",
2493        tags = [
2494            "apex_available=" + name,
2495            "apex_available_checked_manual_for_testing",
2496            "manual",
2497        ],
2498        dynamic_deps = select({
2499            "//build/bazel/rules/apex:android-in_apex": [cc_stub_suite_name + "_current"],
2500            "//build/bazel/rules/apex:android-non_apex": [cc_library_shared_name],
2501        }),
2502    )
2503
2504    test_apex(
2505        name = name,
2506        binaries = [name + "_bar"],
2507    )
2508
2509    apex_in_bundled_build_test(
2510        name = test_name,
2511        target_under_test = name,
2512    )
2513
2514    return test_name
2515
2516def _apex_compression_test(ctx):
2517    env = analysistest.begin(ctx)
2518
2519    target = analysistest.target_under_test(env)
2520    asserts.true(
2521        env,
2522        target[ApexInfo].signed_compressed_output != None,
2523        "ApexInfo.signed_compressed_output should exist from compressible apex",
2524    )
2525
2526    return analysistest.end(env)
2527
2528apex_compression_test = analysistest.make(
2529    _apex_compression_test,
2530    config_settings = {
2531        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing",
2532    },
2533)
2534
2535def _test_apex_compression():
2536    name = "apex_compression"
2537    test_name = name + "_test"
2538
2539    test_apex(
2540        name = name,
2541        compressible = True,
2542    )
2543
2544    apex_compression_test(
2545        name = test_name,
2546        target_under_test = name,
2547    )
2548
2549    return test_name
2550
2551def _apex_no_compression_test(ctx):
2552    env = analysistest.begin(ctx)
2553
2554    target = analysistest.target_under_test(env)
2555    asserts.true(
2556        env,
2557        target[ApexInfo].signed_compressed_output == None,
2558        "ApexInfo.signed_compressed_output should not exist when compression_enabled is not specified",
2559    )
2560
2561    return analysistest.end(env)
2562
2563apex_no_compression_test = analysistest.make(
2564    _apex_no_compression_test,
2565    config_settings = {
2566        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_no_compression",
2567    },
2568)
2569
2570def _test_apex_no_compression():
2571    name = "apex_no_compression"
2572    test_name = name + "_test"
2573
2574    test_apex(
2575        name = name,
2576    )
2577
2578    apex_no_compression_test(
2579        name = test_name,
2580        target_under_test = name,
2581    )
2582
2583    return test_name
2584
2585def _min_target_sdk_version_api_fingerprint_test(ctx):
2586    env = analysistest.begin(ctx)
2587    actions = analysistest.target_actions(env)
2588
2589    apexer_action = None
2590    for action in actions:
2591        if action.argv == None:
2592            continue
2593        for a in action.argv:
2594            if "--min_sdk_version" in a:
2595                apexer_action = action
2596                break
2597        if apexer_action != None:
2598            break
2599
2600    asserts.true(
2601        env,
2602        apexer_action != None,
2603        "There is no apexer action in all the actions",
2604    )
2605
2606    argv = apexer_action.argv[:-1] + apexer_action.argv[-1].split(" ")
2607    api_fingerprint_in_input = False
2608    api_fingerprint_path = None
2609    for f in apexer_action.inputs.to_list():
2610        if f.basename == "api_fingerprint.txt":
2611            api_fingerprint_in_input = True
2612            api_fingerprint_path = f.path
2613            break
2614
2615    asserts.true(
2616        env,
2617        api_fingerprint_in_input,
2618        "api_fingerprint.txt is not in the input files",
2619    )
2620
2621    expected_target_sdk_version = "123" + ".$(cat {})".format(api_fingerprint_path)
2622    target_sdk_version_index = argv.index("--target_sdk_version")
2623    asserts.equals(
2624        env,
2625        expected = expected_target_sdk_version,
2626        actual = argv[target_sdk_version_index + 1] + " " + argv[target_sdk_version_index + 2],
2627    )
2628
2629    min_sdk_version_index = argv.index("--min_sdk_version")
2630    if ctx.attr.min_sdk_version in ["current", "10000"]:
2631        expected_min_sdk_version = "123" + ".$(cat {})".format(api_fingerprint_path)
2632        actual_min_sdk_version = argv[min_sdk_version_index + 1] + " " + argv[min_sdk_version_index + 2]
2633    else:
2634        expected_min_sdk_version = ctx.attr.min_sdk_version
2635        actual_min_sdk_version = argv[min_sdk_version_index + 1]
2636    asserts.equals(
2637        env,
2638        expected = expected_min_sdk_version,
2639        actual = actual_min_sdk_version,
2640    )
2641
2642    return analysistest.end(env)
2643
2644min_target_sdk_version_api_fingerprint_test = analysistest.make(
2645    _min_target_sdk_version_api_fingerprint_test,
2646    attrs = {
2647        "min_sdk_version": attr.string(
2648            default = "current",
2649        ),
2650    },
2651    config_settings = {
2652        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_unbundled_build",
2653        "@//build/bazel/rules/apex:unbundled_build_target_sdk_with_api_fingerprint": True,
2654        "@//build/bazel/rules/apex:platform_sdk_codename": "123",
2655    },
2656)
2657
2658def _test_min_target_sdk_version_api_fingerprint_min_sdk_version_specified():
2659    name = "min_target_sdk_version_api_fingerprint_min_sdk_version_specified"
2660    test_name = name + "_test"
2661    min_sdk_version = "30"
2662
2663    test_apex(
2664        name = name,
2665        min_sdk_version = min_sdk_version,
2666    )
2667
2668    min_target_sdk_version_api_fingerprint_test(
2669        name = test_name,
2670        target_under_test = name,
2671        min_sdk_version = min_sdk_version,
2672    )
2673
2674    return test_name
2675
2676def _test_min_target_sdk_version_api_fingerprint_min_sdk_version_not_specified():
2677    name = "min_target_sdk_version_api_fingerprint_min_sdk_version_not_specified"
2678    test_name = name + "_test"
2679
2680    test_apex(
2681        name = name,
2682    )
2683
2684    min_target_sdk_version_api_fingerprint_test(
2685        name = test_name,
2686        target_under_test = name,
2687    )
2688
2689    return test_name
2690
2691def _apex_sbom_test(ctx):
2692    env = analysistest.begin(ctx)
2693
2694    # Action GenerateSBOMMetadata
2695    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "GenerateSBOMMetadata"]
2696    asserts.true(
2697        env,
2698        len(actions) == 1,
2699        "No GenerateSBOMMetadata action found for creating <apex>-sbom-metadata.csv file: %s" % actions,
2700    )
2701
2702    input_files = [input.basename for input in actions[0].inputs.to_list()]
2703    asserts.true(
2704        env,
2705        "apex_sbom_lib_cc.so" in input_files,
2706        "No expected file in inputs of GenerateSBOMMetadata action",
2707    )
2708
2709    output_files = [output.basename for output in actions[0].outputs.to_list()]
2710    asserts.true(
2711        env,
2712        "apex_sbom.apex-sbom-metadata.csv" in output_files,
2713        "No expected file in outputs of GenerateSBOMMetadata action",
2714    )
2715
2716    # Action GenerateSBOM
2717    actions = [a for a in analysistest.target_actions(env) if a.mnemonic == "GenerateSBOM"]
2718    asserts.true(
2719        env,
2720        len(actions) == 1,
2721        "No GenerateSBOM action found for creating sbom.spdx.json file: %s" % actions,
2722    )
2723    input_files = [input.short_path for input in actions[0].inputs.to_list()]
2724    expected_input_files = [
2725        "build/bazel/rules/apex/apex_sbom.apex",
2726        "build/bazel/rules/apex/apex_sbom.apex-sbom-metadata.csv",
2727        "build/make/tools/sbom/generate-sbom",
2728        "build/bazel/rules/apex/apex_sbom_lib_cc/apex_sbom_lib_cc.so",
2729        "build/bazel/rules/apex/METADATA",
2730    ]
2731    asserts.true(
2732        env,
2733        all([f in input_files for f in expected_input_files]),
2734        "Missing input files: %s" % input_files,
2735    )
2736
2737    output_files = [output.basename for output in actions[0].outputs.to_list()]
2738    expected_output_files = [
2739        "apex_sbom.apex.spdx.json",
2740        "apex_sbom.apex-fragment.spdx",
2741    ]
2742    asserts.true(
2743        env,
2744        all([f in output_files for f in expected_output_files]),
2745        "Missing output files: %s" % input_files,
2746    )
2747
2748    return analysistest.end(env)
2749
2750apex_sbom_test = analysistest.make(
2751    _apex_sbom_test,
2752)
2753
2754def _test_apex_sbom():
2755    name = "apex_sbom"
2756    test_name = name + "_test"
2757
2758    cc_library_shared(
2759        name = name + "_lib_cc",
2760        srcs = [name + "_lib.cc"],
2761        tags = ["manual"],
2762    )
2763
2764    test_apex(
2765        name = name,
2766        native_shared_libs_32 = [name + "_lib_cc"],
2767        android_manifest = "AndroidManifest.xml",
2768    )
2769
2770    apex_sbom_test(
2771        name = test_name,
2772        target_under_test = name,
2773    )
2774
2775    return test_name
2776
2777def _test_apex_variant_version():
2778    name = "apex_variant_version"
2779    test_name = name + "_test"
2780
2781    test_apex(
2782        name = name,
2783        variant_version = "3",
2784    )
2785
2786    expected_manifest_version = default_manifest_version + 3
2787
2788    action_flags_present_only_for_mnemonic_test(
2789        name = test_name,
2790        target_under_test = name,
2791        mnemonics = ["ApexManifestModify"],
2792        expected_flags = ["-se", "version", "0", str(expected_manifest_version)],
2793    )
2794
2795    return test_name
2796
2797def apex_test_suite(name):
2798    native.test_suite(
2799        name = name,
2800        tests = [
2801            _test_canned_fs_config_basic(),
2802            _test_canned_fs_config_custom(),
2803            _test_canned_fs_config_binaries(),
2804            _test_canned_fs_config_native_shared_libs_arm(),
2805            _test_canned_fs_config_native_shared_libs_arm64(),
2806            _test_canned_fs_config_prebuilts(),
2807            _test_canned_fs_config_prebuilts_sort_order(),
2808            _test_canned_fs_config_runtime_deps(),
2809            _test_apex_manifest(),
2810            _test_apex_manifest_min_sdk_version(),
2811            _test_apex_manifest_min_sdk_version_current(),
2812            _test_apex_manifest_min_sdk_version_override(),
2813            _test_apex_manifest_dependencies_nodep(),
2814            _test_apex_manifest_dependencies_cc_binary_bionic_deps(),
2815            _test_apex_manifest_dependencies_cc_library_shared_bionic_deps(),
2816            _test_apex_manifest_dependencies_requires(),
2817            _test_apex_manifest_dependencies_provides(),
2818            _test_apex_manifest_dependencies_selfcontained(),
2819            _test_apex_manifest_dependencies_cc_binary(),
2820            _test_logging_parent_flag(),
2821            _test_package_name(),
2822            _test_package_name_override_from_config(),
2823            _test_generate_file_contexts(),
2824            _test_default_apex_manifest_version(),
2825            _test_override_apex_manifest_version(),
2826            _test_min_sdk_version_failure(),
2827            _test_min_sdk_version_failure_transitive(),
2828            _test_apex_certificate_none(),
2829            _test_apex_certificate_name(),
2830            _test_apex_certificate_label(),
2831            _test_apex_certificate_label_with_overrides(),
2832            _test_min_sdk_version_apex_inherit(),
2833            _test_min_sdk_version_apex_inherit_override_min_sdk_tiramisu(),
2834            _test_apex_testonly_with_manifest(),
2835            _test_apex_provides_base_zip_files(),
2836            _test_apex_testonly_without_manifest(),
2837            _test_apex_backing_file(),
2838            _test_apex_symbols_used_by_apex(),
2839            _test_apex_installed_files(),
2840            _test_apex_java_symbols_used_by_apex(),
2841            _test_apex_generate_notice_file(),
2842            _test_apex_available(),
2843            _test_apex_available_failure(),
2844            _test_apex_available_with_base_apex(),
2845            _test_apex_deps_validation(),
2846            _test_no_static_linking_for_stubs_lib(),
2847            _test_directly_included_stubs_lib_with_indirectly_static_variant(),
2848            _test_apex_in_unbundled_build(),
2849            _test_apex_in_bundled_build(),
2850            _test_apex_compression(),
2851            _test_apex_no_compression(),
2852            _test_min_target_sdk_version_api_fingerprint_min_sdk_version_specified(),
2853            _test_min_target_sdk_version_api_fingerprint_min_sdk_version_not_specified(),
2854            _test_apex_sbom(),
2855            _test_apex_variant_version(),
2856        ] + _test_apex_transition(),
2857    )
2858