1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "linkerconfig/apexconfig.h"
18
19 #include <android-base/file.h>
20 #include <apex_manifest.pb.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <vector>
24
25 #include "configurationtest.h"
26 #include "linkerconfig/apex.h"
27 #include "linkerconfig/configwriter.h"
28 #include "mockenv.h"
29
30 using android::linkerconfig::contents::Context;
31 using android::linkerconfig::contents::CreateApexConfiguration;
32 using android::linkerconfig::modules::ApexInfo;
33 using ::testing::Contains;
34
35 namespace {
36 struct ApexConfigTest : ::testing::Test {
SetUp__anon19652efa0111::ApexConfigTest37 void SetUp() override {
38 MockGenericVariables();
39 }
40
PrepareApex__anon19652efa0111::ApexConfigTest41 ApexInfo PrepareApex(const std::string& apex_name,
42 const std::vector<std::string>& provide_libs,
43 const std::vector<std::string>& require_libs) {
44 return ApexInfo(apex_name,
45 "/apex/" + apex_name,
46 provide_libs,
47 require_libs,
48 /*jni_libs=*/{},
49 /*permitted_paths=*/{},
50 /*has_bin=*/true,
51 /*has_lib=*/true,
52 /*visible=*/false,
53 /*has_shared_lib=*/false);
54 }
55 };
56 } // namespace
57
TEST_F(ApexConfigTest,apex_no_dependency)58 TEST_F(ApexConfigTest, apex_no_dependency) {
59 android::linkerconfig::contents::Context ctx;
60 auto target_apex = PrepareApex("target", {}, {});
61 auto config = android::linkerconfig::contents::CreateApexConfiguration(
62 ctx, target_apex);
63
64 android::linkerconfig::modules::ConfigWriter config_writer;
65 config.WriteConfig(config_writer);
66
67 VerifyConfiguration(config_writer.ToString());
68 }
69
TEST_F(ApexConfigTest,apex_with_required)70 TEST_F(ApexConfigTest, apex_with_required) {
71 android::linkerconfig::contents::Context ctx;
72 ctx.SetApexModules({PrepareApex("foo", {"a.so"}, {"b.so"}),
73 PrepareApex("bar", {"b.so"}, {}),
74 PrepareApex("baz", {"c.so"}, {"a.so"})});
75 auto target_apex = PrepareApex("target", {}, {"a.so", "b.so"});
76 auto config = android::linkerconfig::contents::CreateApexConfiguration(
77 ctx, target_apex);
78
79 android::linkerconfig::modules::ConfigWriter config_writer;
80 config.WriteConfig(config_writer);
81
82 VerifyConfiguration(config_writer.ToString());
83 }
84
TEST_F(ApexConfigTest,vndk_in_system_vendor_apex)85 TEST_F(ApexConfigTest, vndk_in_system_vendor_apex) {
86 MockVndkUsingCoreVariant();
87 android::linkerconfig::contents::Context ctx;
88
89 android::linkerconfig::proto::LinkerConfig vendor_config;
90 vendor_config.add_providelibs("libvendorprovide.so");
91 ctx.SetVendorConfig(vendor_config);
92
93 auto vendor_apex =
94 PrepareApex("vendor_apex", {}, {":vndk", "libvendorprovide.so"});
95 vendor_apex.original_path = "/vendor/apex/com.android.vendor";
96 ctx.SetApexModules({vendor_apex, CreateTestVndkApex()});
97 auto config = android::linkerconfig::contents::CreateApexConfiguration(
98 ctx, vendor_apex);
99
100 android::linkerconfig::modules::ConfigWriter config_writer;
101 config.WriteConfig(config_writer);
102
103 VerifyConfiguration(config_writer.ToString());
104 }
105
TEST_F(ApexConfigTest,vndk_in_system_product_apex)106 TEST_F(ApexConfigTest, vndk_in_system_product_apex) {
107 MockVndkUsingCoreVariant();
108 android::linkerconfig::contents::Context ctx;
109
110 android::linkerconfig::proto::LinkerConfig product_config;
111 product_config.add_providelibs("libproductprovide.so");
112 ctx.SetProductConfig(product_config);
113
114 auto product_apex =
115 PrepareApex("product_apex", {}, {":vndksp", "libproductprovide.so"});
116 product_apex.original_path = "/product/apex/com.android.product";
117 ctx.SetApexModules({product_apex, CreateTestVndkApex()});
118 auto config = android::linkerconfig::contents::CreateApexConfiguration(
119 ctx, product_apex);
120
121 android::linkerconfig::modules::ConfigWriter config_writer;
122 config.WriteConfig(config_writer);
123
124 VerifyConfiguration(config_writer.ToString());
125 }
126
TEST_F(ApexConfigTest,vendor_apex_without_use_vndk_as_stable)127 TEST_F(ApexConfigTest, vendor_apex_without_use_vndk_as_stable) {
128 android::linkerconfig::contents::Context ctx;
129
130 android::linkerconfig::proto::LinkerConfig vendor_config;
131 vendor_config.add_requirelibs("libapexprovide.so");
132 vendor_config.add_providelibs("libvendorprovide.so");
133 ctx.SetVendorConfig(vendor_config);
134
135 // Vendor apex requires :vndk
136 auto vendor_apex = PrepareApex(
137 "com.android.vendor", {"libapexprovide.so"}, {"libvendorprovide.so"});
138 vendor_apex.original_path = "/vendor/apex/com.android.vendor";
139 ctx.SetApexModules({vendor_apex, CreateTestVndkApex()});
140
141 auto config = CreateApexConfiguration(ctx, vendor_apex);
142
143 auto* section = config.GetSection("com.android.vendor");
144 ASSERT_TRUE(section);
145
146 // vendor apex should be able to load vndk libraries
147 auto vndk_namespace = section->GetNamespace("vndk");
148 ASSERT_TRUE(vndk_namespace);
149
150 android::linkerconfig::modules::ConfigWriter config_writer;
151 config.WriteConfig(config_writer);
152 VerifyConfiguration(config_writer.ToString());
153 }
154
155 // [apex]com.android.target --(require)--> missing.so
TEST_F(ApexConfigTest,StrictModeRejects_MissingRequiredLibs)156 TEST_F(ApexConfigTest, StrictModeRejects_MissingRequiredLibs) {
157 const std::string apex_name = "com.android.target";
158 Context ctx;
159 ctx.SetApexModules({CreateTestVndkApex()});
160 ctx.SetStrictMode(true);
161 ctx.SetTargetApex(apex_name);
162 auto apex = PrepareApex(apex_name, {}, /*require_libs=*/{"missing.so"});
163 ASSERT_EXIT(CreateApexConfiguration(ctx, apex),
164 testing::KilledBySignal(SIGABRT),
165 #ifndef __ANDROID__
166 "not found:.*missing\\.so"
167 #else
168 ""
169 #endif
170 );
171 }
172
173 // [apex]com.android.target [apex]com.android.other
174 // `--(require)--> other.so <--(provide)--' |
175 // `-(require)--> missing.so
TEST_F(ApexConfigTest,StrictModeAccepts_MissingRequiredLibsInOtherApex)176 TEST_F(ApexConfigTest, StrictModeAccepts_MissingRequiredLibsInOtherApex) {
177 const std::string apex_name = "com.android.target";
178 Context ctx;
179 ctx.SetStrictMode(true);
180 ctx.SetTargetApex(apex_name);
181 ctx.SetApexModules({PrepareApex("com.android.other",
182 /*provide_libs=*/{"other.so"},
183 /*require_libs=*/{"missing.so"}),
184 CreateTestVndkApex()});
185 auto apex = PrepareApex(apex_name, {}, /*require_libs=*/{"other.so"});
186 auto config = CreateApexConfiguration(ctx, apex);
187 auto section = config.GetSection("com.android.target");
188 auto ns = section->GetNamespace("default");
189 ASSERT_THAT(ns->GetLink("com_android_other").GetSharedLibs(),
190 Contains("other.so"));
191 }
192