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 class DeriveSdkTest : public ::testing::Test {
34 protected:
TearDown()35 void TearDown() override { android::derivesdk::SetSdkLevels("/apex"); }
36
dir()37 const std::string dir() { return std::string(dir_.path); }
38
EtcDir(const std::string & apex)39 const std::string EtcDir(const std::string& apex) {
40 return dir() + "/" + apex + "/etc";
41 }
42
AddExtensionVersion(const int version,const std::unordered_map<SdkModule,int> & requirements)43 void AddExtensionVersion(
44 const int version,
45 const std::unordered_map<SdkModule, int>& requirements) {
46 ExtensionVersion* sdk = db_.add_versions();
47 sdk->set_version(version);
48 for (auto pair : requirements) {
49 ExtensionVersion_ModuleRequirement* req = sdk->add_requirements();
50 req->set_module(pair.first);
51 req->mutable_version()->set_version(pair.second);
52 }
53 WriteProto(db_, EtcDir("com.android.sdkext") + "/extensions_db.pb");
54
55 android::derivesdk::SetSdkLevels(dir());
56 }
57
SetApexVersion(const std::string apex,int version)58 void SetApexVersion(const std::string apex, int version) {
59 SdkVersion sdk_version;
60 sdk_version.set_version(version);
61 WriteProto(sdk_version, EtcDir(apex) + "/sdkinfo.pb");
62
63 android::derivesdk::SetSdkLevels(dir());
64 }
65
WriteProto(const google::protobuf::MessageLite & proto,const std::string & path)66 void WriteProto(const google::protobuf::MessageLite& proto,
67 const std::string& path) {
68 std::string buf;
69 proto.SerializeToString(&buf);
70 std::string cmd("mkdir -p " + path.substr(0, path.find_last_of('/')));
71 ASSERT_EQ(0, system(cmd.c_str()));
72 ASSERT_TRUE(android::base::WriteStringToFile(buf, path, true));
73 }
74
EXPECT_R(int n)75 void EXPECT_R(int n) {
76 int R = android::base::GetIntProperty("build.version.extensions.r", -1);
77 EXPECT_EQ(R, n);
78 }
79
EXPECT_S(int n)80 void EXPECT_S(int n) {
81 int S = android::base::GetIntProperty("build.version.extensions.s", -1);
82 // Only expect the S extension level to be set on S+ devices.
83 EXPECT_EQ(S, android::modules::sdklevel::IsAtLeastS() ? n : -1);
84 }
85
86 ExtensionDatabase db_;
87 TemporaryDir dir_;
88 };
89
TEST_F(DeriveSdkTest,CurrentSystemImageValue)90 TEST_F(DeriveSdkTest, CurrentSystemImageValue) {
91 EXPECT_R(1);
92 EXPECT_S(1);
93 }
94
TEST_F(DeriveSdkTest,OneDessert_OneVersion_OneApex)95 TEST_F(DeriveSdkTest, OneDessert_OneVersion_OneApex) {
96 AddExtensionVersion(3, {{SdkModule::SDK_EXTENSIONS, 2}});
97 EXPECT_S(3);
98
99 SetApexVersion("com.android.sdkext", 3);
100
101 EXPECT_R(3);
102 EXPECT_S(3);
103 }
104
TEST_F(DeriveSdkTest,OneDessert_OneVersion_TwoApexes)105 TEST_F(DeriveSdkTest, OneDessert_OneVersion_TwoApexes) {
106 AddExtensionVersion(5, {
107 {SdkModule::MEDIA, 5},
108 {SdkModule::SDK_EXTENSIONS, 2},
109 });
110 EXPECT_R(0);
111 EXPECT_S(5);
112
113 SetApexVersion("com.android.sdkext", 2);
114 EXPECT_R(0);
115 SetApexVersion("com.android.media", 5);
116 EXPECT_R(5);
117 }
118
TEST_F(DeriveSdkTest,OneDessert_ManyVersions)119 TEST_F(DeriveSdkTest, OneDessert_ManyVersions) {
120 AddExtensionVersion(1, {
121 {SdkModule::MEDIA, 1},
122 });
123 AddExtensionVersion(2, {
124 {SdkModule::MEDIA, 1},
125 {SdkModule::MEDIA_PROVIDER, 2},
126 {SdkModule::SDK_EXTENSIONS, 2},
127 });
128 AddExtensionVersion(3, {
129 {SdkModule::MEDIA, 3},
130 {SdkModule::MEDIA_PROVIDER, 2},
131 {SdkModule::SDK_EXTENSIONS, 3},
132 });
133 EXPECT_R(0);
134 EXPECT_S(3);
135
136 SetApexVersion("com.android.media", 1);
137 EXPECT_R(1);
138
139 SetApexVersion("com.android.mediaprovider", 2);
140 EXPECT_R(1);
141 SetApexVersion("com.android.sdkext", 2);
142 EXPECT_R(2);
143
144 SetApexVersion("com.android.media", 3);
145 EXPECT_R(2);
146 SetApexVersion("com.android.sdkext", 3);
147 EXPECT_R(3);
148 }
149
TEST_F(DeriveSdkTest,TwoDesserts_ManyVersions)150 TEST_F(DeriveSdkTest, TwoDesserts_ManyVersions) {
151 AddExtensionVersion(1, {
152 {SdkModule::TETHERING, 1},
153 });
154 AddExtensionVersion(2, {
155 {SdkModule::ART, 2},
156 {SdkModule::TETHERING, 1},
157 });
158 AddExtensionVersion(3, {
159 {SdkModule::ART, 3},
160 {SdkModule::MEDIA, 3},
161 {SdkModule::TETHERING, 1},
162 });
163 EXPECT_R(0);
164 EXPECT_S(1);
165
166 SetApexVersion("com.android.tethering", 1);
167 EXPECT_R(2);
168 EXPECT_S(1);
169
170 SetApexVersion("com.android.art", 2);
171 EXPECT_R(2);
172 EXPECT_S(2);
173
174 SetApexVersion("com.android.media", 3);
175 EXPECT_R(3);
176 EXPECT_S(2);
177 SetApexVersion("com.android.art", 3);
178 EXPECT_R(3);
179 EXPECT_S(3);
180 }
181
main(int argc,char ** argv)182 int main(int argc, char** argv) {
183 ::testing::InitGoogleTest(&argc, argv);
184 return RUN_ALL_TESTS();
185 }
186