• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "derive_sdk_test"
18 
19 #include "derive_sdk.h"
20 
21 #include <android-base/file.h>
22 #include <android-base/logging.h>
23 #include <android-base/properties.h>
24 #include <android-modules-utils/sdk_level.h>
25 #include <gtest/gtest.h>
26 #include <stdlib.h>
27 #include <sys/stat.h>
28 
29 #include <cstdlib>
30 
31 #include "packages/modules/common/proto/sdk.pb.h"
32 
33 #define EXPECT_ALL(n) \
34   {                   \
35     EXPECT_R(n);      \
36     EXPECT_S(n);      \
37     EXPECT_T(n);      \
38     EXPECT_U(n);      \
39   }
40 
41 #define EXPECT_R(n) EXPECT_EQ(GetR(), (n))
42 
43 // Only expect the S extension level to be set on S+ devices.
44 #define EXPECT_S(n) EXPECT_EQ(GetS(), android::modules::sdklevel::IsAtLeastS() ? (n) : -1)
45 
46 // Only expect the T extension level to be set on T+ devices.
47 #define EXPECT_T(n) EXPECT_EQ(GetT(), android::modules::sdklevel::IsAtLeastT() ? (n) : -1)
48 
49 // Only expect the U extension level to be set on U+ devices.
50 #define EXPECT_U(n) EXPECT_EQ(GetU(), android::modules::sdklevel::IsAtLeastU() ? (n) : -1)
51 
52 class DeriveSdkTest : public ::testing::Test {
53  protected:
TearDown()54   void TearDown() override { android::derivesdk::SetSdkLevels("/apex"); }
55 
dir()56   const std::string dir() { return std::string(dir_.path); }
57 
EtcDir(const std::string & apex)58   const std::string EtcDir(const std::string& apex) {
59     return dir() + "/" + apex + "/etc";
60   }
61 
AddVersionToDb(const int version,const std::unordered_map<SdkModule,int> & requirements)62   void AddVersionToDb(const int version, const std::unordered_map<SdkModule, int>& requirements) {
63     ExtensionVersion* sdk = db_.add_versions();
64     sdk->set_version(version);
65     for (auto pair : requirements) {
66       ExtensionVersion_ModuleRequirement* req = sdk->add_requirements();
67       req->set_module(pair.first);
68       req->mutable_version()->set_version(pair.second);
69     }
70     WriteProto(db_, EtcDir("com.android.sdkext") + "/extensions_db.pb");
71   }
72 
AddExtensionVersion(const int version,const std::unordered_map<SdkModule,int> & requirements)73   void AddExtensionVersion(const int version,
74                            const std::unordered_map<SdkModule, int>& requirements) {
75     AddVersionToDb(version, requirements);
76     ASSERT_TRUE(android::derivesdk::SetSdkLevels(dir()));
77   }
78 
SetApexVersion(const std::string apex,int version)79   void SetApexVersion(const std::string apex, int version) {
80     SdkVersion sdk_version;
81     sdk_version.set_version(version);
82     WriteProto(sdk_version, EtcDir(apex) + "/sdkinfo.pb");
83 
84     ASSERT_TRUE(android::derivesdk::SetSdkLevels(dir()));
85   }
86 
WriteProto(const google::protobuf::MessageLite & proto,const std::string & path)87   void WriteProto(const google::protobuf::MessageLite& proto,
88                   const std::string& path) {
89     std::string buf;
90     proto.SerializeToString(&buf);
91     std::string cmd("mkdir -p " + path.substr(0, path.find_last_of('/')));
92     ASSERT_EQ(0, system(cmd.c_str()));
93     ASSERT_TRUE(android::base::WriteStringToFile(buf, path, true));
94   }
95 
GetR()96   int GetR() { return android::base::GetIntProperty("build.version.extensions.r", -1); }
97 
GetS()98   int GetS() { return android::base::GetIntProperty("build.version.extensions.s", -1); }
99 
GetT()100   int GetT() { return android::base::GetIntProperty("build.version.extensions.t", -1); }
101 
GetU()102   int GetU() { return android::base::GetIntProperty("build.version.extensions.u", -1); }
103 
EXPECT_ADSERVICES(int n)104   void EXPECT_ADSERVICES(int n) {
105     int actual = android::base::GetIntProperty("build.version.extensions.ad_services", -1);
106     // Only expect the AdServices extension level to be set on T+ devices.
107     EXPECT_EQ(actual, android::modules::sdklevel::IsAtLeastT() ? n : -1);
108   }
109 
110   ExtensionDatabase db_;
111   TemporaryDir dir_;
112 };
113 
TEST_F(DeriveSdkTest,OneDessert_OneVersion_OneApex)114 TEST_F(DeriveSdkTest, OneDessert_OneVersion_OneApex) {
115   AddExtensionVersion(3, {{SdkModule::SDK_EXTENSIONS, 2}});
116   EXPECT_ALL(0);
117 
118   SetApexVersion("com.android.sdkext", 3);
119   EXPECT_ALL(3);
120 }
121 
TEST_F(DeriveSdkTest,OneDessert_OneVersion_TwoApexes)122 TEST_F(DeriveSdkTest, OneDessert_OneVersion_TwoApexes) {
123   AddExtensionVersion(5, {
124                              {SdkModule::MEDIA, 5},
125                              {SdkModule::SDK_EXTENSIONS, 2},
126                          });
127   EXPECT_ALL(0);
128 
129   // Only sdkext
130   SetApexVersion("com.android.sdkext", 2);
131   EXPECT_ALL(0);
132 
133   // Only media
134   SetApexVersion("com.android.sdkext", 0);
135   SetApexVersion("com.android.media", 5);
136   EXPECT_ALL(0);
137 
138   // Both
139   SetApexVersion("com.android.sdkext", 2);
140   EXPECT_ALL(5);
141 }
142 
TEST_F(DeriveSdkTest,OneDessert_ManyVersions)143 TEST_F(DeriveSdkTest, OneDessert_ManyVersions) {
144   AddExtensionVersion(1, {
145                              {SdkModule::MEDIA, 1},
146                          });
147   EXPECT_ALL(0);
148   SetApexVersion("com.android.media", 1);
149   EXPECT_ALL(1);
150 
151   AddExtensionVersion(2, {
152                              {SdkModule::MEDIA, 1},
153                              {SdkModule::MEDIA_PROVIDER, 2},
154                              {SdkModule::SDK_EXTENSIONS, 2},
155                          });
156   EXPECT_ALL(1);
157   SetApexVersion("com.android.mediaprovider", 2);
158   EXPECT_ALL(1);
159   SetApexVersion("com.android.sdkext", 2);
160   EXPECT_ALL(2);
161 
162   AddExtensionVersion(3, {
163                              {SdkModule::MEDIA, 3},
164                              {SdkModule::MEDIA_PROVIDER, 2},
165                              {SdkModule::SDK_EXTENSIONS, 3},
166                          });
167   EXPECT_ALL(2);
168   SetApexVersion("com.android.media", 3);
169   EXPECT_ALL(2);
170   SetApexVersion("com.android.sdkext", 3);
171   EXPECT_ALL(3);
172 }
173 
TEST_F(DeriveSdkTest,TwoDesserts_ManyVersions)174 TEST_F(DeriveSdkTest, TwoDesserts_ManyVersions) {
175   AddExtensionVersion(1, {
176                              {SdkModule::TETHERING, 1},
177                          });
178   EXPECT_ALL(0);
179 
180   // Only tethering v1
181   SetApexVersion("com.android.tethering", 1);
182   EXPECT_ALL(1);
183 
184   // V2 defined
185   AddExtensionVersion(2, {
186                              {SdkModule::ART, 2},
187                              {SdkModule::TETHERING, 1},
188                          });
189   EXPECT_R(2);
190   EXPECT_S(1);
191 
192   // Only art v2
193   SetApexVersion("com.android.tethering", 0);
194   SetApexVersion("com.android.art", 2);
195   EXPECT_ALL(0);
196 
197   // Both
198   SetApexVersion("com.android.tethering", 1);
199   EXPECT_ALL(2);
200 
201   // V3 defined
202   AddExtensionVersion(3, {
203                              {SdkModule::ART, 3},
204                              {SdkModule::MEDIA, 3},
205                              {SdkModule::TETHERING, 1},
206                          });
207   EXPECT_ALL(2);
208 
209   // Only media v3
210   SetApexVersion("com.android.media", 3);
211   EXPECT_R(3);
212   EXPECT_S(2);
213 
214   // Only art v3
215   SetApexVersion("com.android.media", 0);
216   SetApexVersion("com.android.art", 3);
217   EXPECT_ALL(2);
218 
219   // Both
220   SetApexVersion("com.android.media", 3);
221   EXPECT_ALL(3);
222 }
223 
TEST_F(DeriveSdkTest,UnmappedModule)224 TEST_F(DeriveSdkTest, UnmappedModule) {
225   AddVersionToDb(5, {
226                         {static_cast<SdkModule>(77), 5},  // Doesn't exist.
227                         {SdkModule::SDK_EXTENSIONS, 2},
228                     });
229 
230   ASSERT_FALSE(android::derivesdk::SetSdkLevels(dir()));
231 }
232 
TEST_F(DeriveSdkTest,AdServicesPreV7)233 TEST_F(DeriveSdkTest, AdServicesPreV7) {
234   AddExtensionVersion(1, {
235                              {SdkModule::TETHERING, 1},
236                          });
237   EXPECT_ALL(0);
238   EXPECT_ADSERVICES(1);
239 
240   SetApexVersion("com.android.tethering", 1);
241   EXPECT_ALL(1);
242 
243   // V2 defined
244   AddExtensionVersion(2, {
245                              {SdkModule::AD_SERVICES, 2},
246                              {SdkModule::TETHERING, 2},
247                          });
248   EXPECT_ALL(1);
249   EXPECT_ADSERVICES(1);
250 
251   // Only adservices v2
252   SetApexVersion("com.android.adservices", 2);
253   EXPECT_ALL(1);
254   EXPECT_ADSERVICES(2);
255 
256   // Both v2
257   SetApexVersion("com.android.tethering", 2);
258   EXPECT_ALL(2);
259   EXPECT_ADSERVICES(2);
260 
261   // Only tethering v2. R and S extension are bumped, but T requires adserices.
262   SetApexVersion("com.android.adservices", 0);
263   SetApexVersion("com.android.tethering", 2);
264   EXPECT_R(2);
265   EXPECT_S(2);
266   EXPECT_T(1);
267   EXPECT_ADSERVICES(1);
268 }
269 
TEST_F(DeriveSdkTest,AdServicesPostV7)270 TEST_F(DeriveSdkTest, AdServicesPostV7) {
271   // Need to add a base version with an R module to prevent the
272   // dessert extension versions from getting bumped.
273   AddExtensionVersion(1, {
274                              {SdkModule::TETHERING, 1},
275                          });
276 
277   // Only adservices v2
278   SetApexVersion("com.android.adservices", 2);
279   EXPECT_ALL(0);
280   EXPECT_ADSERVICES(1);
281 
282   // From v7 and onwards, we only care about the adservices version
283   SetApexVersion("com.android.adservices", 7);
284   EXPECT_ALL(0);
285   EXPECT_ADSERVICES(7);
286 
287   SetApexVersion("com.android.adservices", 10);
288   EXPECT_ALL(0);
289   EXPECT_ADSERVICES(10);
290 }
291 
TEST_F(DeriveSdkTest,Tiramisu)292 TEST_F(DeriveSdkTest, Tiramisu) {
293   AddExtensionVersion(1, {
294                              {SdkModule::AD_SERVICES, 1},
295                              {SdkModule::APPSEARCH, 2},
296                              {SdkModule::ON_DEVICE_PERSONALIZATION, 3},
297                          });
298   EXPECT_T(0);
299 
300   SetApexVersion("com.android.adservices", 1);
301   EXPECT_T(0);
302 
303   SetApexVersion("com.android.appsearch", 2);
304   EXPECT_T(0);
305 
306   SetApexVersion("com.android.ondevicepersonalization", 3);
307   EXPECT_T(1);
308 }
309 
TEST_F(DeriveSdkTest,UpsideDownCake)310 TEST_F(DeriveSdkTest, UpsideDownCake) {
311   AddExtensionVersion(1, {
312                              {SdkModule::CONFIG_INFRASTRUCTURE, 1},
313                              {SdkModule::HEALTH_FITNESS, 2},
314                          });
315   EXPECT_U(0);
316 
317   SetApexVersion("com.android.configinfrastructure", 1);
318   EXPECT_U(0);
319 
320   SetApexVersion("com.android.healthfitness", 2);
321   EXPECT_U(1);
322 }
323 
main(int argc,char ** argv)324 int main(int argc, char** argv) {
325   ::testing::InitGoogleTest(&argc, argv);
326   return RUN_ALL_TESTS();
327 }
328