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: 35 void TearDown() override { android::derivesdk::SetSdkLevels("/apex"); } 36 37 const std::string dir() { return std::string(dir_.path); } 38 39 const std::string EtcDir(const std::string& apex) { 40 return dir() + "/" + apex + "/etc"; 41 } 42 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 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 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 75 void EXPECT_R(int n) { 76 int R = android::base::GetIntProperty("build.version.extensions.r", -1); 77 EXPECT_EQ(R, n); 78 } 79 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 90 TEST_F(DeriveSdkTest, CurrentSystemImageValue) { 91 EXPECT_R(1); 92 EXPECT_S(1); 93 } 94 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 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 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 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 182 int main(int argc, char** argv) { 183 ::testing::InitGoogleTest(&argc, argv); 184 return RUN_ALL_TESTS(); 185 } 186