1*33f37583SAndroid Build Coastguard Worker /*
2*33f37583SAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*33f37583SAndroid Build Coastguard Worker *
4*33f37583SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*33f37583SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*33f37583SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*33f37583SAndroid Build Coastguard Worker *
8*33f37583SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*33f37583SAndroid Build Coastguard Worker *
10*33f37583SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*33f37583SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*33f37583SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*33f37583SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*33f37583SAndroid Build Coastguard Worker * limitations under the License.
15*33f37583SAndroid Build Coastguard Worker */
16*33f37583SAndroid Build Coastguard Worker
17*33f37583SAndroid Build Coastguard Worker #include "apexd.h"
18*33f37583SAndroid Build Coastguard Worker
19*33f37583SAndroid Build Coastguard Worker #include <android-base/file.h>
20*33f37583SAndroid Build Coastguard Worker #include <android-base/properties.h>
21*33f37583SAndroid Build Coastguard Worker #include <android-base/result-gmock.h>
22*33f37583SAndroid Build Coastguard Worker #include <android-base/scopeguard.h>
23*33f37583SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
24*33f37583SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
25*33f37583SAndroid Build Coastguard Worker #include <gmock/gmock.h>
26*33f37583SAndroid Build Coastguard Worker #include <gtest/gtest.h>
27*33f37583SAndroid Build Coastguard Worker #include <libdm/dm.h>
28*33f37583SAndroid Build Coastguard Worker #include <microdroid/metadata.h>
29*33f37583SAndroid Build Coastguard Worker #include <selinux/selinux.h>
30*33f37583SAndroid Build Coastguard Worker #include <sys/stat.h>
31*33f37583SAndroid Build Coastguard Worker #include <unistd.h>
32*33f37583SAndroid Build Coastguard Worker
33*33f37583SAndroid Build Coastguard Worker #include <chrono>
34*33f37583SAndroid Build Coastguard Worker #include <functional>
35*33f37583SAndroid Build Coastguard Worker #include <optional>
36*33f37583SAndroid Build Coastguard Worker #include <string>
37*33f37583SAndroid Build Coastguard Worker #include <thread>
38*33f37583SAndroid Build Coastguard Worker #include <tuple>
39*33f37583SAndroid Build Coastguard Worker #include <unordered_set>
40*33f37583SAndroid Build Coastguard Worker #include <vector>
41*33f37583SAndroid Build Coastguard Worker
42*33f37583SAndroid Build Coastguard Worker #include "apex_constants.h"
43*33f37583SAndroid Build Coastguard Worker #include "apex_database.h"
44*33f37583SAndroid Build Coastguard Worker #include "apex_file.h"
45*33f37583SAndroid Build Coastguard Worker #include "apex_file_repository.h"
46*33f37583SAndroid Build Coastguard Worker #include "apex_manifest.pb.h"
47*33f37583SAndroid Build Coastguard Worker #include "apexd_checkpoint.h"
48*33f37583SAndroid Build Coastguard Worker #include "apexd_loop.h"
49*33f37583SAndroid Build Coastguard Worker #include "apexd_metrics.h"
50*33f37583SAndroid Build Coastguard Worker #include "apexd_session.h"
51*33f37583SAndroid Build Coastguard Worker #include "apexd_test_utils.h"
52*33f37583SAndroid Build Coastguard Worker #include "apexd_utils.h"
53*33f37583SAndroid Build Coastguard Worker #include "com_android_apex.h"
54*33f37583SAndroid Build Coastguard Worker #include "gmock/gmock-matchers.h"
55*33f37583SAndroid Build Coastguard Worker
56*33f37583SAndroid Build Coastguard Worker namespace android {
57*33f37583SAndroid Build Coastguard Worker namespace apex {
58*33f37583SAndroid Build Coastguard Worker
59*33f37583SAndroid Build Coastguard Worker using namespace std::literals;
60*33f37583SAndroid Build Coastguard Worker namespace fs = std::filesystem;
61*33f37583SAndroid Build Coastguard Worker
62*33f37583SAndroid Build Coastguard Worker using MountedApexData = MountedApexDatabase::MountedApexData;
63*33f37583SAndroid Build Coastguard Worker using android::apex::testing::ApexFileEq;
64*33f37583SAndroid Build Coastguard Worker using android::base::GetExecutableDirectory;
65*33f37583SAndroid Build Coastguard Worker using android::base::GetProperty;
66*33f37583SAndroid Build Coastguard Worker using android::base::Join;
67*33f37583SAndroid Build Coastguard Worker using android::base::make_scope_guard;
68*33f37583SAndroid Build Coastguard Worker using android::base::ReadFileToString;
69*33f37583SAndroid Build Coastguard Worker using android::base::ReadFully;
70*33f37583SAndroid Build Coastguard Worker using android::base::RemoveFileIfExists;
71*33f37583SAndroid Build Coastguard Worker using android::base::Result;
72*33f37583SAndroid Build Coastguard Worker using android::base::Split;
73*33f37583SAndroid Build Coastguard Worker using android::base::StringPrintf;
74*33f37583SAndroid Build Coastguard Worker using android::base::unique_fd;
75*33f37583SAndroid Build Coastguard Worker using android::base::WriteStringToFile;
76*33f37583SAndroid Build Coastguard Worker using android::base::testing::HasError;
77*33f37583SAndroid Build Coastguard Worker using android::base::testing::HasValue;
78*33f37583SAndroid Build Coastguard Worker using android::base::testing::Ok;
79*33f37583SAndroid Build Coastguard Worker using android::base::testing::WithCode;
80*33f37583SAndroid Build Coastguard Worker using android::base::testing::WithMessage;
81*33f37583SAndroid Build Coastguard Worker using android::dm::DeviceMapper;
82*33f37583SAndroid Build Coastguard Worker using ::apex::proto::SessionState;
83*33f37583SAndroid Build Coastguard Worker using com::android::apex::testing::ApexInfoXmlEq;
84*33f37583SAndroid Build Coastguard Worker using ::testing::ByRef;
85*33f37583SAndroid Build Coastguard Worker using ::testing::Contains;
86*33f37583SAndroid Build Coastguard Worker using ::testing::ElementsAre;
87*33f37583SAndroid Build Coastguard Worker using ::testing::EndsWith;
88*33f37583SAndroid Build Coastguard Worker using ::testing::HasSubstr;
89*33f37583SAndroid Build Coastguard Worker using ::testing::IsEmpty;
90*33f37583SAndroid Build Coastguard Worker using ::testing::Not;
91*33f37583SAndroid Build Coastguard Worker using ::testing::StartsWith;
92*33f37583SAndroid Build Coastguard Worker using ::testing::UnorderedElementsAre;
93*33f37583SAndroid Build Coastguard Worker using ::testing::UnorderedElementsAreArray;
94*33f37583SAndroid Build Coastguard Worker using ::testing::internal::CaptureStderr;
95*33f37583SAndroid Build Coastguard Worker using ::testing::internal::GetCapturedStderr;
96*33f37583SAndroid Build Coastguard Worker
GetTestDataDir()97*33f37583SAndroid Build Coastguard Worker static std::string GetTestDataDir() { return GetExecutableDirectory(); }
GetTestFile(const std::string & name)98*33f37583SAndroid Build Coastguard Worker static std::string GetTestFile(const std::string& name) {
99*33f37583SAndroid Build Coastguard Worker return GetTestDataDir() + "/" + name;
100*33f37583SAndroid Build Coastguard Worker }
101*33f37583SAndroid Build Coastguard Worker
GetMTime(const std::string & path)102*33f37583SAndroid Build Coastguard Worker static int64_t GetMTime(const std::string& path) {
103*33f37583SAndroid Build Coastguard Worker struct stat st_buf;
104*33f37583SAndroid Build Coastguard Worker if (stat(path.c_str(), &st_buf) != 0) {
105*33f37583SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to stat " << path;
106*33f37583SAndroid Build Coastguard Worker return 0;
107*33f37583SAndroid Build Coastguard Worker }
108*33f37583SAndroid Build Coastguard Worker return st_buf.st_mtime;
109*33f37583SAndroid Build Coastguard Worker }
110*33f37583SAndroid Build Coastguard Worker
GetSizeByBlocks(const std::string & path)111*33f37583SAndroid Build Coastguard Worker static int64_t GetSizeByBlocks(const std::string& path) {
112*33f37583SAndroid Build Coastguard Worker struct stat st_buf;
113*33f37583SAndroid Build Coastguard Worker if (stat(path.c_str(), &st_buf) != 0) {
114*33f37583SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to stat " << path;
115*33f37583SAndroid Build Coastguard Worker return 0;
116*33f37583SAndroid Build Coastguard Worker }
117*33f37583SAndroid Build Coastguard Worker return st_buf.st_blocks * st_buf.st_blksize;
118*33f37583SAndroid Build Coastguard Worker }
119*33f37583SAndroid Build Coastguard Worker
120*33f37583SAndroid Build Coastguard Worker // A very basic mock of CheckpointInterface.
121*33f37583SAndroid Build Coastguard Worker class MockCheckpointInterface : public CheckpointInterface {
122*33f37583SAndroid Build Coastguard Worker public:
SupportsFsCheckpoints()123*33f37583SAndroid Build Coastguard Worker Result<bool> SupportsFsCheckpoints() override {
124*33f37583SAndroid Build Coastguard Worker return supports_fs_checkpoint_;
125*33f37583SAndroid Build Coastguard Worker }
126*33f37583SAndroid Build Coastguard Worker
NeedsCheckpoint()127*33f37583SAndroid Build Coastguard Worker Result<bool> NeedsCheckpoint() override { return needs_checkpoint_; }
128*33f37583SAndroid Build Coastguard Worker
NeedsRollback()129*33f37583SAndroid Build Coastguard Worker Result<bool> NeedsRollback() override { return needs_rollback_; }
130*33f37583SAndroid Build Coastguard Worker
AbortChanges(const std::string & msg,bool retry)131*33f37583SAndroid Build Coastguard Worker Result<void> AbortChanges(const std::string& msg, bool retry) override {
132*33f37583SAndroid Build Coastguard Worker return {};
133*33f37583SAndroid Build Coastguard Worker }
134*33f37583SAndroid Build Coastguard Worker
SetSupportsCheckpoint(bool value)135*33f37583SAndroid Build Coastguard Worker void SetSupportsCheckpoint(bool value) { supports_fs_checkpoint_ = value; }
136*33f37583SAndroid Build Coastguard Worker
SetNeedsCheckpoint(bool value)137*33f37583SAndroid Build Coastguard Worker void SetNeedsCheckpoint(bool value) { needs_checkpoint_ = value; }
138*33f37583SAndroid Build Coastguard Worker
SetNeedsRollback(bool value)139*33f37583SAndroid Build Coastguard Worker void SetNeedsRollback(bool value) { needs_rollback_ = value; }
140*33f37583SAndroid Build Coastguard Worker
141*33f37583SAndroid Build Coastguard Worker private:
142*33f37583SAndroid Build Coastguard Worker bool supports_fs_checkpoint_, needs_checkpoint_, needs_rollback_;
143*33f37583SAndroid Build Coastguard Worker };
144*33f37583SAndroid Build Coastguard Worker
145*33f37583SAndroid Build Coastguard Worker static constexpr const char* kTestApexdStatusSysprop = "apexd.status.test";
146*33f37583SAndroid Build Coastguard Worker static constexpr const char* kTestVmPayloadMetadataPartitionProp =
147*33f37583SAndroid Build Coastguard Worker "apexd.vm.payload_metadata_partition.test";
148*33f37583SAndroid Build Coastguard Worker
149*33f37583SAndroid Build Coastguard Worker static constexpr const char* kTestActiveApexSelinuxCtx =
150*33f37583SAndroid Build Coastguard Worker "u:object_r:shell_data_file:s0";
151*33f37583SAndroid Build Coastguard Worker
152*33f37583SAndroid Build Coastguard Worker // A test fixture that provides frequently required temp directories for tests
153*33f37583SAndroid Build Coastguard Worker class ApexdUnitTest : public ::testing::Test {
154*33f37583SAndroid Build Coastguard Worker public:
ApexdUnitTest()155*33f37583SAndroid Build Coastguard Worker ApexdUnitTest() {
156*33f37583SAndroid Build Coastguard Worker built_in_dir_ = StringPrintf("%s/pre-installed-apex", td_.path);
157*33f37583SAndroid Build Coastguard Worker partition_ = ApexPartition::System;
158*33f37583SAndroid Build Coastguard Worker partition_string_ = "SYSTEM";
159*33f37583SAndroid Build Coastguard Worker block_partition_string_ = "SYSTEM";
160*33f37583SAndroid Build Coastguard Worker data_dir_ = StringPrintf("%s/data-apex", td_.path);
161*33f37583SAndroid Build Coastguard Worker decompression_dir_ = StringPrintf("%s/decompressed-apex", td_.path);
162*33f37583SAndroid Build Coastguard Worker ota_reserved_dir_ = StringPrintf("%s/ota-reserved", td_.path);
163*33f37583SAndroid Build Coastguard Worker staged_session_dir_ = StringPrintf("%s/staged-session-dir", td_.path);
164*33f37583SAndroid Build Coastguard Worker
165*33f37583SAndroid Build Coastguard Worker sessions_metadata_dir_ =
166*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/metadata-staged-session-dir", td_.path);
167*33f37583SAndroid Build Coastguard Worker session_manager_ = ApexSessionManager::Create(sessions_metadata_dir_);
168*33f37583SAndroid Build Coastguard Worker
169*33f37583SAndroid Build Coastguard Worker config_ = {kTestApexdStatusSysprop,
170*33f37583SAndroid Build Coastguard Worker {{partition_, built_in_dir_}},
171*33f37583SAndroid Build Coastguard Worker data_dir_.c_str(),
172*33f37583SAndroid Build Coastguard Worker decompression_dir_.c_str(),
173*33f37583SAndroid Build Coastguard Worker ota_reserved_dir_.c_str(),
174*33f37583SAndroid Build Coastguard Worker staged_session_dir_.c_str(),
175*33f37583SAndroid Build Coastguard Worker kTestVmPayloadMetadataPartitionProp,
176*33f37583SAndroid Build Coastguard Worker kTestActiveApexSelinuxCtx};
177*33f37583SAndroid Build Coastguard Worker }
178*33f37583SAndroid Build Coastguard Worker
GetBuiltInDir()179*33f37583SAndroid Build Coastguard Worker const std::string& GetBuiltInDir() { return built_in_dir_; }
GetPartition()180*33f37583SAndroid Build Coastguard Worker ApexPartition GetPartition() { return partition_; }
GetPartitionString()181*33f37583SAndroid Build Coastguard Worker const std::string& GetPartitionString() { return partition_string_; }
GetBlockPartitionString()182*33f37583SAndroid Build Coastguard Worker const std::string& GetBlockPartitionString() {
183*33f37583SAndroid Build Coastguard Worker return block_partition_string_;
184*33f37583SAndroid Build Coastguard Worker }
GetDataDir()185*33f37583SAndroid Build Coastguard Worker const std::string& GetDataDir() { return data_dir_; }
GetDecompressionDir()186*33f37583SAndroid Build Coastguard Worker const std::string& GetDecompressionDir() { return decompression_dir_; }
GetOtaReservedDir()187*33f37583SAndroid Build Coastguard Worker const std::string& GetOtaReservedDir() { return ota_reserved_dir_; }
GetStagedDir(int session_id)188*33f37583SAndroid Build Coastguard Worker const std::string GetStagedDir(int session_id) {
189*33f37583SAndroid Build Coastguard Worker return StringPrintf("%s/session_%d", staged_session_dir_.c_str(),
190*33f37583SAndroid Build Coastguard Worker session_id);
191*33f37583SAndroid Build Coastguard Worker }
GetSessionManager()192*33f37583SAndroid Build Coastguard Worker ApexSessionManager* GetSessionManager() { return session_manager_.get(); }
193*33f37583SAndroid Build Coastguard Worker
GetRootDigest(const ApexFile & apex)194*33f37583SAndroid Build Coastguard Worker std::string GetRootDigest(const ApexFile& apex) {
195*33f37583SAndroid Build Coastguard Worker if (apex.IsCompressed()) {
196*33f37583SAndroid Build Coastguard Worker return "";
197*33f37583SAndroid Build Coastguard Worker }
198*33f37583SAndroid Build Coastguard Worker auto digest = apex.VerifyApexVerity(apex.GetBundledPublicKey());
199*33f37583SAndroid Build Coastguard Worker if (!digest.ok()) {
200*33f37583SAndroid Build Coastguard Worker return "";
201*33f37583SAndroid Build Coastguard Worker }
202*33f37583SAndroid Build Coastguard Worker return digest->root_digest;
203*33f37583SAndroid Build Coastguard Worker }
204*33f37583SAndroid Build Coastguard Worker
AddPreInstalledApex(const std::string & apex_name)205*33f37583SAndroid Build Coastguard Worker std::string AddPreInstalledApex(const std::string& apex_name) {
206*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(apex_name), built_in_dir_);
207*33f37583SAndroid Build Coastguard Worker return StringPrintf("%s/%s", built_in_dir_.c_str(), apex_name.c_str());
208*33f37583SAndroid Build Coastguard Worker }
209*33f37583SAndroid Build Coastguard Worker
AddDataApex(const std::string & apex_name)210*33f37583SAndroid Build Coastguard Worker std::string AddDataApex(const std::string& apex_name) {
211*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(apex_name), data_dir_);
212*33f37583SAndroid Build Coastguard Worker return StringPrintf("%s/%s", data_dir_.c_str(), apex_name.c_str());
213*33f37583SAndroid Build Coastguard Worker }
214*33f37583SAndroid Build Coastguard Worker
AddDataApex(const std::string & apex_name,const std::string & target_name)215*33f37583SAndroid Build Coastguard Worker std::string AddDataApex(const std::string& apex_name,
216*33f37583SAndroid Build Coastguard Worker const std::string& target_name) {
217*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(apex_name), data_dir_ + "/" + target_name);
218*33f37583SAndroid Build Coastguard Worker return StringPrintf("%s/%s", data_dir_.c_str(), target_name.c_str());
219*33f37583SAndroid Build Coastguard Worker }
220*33f37583SAndroid Build Coastguard Worker
AddDecompressedApex(const std::string & apex_name)221*33f37583SAndroid Build Coastguard Worker std::string AddDecompressedApex(const std::string& apex_name) {
222*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(GetTestFile(apex_name));
223*33f37583SAndroid Build Coastguard Worker CHECK(apex_file.ok());
224*33f37583SAndroid Build Coastguard Worker std::string target_name =
225*33f37583SAndroid Build Coastguard Worker apex_file->GetManifest().name() + "@" +
226*33f37583SAndroid Build Coastguard Worker std::to_string(apex_file->GetManifest().version()) +
227*33f37583SAndroid Build Coastguard Worker std::string(kDecompressedApexPackageSuffix);
228*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(apex_name), decompression_dir_ + "/" + target_name);
229*33f37583SAndroid Build Coastguard Worker return StringPrintf("%s/%s", decompression_dir_.c_str(),
230*33f37583SAndroid Build Coastguard Worker target_name.c_str());
231*33f37583SAndroid Build Coastguard Worker }
232*33f37583SAndroid Build Coastguard Worker
233*33f37583SAndroid Build Coastguard Worker // Copies the compressed apex to |built_in_dir| and decompresses it to
234*33f37583SAndroid Build Coastguard Worker // |decompressed_dir| and then hard links to |target_dir|
PrepareCompressedApex(const std::string & name,const std::string & built_in_dir)235*33f37583SAndroid Build Coastguard Worker std::string PrepareCompressedApex(const std::string& name,
236*33f37583SAndroid Build Coastguard Worker const std::string& built_in_dir) {
237*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(name), built_in_dir);
238*33f37583SAndroid Build Coastguard Worker auto compressed_apex = ApexFile::Open(
239*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/%s", built_in_dir.c_str(), name.c_str()));
240*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
241*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex));
242*33f37583SAndroid Build Coastguard Worker auto return_value =
243*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /*is_ota_chroot*/ false);
244*33f37583SAndroid Build Coastguard Worker return StringPrintf("%s/%s", built_in_dir.c_str(), name.c_str());
245*33f37583SAndroid Build Coastguard Worker }
246*33f37583SAndroid Build Coastguard Worker
PrepareCompressedApex(const std::string & name)247*33f37583SAndroid Build Coastguard Worker std::string PrepareCompressedApex(const std::string& name) {
248*33f37583SAndroid Build Coastguard Worker return PrepareCompressedApex(name, built_in_dir_);
249*33f37583SAndroid Build Coastguard Worker }
250*33f37583SAndroid Build Coastguard Worker
PrepareStagedSession(const std::string & apex_name,int session_id)251*33f37583SAndroid Build Coastguard Worker void PrepareStagedSession(const std::string& apex_name, int session_id) {
252*33f37583SAndroid Build Coastguard Worker CreateDirIfNeeded(GetStagedDir(session_id), 0755);
253*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(apex_name), GetStagedDir(session_id));
254*33f37583SAndroid Build Coastguard Worker }
255*33f37583SAndroid Build Coastguard Worker
CreateStagedSession(const std::string & apex_name,int session_id)256*33f37583SAndroid Build Coastguard Worker Result<ApexSession> CreateStagedSession(const std::string& apex_name,
257*33f37583SAndroid Build Coastguard Worker int session_id) {
258*33f37583SAndroid Build Coastguard Worker PrepareStagedSession(apex_name, session_id);
259*33f37583SAndroid Build Coastguard Worker auto result = session_manager_->CreateSession(session_id);
260*33f37583SAndroid Build Coastguard Worker if (!result.ok()) {
261*33f37583SAndroid Build Coastguard Worker return result.error();
262*33f37583SAndroid Build Coastguard Worker }
263*33f37583SAndroid Build Coastguard Worker result->SetBuildFingerprint(GetProperty("ro.build.fingerprint", ""));
264*33f37583SAndroid Build Coastguard Worker return result;
265*33f37583SAndroid Build Coastguard Worker }
266*33f37583SAndroid Build Coastguard Worker
267*33f37583SAndroid Build Coastguard Worker protected:
SetUp()268*33f37583SAndroid Build Coastguard Worker void SetUp() override {
269*33f37583SAndroid Build Coastguard Worker SetConfig(config_);
270*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().Reset(decompression_dir_);
271*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir(built_in_dir_.c_str(), 0755), 0);
272*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir(data_dir_.c_str(), 0755), 0);
273*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir(decompression_dir_.c_str(), 0755), 0);
274*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir(ota_reserved_dir_.c_str(), 0755), 0);
275*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir(staged_session_dir_.c_str(), 0755), 0);
276*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir(sessions_metadata_dir_.c_str(), 0755), 0);
277*33f37583SAndroid Build Coastguard Worker
278*33f37583SAndroid Build Coastguard Worker // We don't really need for all the test cases, but until we refactor apexd
279*33f37583SAndroid Build Coastguard Worker // to use dependency injection instead of this SetConfig approach, it is not
280*33f37583SAndroid Build Coastguard Worker // trivial to figure out which test cases need the session manager, so we
281*33f37583SAndroid Build Coastguard Worker // initialize it for all of them.
282*33f37583SAndroid Build Coastguard Worker InitializeSessionManager(GetSessionManager());
283*33f37583SAndroid Build Coastguard Worker DeleteDirContent(GetSessionsDir());
284*33f37583SAndroid Build Coastguard Worker }
285*33f37583SAndroid Build Coastguard Worker
TearDown()286*33f37583SAndroid Build Coastguard Worker void TearDown() override { DeleteDirContent(GetSessionsDir()); }
287*33f37583SAndroid Build Coastguard Worker
288*33f37583SAndroid Build Coastguard Worker protected:
289*33f37583SAndroid Build Coastguard Worker TemporaryDir td_;
290*33f37583SAndroid Build Coastguard Worker std::string built_in_dir_;
291*33f37583SAndroid Build Coastguard Worker ApexPartition partition_;
292*33f37583SAndroid Build Coastguard Worker std::string partition_string_;
293*33f37583SAndroid Build Coastguard Worker std::string block_partition_string_;
294*33f37583SAndroid Build Coastguard Worker std::string data_dir_;
295*33f37583SAndroid Build Coastguard Worker std::string decompression_dir_;
296*33f37583SAndroid Build Coastguard Worker std::string ota_reserved_dir_;
297*33f37583SAndroid Build Coastguard Worker
298*33f37583SAndroid Build Coastguard Worker std::string staged_session_dir_;
299*33f37583SAndroid Build Coastguard Worker std::string sessions_metadata_dir_;
300*33f37583SAndroid Build Coastguard Worker std::unique_ptr<ApexSessionManager> session_manager_;
301*33f37583SAndroid Build Coastguard Worker
302*33f37583SAndroid Build Coastguard Worker ApexdConfig config_;
303*33f37583SAndroid Build Coastguard Worker };
304*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,SelectApexForActivationSuccess)305*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, SelectApexForActivationSuccess) {
306*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
307*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.cts.shim.apex");
308*33f37583SAndroid Build Coastguard Worker auto shared_lib_1 = ApexFile::Open(AddPreInstalledApex(
309*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
310*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
311*33f37583SAndroid Build Coastguard Worker // Pre-installed data needs to be present so that we can add data apex
312*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
313*33f37583SAndroid Build Coastguard Worker Ok());
314*33f37583SAndroid Build Coastguard Worker
315*33f37583SAndroid Build Coastguard Worker auto apexd_test_file = ApexFile::Open(AddDataApex("apex.apexd_test.apex"));
316*33f37583SAndroid Build Coastguard Worker auto shim_v1 = ApexFile::Open(AddDataApex("com.android.apex.cts.shim.apex"));
317*33f37583SAndroid Build Coastguard Worker // Normally both pre-installed and data apex would be activated for a shared
318*33f37583SAndroid Build Coastguard Worker // libs apex, but if they are the same version only the data apex will be.
319*33f37583SAndroid Build Coastguard Worker auto shared_lib_2 = ApexFile::Open(
320*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
321*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
322*33f37583SAndroid Build Coastguard Worker
323*33f37583SAndroid Build Coastguard Worker const auto all_apex = instance.AllApexFilesByName();
324*33f37583SAndroid Build Coastguard Worker // Pass a blank instance so that no apex file is considered
325*33f37583SAndroid Build Coastguard Worker // pre-installed
326*33f37583SAndroid Build Coastguard Worker const ApexFileRepository instance_blank;
327*33f37583SAndroid Build Coastguard Worker auto result = SelectApexForActivation(all_apex, instance_blank);
328*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(result.size(), 6u);
329*33f37583SAndroid Build Coastguard Worker // When passed proper instance they should get selected
330*33f37583SAndroid Build Coastguard Worker result = SelectApexForActivation(all_apex, instance);
331*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(result.size(), 3u);
332*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, UnorderedElementsAre(ApexFileEq(ByRef(*apexd_test_file)),
333*33f37583SAndroid Build Coastguard Worker ApexFileEq(ByRef(*shim_v1)),
334*33f37583SAndroid Build Coastguard Worker ApexFileEq(ByRef(*shared_lib_2))));
335*33f37583SAndroid Build Coastguard Worker }
336*33f37583SAndroid Build Coastguard Worker
337*33f37583SAndroid Build Coastguard Worker // Higher version gets priority when selecting for activation
TEST_F(ApexdUnitTest,HigherVersionOfApexIsSelected)338*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, HigherVersionOfApexIsSelected) {
339*33f37583SAndroid Build Coastguard Worker auto apexd_test_file_v2 =
340*33f37583SAndroid Build Coastguard Worker ApexFile::Open(AddPreInstalledApex("apex.apexd_test_v2.apex"));
341*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.cts.shim.apex");
342*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
343*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
344*33f37583SAndroid Build Coastguard Worker Ok());
345*33f37583SAndroid Build Coastguard Worker
346*33f37583SAndroid Build Coastguard Worker TemporaryDir data_dir;
347*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test.apex");
348*33f37583SAndroid Build Coastguard Worker auto shim_v2 =
349*33f37583SAndroid Build Coastguard Worker ApexFile::Open(AddDataApex("com.android.apex.cts.shim.v2.apex"));
350*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
351*33f37583SAndroid Build Coastguard Worker
352*33f37583SAndroid Build Coastguard Worker auto all_apex = instance.AllApexFilesByName();
353*33f37583SAndroid Build Coastguard Worker auto result = SelectApexForActivation(all_apex, instance);
354*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(result.size(), 2u);
355*33f37583SAndroid Build Coastguard Worker
356*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result,
357*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexFileEq(ByRef(*apexd_test_file_v2)),
358*33f37583SAndroid Build Coastguard Worker ApexFileEq(ByRef(*shim_v2))));
359*33f37583SAndroid Build Coastguard Worker }
360*33f37583SAndroid Build Coastguard Worker
361*33f37583SAndroid Build Coastguard Worker // When versions are equal, non-pre-installed version gets priority
TEST_F(ApexdUnitTest,DataApexGetsPriorityForSameVersions)362*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, DataApexGetsPriorityForSameVersions) {
363*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
364*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.cts.shim.apex");
365*33f37583SAndroid Build Coastguard Worker // Initialize pre-installed APEX information
366*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
367*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
368*33f37583SAndroid Build Coastguard Worker Ok());
369*33f37583SAndroid Build Coastguard Worker
370*33f37583SAndroid Build Coastguard Worker auto apexd_test_file = ApexFile::Open(AddDataApex("apex.apexd_test.apex"));
371*33f37583SAndroid Build Coastguard Worker auto shim_v1 = ApexFile::Open(AddDataApex("com.android.apex.cts.shim.apex"));
372*33f37583SAndroid Build Coastguard Worker // Initialize ApexFile repo
373*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
374*33f37583SAndroid Build Coastguard Worker
375*33f37583SAndroid Build Coastguard Worker auto all_apex = instance.AllApexFilesByName();
376*33f37583SAndroid Build Coastguard Worker auto result = SelectApexForActivation(all_apex, instance);
377*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(result.size(), 2u);
378*33f37583SAndroid Build Coastguard Worker
379*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, UnorderedElementsAre(ApexFileEq(ByRef(*apexd_test_file)),
380*33f37583SAndroid Build Coastguard Worker ApexFileEq(ByRef(*shim_v1))));
381*33f37583SAndroid Build Coastguard Worker }
382*33f37583SAndroid Build Coastguard Worker
383*33f37583SAndroid Build Coastguard Worker // Both versions of shared libs can be selected when preinstalled version is
384*33f37583SAndroid Build Coastguard Worker // lower than data version
TEST_F(ApexdUnitTest,SharedLibsCanHaveBothVersionSelected)385*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, SharedLibsCanHaveBothVersionSelected) {
386*33f37583SAndroid Build Coastguard Worker auto shared_lib_v1 = ApexFile::Open(AddPreInstalledApex(
387*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
388*33f37583SAndroid Build Coastguard Worker // Initialize pre-installed APEX information
389*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
390*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
391*33f37583SAndroid Build Coastguard Worker Ok());
392*33f37583SAndroid Build Coastguard Worker
393*33f37583SAndroid Build Coastguard Worker auto shared_lib_v2 = ApexFile::Open(
394*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex"));
395*33f37583SAndroid Build Coastguard Worker // Initialize data APEX information
396*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
397*33f37583SAndroid Build Coastguard Worker
398*33f37583SAndroid Build Coastguard Worker auto all_apex = instance.AllApexFilesByName();
399*33f37583SAndroid Build Coastguard Worker auto result = SelectApexForActivation(all_apex, instance);
400*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(result.size(), 2u);
401*33f37583SAndroid Build Coastguard Worker
402*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, UnorderedElementsAre(ApexFileEq(ByRef(*shared_lib_v1)),
403*33f37583SAndroid Build Coastguard Worker ApexFileEq(ByRef(*shared_lib_v2))));
404*33f37583SAndroid Build Coastguard Worker }
405*33f37583SAndroid Build Coastguard Worker
406*33f37583SAndroid Build Coastguard Worker // Data version of shared libs should not be selected if lower than
407*33f37583SAndroid Build Coastguard Worker // preinstalled version
TEST_F(ApexdUnitTest,SharedLibsDataVersionDeletedIfLower)408*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, SharedLibsDataVersionDeletedIfLower) {
409*33f37583SAndroid Build Coastguard Worker auto shared_lib_v2 = ApexFile::Open(AddPreInstalledApex(
410*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v2.libvY.apex"));
411*33f37583SAndroid Build Coastguard Worker // Initialize pre-installed APEX information
412*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
413*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
414*33f37583SAndroid Build Coastguard Worker Ok());
415*33f37583SAndroid Build Coastguard Worker
416*33f37583SAndroid Build Coastguard Worker auto shared_lib_v1 = ApexFile::Open(
417*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
418*33f37583SAndroid Build Coastguard Worker // Initialize data APEX information
419*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
420*33f37583SAndroid Build Coastguard Worker
421*33f37583SAndroid Build Coastguard Worker auto all_apex = instance.AllApexFilesByName();
422*33f37583SAndroid Build Coastguard Worker auto result = SelectApexForActivation(all_apex, instance);
423*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(result.size(), 1u);
424*33f37583SAndroid Build Coastguard Worker
425*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, UnorderedElementsAre(ApexFileEq(ByRef(*shared_lib_v2))));
426*33f37583SAndroid Build Coastguard Worker }
427*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ProcessCompressedApex)428*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ProcessCompressedApex) {
429*33f37583SAndroid Build Coastguard Worker auto compressed_apex = ApexFile::Open(
430*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
431*33f37583SAndroid Build Coastguard Worker
432*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
433*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex));
434*33f37583SAndroid Build Coastguard Worker auto return_value =
435*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
436*33f37583SAndroid Build Coastguard Worker
437*33f37583SAndroid Build Coastguard Worker std::string decompressed_file_path = StringPrintf(
438*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
439*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
440*33f37583SAndroid Build Coastguard Worker // Assert output path is not empty
441*33f37583SAndroid Build Coastguard Worker auto exists = PathExists(decompressed_file_path);
442*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(exists, HasValue(true));
443*33f37583SAndroid Build Coastguard Worker
444*33f37583SAndroid Build Coastguard Worker // Assert that return value contains decompressed APEX
445*33f37583SAndroid Build Coastguard Worker auto decompressed_apex = ApexFile::Open(decompressed_file_path);
446*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(return_value,
447*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexFileEq(ByRef(*decompressed_apex))));
448*33f37583SAndroid Build Coastguard Worker }
449*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ProcessCompressedApexRunsVerification)450*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ProcessCompressedApexRunsVerification) {
451*33f37583SAndroid Build Coastguard Worker auto compressed_apex_mismatch_key = ApexFile::Open(AddPreInstalledApex(
452*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed_key_mismatch_with_original.capex"));
453*33f37583SAndroid Build Coastguard Worker auto compressed_apex_version_mismatch = ApexFile::Open(
454*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1_with_v2_apex.capex"));
455*33f37583SAndroid Build Coastguard Worker
456*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
457*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex_mismatch_key));
458*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(
459*33f37583SAndroid Build Coastguard Worker std::cref(*compressed_apex_version_mismatch));
460*33f37583SAndroid Build Coastguard Worker auto return_value =
461*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
462*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 0u);
463*33f37583SAndroid Build Coastguard Worker }
464*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ValidateDecompressedApex)465*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ValidateDecompressedApex) {
466*33f37583SAndroid Build Coastguard Worker auto capex = ApexFile::Open(
467*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
468*33f37583SAndroid Build Coastguard Worker auto decompressed_v1 =
469*33f37583SAndroid Build Coastguard Worker ApexFile::Open(AddDataApex("com.android.apex.compressed.v1.apex"));
470*33f37583SAndroid Build Coastguard Worker
471*33f37583SAndroid Build Coastguard Worker auto result =
472*33f37583SAndroid Build Coastguard Worker ValidateDecompressedApex(std::cref(*capex), std::cref(*decompressed_v1));
473*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
474*33f37583SAndroid Build Coastguard Worker
475*33f37583SAndroid Build Coastguard Worker // Validation checks version
476*33f37583SAndroid Build Coastguard Worker auto decompressed_v2 = ApexFile::Open(
477*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v2_original.apex"));
478*33f37583SAndroid Build Coastguard Worker result =
479*33f37583SAndroid Build Coastguard Worker ValidateDecompressedApex(std::cref(*capex), std::cref(*decompressed_v2));
480*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
481*33f37583SAndroid Build Coastguard Worker result,
482*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
483*33f37583SAndroid Build Coastguard Worker "Compressed APEX has different version than decompressed APEX"))));
484*33f37583SAndroid Build Coastguard Worker
485*33f37583SAndroid Build Coastguard Worker // Validation check root digest
486*33f37583SAndroid Build Coastguard Worker auto decompressed_v1_different_digest = ApexFile::Open(AddDataApex(
487*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed.v1_different_digest_original.apex"));
488*33f37583SAndroid Build Coastguard Worker result = ValidateDecompressedApex(
489*33f37583SAndroid Build Coastguard Worker std::cref(*capex), std::cref(*decompressed_v1_different_digest));
490*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
491*33f37583SAndroid Build Coastguard Worker "does not match with expected root digest"))));
492*33f37583SAndroid Build Coastguard Worker
493*33f37583SAndroid Build Coastguard Worker // Validation checks key
494*33f37583SAndroid Build Coastguard Worker auto capex_different_key = ApexFile::Open(
495*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed_different_key.capex"));
496*33f37583SAndroid Build Coastguard Worker result = ValidateDecompressedApex(std::cref(*capex_different_key),
497*33f37583SAndroid Build Coastguard Worker std::cref(*decompressed_v1));
498*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
499*33f37583SAndroid Build Coastguard Worker result,
500*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
501*33f37583SAndroid Build Coastguard Worker "Public key of compressed APEX is different than original"))));
502*33f37583SAndroid Build Coastguard Worker }
503*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ProcessCompressedApexCanBeCalledMultipleTimes)504*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ProcessCompressedApexCanBeCalledMultipleTimes) {
505*33f37583SAndroid Build Coastguard Worker auto compressed_apex = ApexFile::Open(
506*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
507*33f37583SAndroid Build Coastguard Worker
508*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
509*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex));
510*33f37583SAndroid Build Coastguard Worker auto return_value =
511*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
512*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 1u);
513*33f37583SAndroid Build Coastguard Worker
514*33f37583SAndroid Build Coastguard Worker // Capture the creation time of the decompressed APEX
515*33f37583SAndroid Build Coastguard Worker std::error_code ec;
516*33f37583SAndroid Build Coastguard Worker auto decompressed_apex_path = StringPrintf(
517*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
518*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
519*33f37583SAndroid Build Coastguard Worker auto last_write_time_1 = fs::last_write_time(decompressed_apex_path, ec);
520*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(ec) << "Failed to capture last write time of "
521*33f37583SAndroid Build Coastguard Worker << decompressed_apex_path;
522*33f37583SAndroid Build Coastguard Worker
523*33f37583SAndroid Build Coastguard Worker // Now try to decompress the same capex again. It should not fail.
524*33f37583SAndroid Build Coastguard Worker return_value =
525*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
526*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 1u);
527*33f37583SAndroid Build Coastguard Worker
528*33f37583SAndroid Build Coastguard Worker // Ensure the decompressed APEX file did not change
529*33f37583SAndroid Build Coastguard Worker auto last_write_time_2 = fs::last_write_time(decompressed_apex_path, ec);
530*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(ec) << "Failed to capture last write time of "
531*33f37583SAndroid Build Coastguard Worker << decompressed_apex_path;
532*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(last_write_time_1, last_write_time_2);
533*33f37583SAndroid Build Coastguard Worker }
534*33f37583SAndroid Build Coastguard Worker
535*33f37583SAndroid Build Coastguard Worker // Test behavior of ProcessCompressedApex when is_ota_chroot is true
TEST_F(ApexdUnitTest,ProcessCompressedApexOnOtaChroot)536*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ProcessCompressedApexOnOtaChroot) {
537*33f37583SAndroid Build Coastguard Worker auto compressed_apex = ApexFile::Open(
538*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
539*33f37583SAndroid Build Coastguard Worker
540*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
541*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex));
542*33f37583SAndroid Build Coastguard Worker auto return_value =
543*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ true);
544*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 1u);
545*33f37583SAndroid Build Coastguard Worker
546*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be located in decompression_dir
547*33f37583SAndroid Build Coastguard Worker std::string decompressed_file_path =
548*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
549*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
550*33f37583SAndroid Build Coastguard Worker // Assert output path is not empty
551*33f37583SAndroid Build Coastguard Worker auto exists = PathExists(decompressed_file_path);
552*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(exists, HasValue(true))
553*33f37583SAndroid Build Coastguard Worker << decompressed_file_path << " does not exist";
554*33f37583SAndroid Build Coastguard Worker
555*33f37583SAndroid Build Coastguard Worker // Assert that return value contains the decompressed APEX
556*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(decompressed_file_path);
557*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(return_value,
558*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexFileEq(ByRef(*apex_file))));
559*33f37583SAndroid Build Coastguard Worker }
560*33f37583SAndroid Build Coastguard Worker
561*33f37583SAndroid Build Coastguard Worker // When decompressing APEX, reuse existing OTA APEX
TEST_F(ApexdUnitTest,ProcessCompressedApexReuseOtaApex)562*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ProcessCompressedApexReuseOtaApex) {
563*33f37583SAndroid Build Coastguard Worker // Push a compressed APEX that will fail to decompress
564*33f37583SAndroid Build Coastguard Worker auto compressed_apex = ApexFile::Open(AddPreInstalledApex(
565*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed.v1_not_decompressible.capex"));
566*33f37583SAndroid Build Coastguard Worker
567*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
568*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex));
569*33f37583SAndroid Build Coastguard Worker
570*33f37583SAndroid Build Coastguard Worker // If we try to decompress capex directly, it should fail since the capex
571*33f37583SAndroid Build Coastguard Worker // pushed is faulty and cannot be decompressed
572*33f37583SAndroid Build Coastguard Worker auto return_value =
573*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
574*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 0u);
575*33f37583SAndroid Build Coastguard Worker
576*33f37583SAndroid Build Coastguard Worker // But, if there is an ota_apex present for reuse, it should reuse that
577*33f37583SAndroid Build Coastguard Worker // and avoid decompressing the faulty capex
578*33f37583SAndroid Build Coastguard Worker
579*33f37583SAndroid Build Coastguard Worker // Push an OTA apex that should be reused to skip decompression
580*33f37583SAndroid Build Coastguard Worker auto ota_apex_path =
581*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
582*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
583*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v1.apex"), ota_apex_path);
584*33f37583SAndroid Build Coastguard Worker return_value =
585*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
586*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 1u);
587*33f37583SAndroid Build Coastguard Worker
588*33f37583SAndroid Build Coastguard Worker // Ota Apex should be cleaned up
589*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(PathExists(ota_apex_path), HasValue(false));
590*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value[0].GetPath(),
591*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
592*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(),
593*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix));
594*33f37583SAndroid Build Coastguard Worker }
595*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ShouldAllocateSpaceForDecompressionNewApex)596*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ShouldAllocateSpaceForDecompressionNewApex) {
597*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
598*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
599*33f37583SAndroid Build Coastguard Worker Ok());
600*33f37583SAndroid Build Coastguard Worker
601*33f37583SAndroid Build Coastguard Worker // A brand new compressed APEX is being introduced: selected
602*33f37583SAndroid Build Coastguard Worker bool result =
603*33f37583SAndroid Build Coastguard Worker ShouldAllocateSpaceForDecompression("com.android.brand.new", 1, instance);
604*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(result);
605*33f37583SAndroid Build Coastguard Worker }
606*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ShouldAllocateSpaceForDecompressionWasNotCompressedBefore)607*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest,
608*33f37583SAndroid Build Coastguard Worker ShouldAllocateSpaceForDecompressionWasNotCompressedBefore) {
609*33f37583SAndroid Build Coastguard Worker // Prepare fake pre-installed apex
610*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
611*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
612*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
613*33f37583SAndroid Build Coastguard Worker Ok());
614*33f37583SAndroid Build Coastguard Worker
615*33f37583SAndroid Build Coastguard Worker // An existing pre-installed APEX is now compressed in the OTA: selected
616*33f37583SAndroid Build Coastguard Worker {
617*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
618*33f37583SAndroid Build Coastguard Worker "com.android.apex.test_package", 1, instance);
619*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(result);
620*33f37583SAndroid Build Coastguard Worker }
621*33f37583SAndroid Build Coastguard Worker
622*33f37583SAndroid Build Coastguard Worker // Even if there is a data apex (lower version)
623*33f37583SAndroid Build Coastguard Worker // Include data apex within calculation now
624*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_v2.apex");
625*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
626*33f37583SAndroid Build Coastguard Worker {
627*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
628*33f37583SAndroid Build Coastguard Worker "com.android.apex.test_package", 3, instance);
629*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(result);
630*33f37583SAndroid Build Coastguard Worker }
631*33f37583SAndroid Build Coastguard Worker
632*33f37583SAndroid Build Coastguard Worker // But not if data apex has equal or higher version
633*33f37583SAndroid Build Coastguard Worker {
634*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
635*33f37583SAndroid Build Coastguard Worker "com.android.apex.test_package", 2, instance);
636*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(result);
637*33f37583SAndroid Build Coastguard Worker }
638*33f37583SAndroid Build Coastguard Worker }
639*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ShouldAllocateSpaceForDecompressionVersionCompare)640*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ShouldAllocateSpaceForDecompressionVersionCompare) {
641*33f37583SAndroid Build Coastguard Worker // Prepare fake pre-installed apex
642*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex");
643*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
644*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
645*33f37583SAndroid Build Coastguard Worker Ok());
646*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
647*33f37583SAndroid Build Coastguard Worker
648*33f37583SAndroid Build Coastguard Worker {
649*33f37583SAndroid Build Coastguard Worker // New Compressed apex has higher version than decompressed data apex:
650*33f37583SAndroid Build Coastguard Worker // selected
651*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
652*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed", 2, instance);
653*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(result)
654*33f37583SAndroid Build Coastguard Worker << "Higher version test with decompressed data returned false";
655*33f37583SAndroid Build Coastguard Worker }
656*33f37583SAndroid Build Coastguard Worker
657*33f37583SAndroid Build Coastguard Worker // Compare against decompressed data apex
658*33f37583SAndroid Build Coastguard Worker {
659*33f37583SAndroid Build Coastguard Worker // New Compressed apex has same version as decompressed data apex: not
660*33f37583SAndroid Build Coastguard Worker // selected
661*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
662*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed", 1, instance);
663*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(result)
664*33f37583SAndroid Build Coastguard Worker << "Same version test with decompressed data returned true";
665*33f37583SAndroid Build Coastguard Worker }
666*33f37583SAndroid Build Coastguard Worker
667*33f37583SAndroid Build Coastguard Worker {
668*33f37583SAndroid Build Coastguard Worker // New Compressed apex has lower version than decompressed data apex:
669*33f37583SAndroid Build Coastguard Worker // selected
670*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
671*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed", 0, instance);
672*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(result)
673*33f37583SAndroid Build Coastguard Worker << "lower version test with decompressed data returned false";
674*33f37583SAndroid Build Coastguard Worker }
675*33f37583SAndroid Build Coastguard Worker
676*33f37583SAndroid Build Coastguard Worker // Replace decompressed data apex with a higher version
677*33f37583SAndroid Build Coastguard Worker ApexFileRepository instance_new(GetDecompressionDir());
678*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
679*33f37583SAndroid Build Coastguard Worker instance_new.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
680*33f37583SAndroid Build Coastguard Worker Ok());
681*33f37583SAndroid Build Coastguard Worker TemporaryDir data_dir_new;
682*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v2_original.apex"),
683*33f37583SAndroid Build Coastguard Worker data_dir_new.path);
684*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance_new.AddDataApex(data_dir_new.path), Ok());
685*33f37583SAndroid Build Coastguard Worker
686*33f37583SAndroid Build Coastguard Worker {
687*33f37583SAndroid Build Coastguard Worker // New Compressed apex has higher version as data apex: selected
688*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
689*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed", 3, instance_new);
690*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(result) << "Higher version test with new data returned false";
691*33f37583SAndroid Build Coastguard Worker }
692*33f37583SAndroid Build Coastguard Worker
693*33f37583SAndroid Build Coastguard Worker {
694*33f37583SAndroid Build Coastguard Worker // New Compressed apex has same version as data apex: not selected
695*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
696*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed", 2, instance_new);
697*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(result) << "Same version test with new data returned true";
698*33f37583SAndroid Build Coastguard Worker }
699*33f37583SAndroid Build Coastguard Worker
700*33f37583SAndroid Build Coastguard Worker {
701*33f37583SAndroid Build Coastguard Worker // New Compressed apex has lower version than data apex: not selected
702*33f37583SAndroid Build Coastguard Worker bool result = ShouldAllocateSpaceForDecompression(
703*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed", 1, instance_new);
704*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(result) << "lower version test with new data returned true";
705*33f37583SAndroid Build Coastguard Worker }
706*33f37583SAndroid Build Coastguard Worker }
707*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,CalculateSizeForCompressedApexEmptyList)708*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, CalculateSizeForCompressedApexEmptyList) {
709*33f37583SAndroid Build Coastguard Worker ApexFileRepository instance;
710*33f37583SAndroid Build Coastguard Worker int64_t result = CalculateSizeForCompressedApex({}, instance);
711*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0LL, result);
712*33f37583SAndroid Build Coastguard Worker }
713*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,CalculateSizeForCompressedApex)714*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, CalculateSizeForCompressedApex) {
715*33f37583SAndroid Build Coastguard Worker ApexFileRepository instance;
716*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
717*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
718*33f37583SAndroid Build Coastguard Worker Ok());
719*33f37583SAndroid Build Coastguard Worker
720*33f37583SAndroid Build Coastguard Worker std::vector<std::tuple<std::string, int64_t, int64_t>> input = {
721*33f37583SAndroid Build Coastguard Worker std::make_tuple("new_apex", 1, 1),
722*33f37583SAndroid Build Coastguard Worker std::make_tuple("new_apex_2", 1, 2),
723*33f37583SAndroid Build Coastguard Worker std::make_tuple("com.android.apex.compressed", 1, 4), // will be ignored
724*33f37583SAndroid Build Coastguard Worker std::make_tuple("com.android.apex.compressed", 2, 8),
725*33f37583SAndroid Build Coastguard Worker };
726*33f37583SAndroid Build Coastguard Worker int64_t result = CalculateSizeForCompressedApex(input, instance);
727*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1 + 2 + 8LL, result);
728*33f37583SAndroid Build Coastguard Worker }
729*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ReserveSpaceForCompressedApexCreatesSingleFile)730*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexCreatesSingleFile) {
731*33f37583SAndroid Build Coastguard Worker TemporaryDir dest_dir;
732*33f37583SAndroid Build Coastguard Worker // Reserving space should create a single file in dest_dir with exact size
733*33f37583SAndroid Build Coastguard Worker
734*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
735*33f37583SAndroid Build Coastguard Worker auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
736*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(files, Ok());
737*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(files->size(), 1u);
738*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(fs::file_size((*files)[0]), 100u);
739*33f37583SAndroid Build Coastguard Worker EXPECT_GE(GetSizeByBlocks((*files)[0]), 100u);
740*33f37583SAndroid Build Coastguard Worker }
741*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ReserveSpaceForCompressedApexSafeToCallMultipleTimes)742*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexSafeToCallMultipleTimes) {
743*33f37583SAndroid Build Coastguard Worker TemporaryDir dest_dir;
744*33f37583SAndroid Build Coastguard Worker // Calling ReserveSpaceForCompressedApex multiple times should still create
745*33f37583SAndroid Build Coastguard Worker // a single file
746*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
747*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
748*33f37583SAndroid Build Coastguard Worker auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
749*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(files, Ok());
750*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(files->size(), 1u);
751*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(fs::file_size((*files)[0]), 100u);
752*33f37583SAndroid Build Coastguard Worker EXPECT_GE(GetSizeByBlocks((*files)[0]), 100u);
753*33f37583SAndroid Build Coastguard Worker }
754*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ReserveSpaceForCompressedApexShrinkAndGrow)755*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexShrinkAndGrow) {
756*33f37583SAndroid Build Coastguard Worker TemporaryDir dest_dir;
757*33f37583SAndroid Build Coastguard Worker
758*33f37583SAndroid Build Coastguard Worker // Create a 100 byte file
759*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
760*33f37583SAndroid Build Coastguard Worker
761*33f37583SAndroid Build Coastguard Worker // Should be able to shrink and grow the reserved space
762*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(1000, dest_dir.path), Ok());
763*33f37583SAndroid Build Coastguard Worker
764*33f37583SAndroid Build Coastguard Worker auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
765*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(files, Ok());
766*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(files->size(), 1u);
767*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(fs::file_size((*files)[0]), 1000u);
768*33f37583SAndroid Build Coastguard Worker EXPECT_GE(GetSizeByBlocks((*files)[0]), 1000u);
769*33f37583SAndroid Build Coastguard Worker
770*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(10, dest_dir.path), Ok());
771*33f37583SAndroid Build Coastguard Worker files = ReadDir(dest_dir.path, [](auto _) { return true; });
772*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(files, Ok());
773*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(files->size(), 1u);
774*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(fs::file_size((*files)[0]), 10u);
775*33f37583SAndroid Build Coastguard Worker EXPECT_GE(GetSizeByBlocks((*files)[0]), 10u);
776*33f37583SAndroid Build Coastguard Worker }
777*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ReserveSpaceForCompressedApexDeallocateIfPassedZero)778*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexDeallocateIfPassedZero) {
779*33f37583SAndroid Build Coastguard Worker TemporaryDir dest_dir;
780*33f37583SAndroid Build Coastguard Worker
781*33f37583SAndroid Build Coastguard Worker // Create a file first
782*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
783*33f37583SAndroid Build Coastguard Worker auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
784*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(files, Ok());
785*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(files->size(), 1u);
786*33f37583SAndroid Build Coastguard Worker
787*33f37583SAndroid Build Coastguard Worker // Should delete the reserved file if size passed is 0
788*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(0, dest_dir.path), Ok());
789*33f37583SAndroid Build Coastguard Worker files = ReadDir(dest_dir.path, [](auto _) { return true; });
790*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(files, Ok());
791*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(files->size(), 0u);
792*33f37583SAndroid Build Coastguard Worker }
793*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ReserveSpaceForCapexCleansOtaApex)794*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ReserveSpaceForCapexCleansOtaApex) {
795*33f37583SAndroid Build Coastguard Worker TemporaryDir dest_dir;
796*33f37583SAndroid Build Coastguard Worker
797*33f37583SAndroid Build Coastguard Worker auto ota_apex_path = StringPrintf(
798*33f37583SAndroid Build Coastguard Worker "%s/ota_apex%s", GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
799*33f37583SAndroid Build Coastguard Worker auto create_ota_apex = [&]() {
800*33f37583SAndroid Build Coastguard Worker // Create an ota_apex first
801*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v1.apex"), ota_apex_path);
802*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(PathExists(ota_apex_path), HasValue(true));
803*33f37583SAndroid Build Coastguard Worker };
804*33f37583SAndroid Build Coastguard Worker create_ota_apex();
805*33f37583SAndroid Build Coastguard Worker
806*33f37583SAndroid Build Coastguard Worker // Should not delete the reserved file if size passed is negative
807*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(-1, dest_dir.path), Not(Ok()));
808*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(PathExists(ota_apex_path), HasValue(true));
809*33f37583SAndroid Build Coastguard Worker
810*33f37583SAndroid Build Coastguard Worker // Should delete the reserved file if size passed is 0
811*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(0, dest_dir.path), Ok());
812*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(PathExists(ota_apex_path), HasValue(false));
813*33f37583SAndroid Build Coastguard Worker
814*33f37583SAndroid Build Coastguard Worker create_ota_apex();
815*33f37583SAndroid Build Coastguard Worker // Should delete the reserved file if size passed is positive
816*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(10, dest_dir.path), Ok());
817*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(PathExists(ota_apex_path), HasValue(false));
818*33f37583SAndroid Build Coastguard Worker }
819*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ReserveSpaceForCompressedApexErrorForNegativeValue)820*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexErrorForNegativeValue) {
821*33f37583SAndroid Build Coastguard Worker TemporaryDir dest_dir;
822*33f37583SAndroid Build Coastguard Worker // Should return error if negative value is passed
823*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ReserveSpaceForCompressedApex(-1, dest_dir.path), Not(Ok()));
824*33f37583SAndroid Build Coastguard Worker }
825*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,GetStagedApexFilesNoChild)826*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, GetStagedApexFilesNoChild) {
827*33f37583SAndroid Build Coastguard Worker // Create staged session
828*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
829*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
830*33f37583SAndroid Build Coastguard Worker
831*33f37583SAndroid Build Coastguard Worker // Query for its file
832*33f37583SAndroid Build Coastguard Worker auto result = GetStagedApexFiles(123, {});
833*33f37583SAndroid Build Coastguard Worker
834*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(
835*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/apex.apexd_test.apex", GetStagedDir(123).c_str()));
836*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result,
837*33f37583SAndroid Build Coastguard Worker HasValue(UnorderedElementsAre(ApexFileEq(ByRef(*apex_file)))));
838*33f37583SAndroid Build Coastguard Worker }
839*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,GetStagedApexFilesOnlyStaged)840*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, GetStagedApexFilesOnlyStaged) {
841*33f37583SAndroid Build Coastguard Worker // Create staged session
842*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
843*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::VERIFIED);
844*33f37583SAndroid Build Coastguard Worker
845*33f37583SAndroid Build Coastguard Worker // Query for its file
846*33f37583SAndroid Build Coastguard Worker auto result = GetStagedApexFiles(123, {});
847*33f37583SAndroid Build Coastguard Worker
848*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
849*33f37583SAndroid Build Coastguard Worker result,
850*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr("Session 123 is not in state STAGED"))));
851*33f37583SAndroid Build Coastguard Worker }
852*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,GetStagedApexFilesChecksNumberOfApexFiles)853*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, GetStagedApexFilesChecksNumberOfApexFiles) {
854*33f37583SAndroid Build Coastguard Worker // Create staged session
855*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
856*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
857*33f37583SAndroid Build Coastguard Worker auto staged_dir = GetStagedDir(123);
858*33f37583SAndroid Build Coastguard Worker
859*33f37583SAndroid Build Coastguard Worker {
860*33f37583SAndroid Build Coastguard Worker // Delete the staged apex file
861*33f37583SAndroid Build Coastguard Worker DeleteDirContent(staged_dir);
862*33f37583SAndroid Build Coastguard Worker
863*33f37583SAndroid Build Coastguard Worker // Query for its file
864*33f37583SAndroid Build Coastguard Worker auto result = GetStagedApexFiles(123, {});
865*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
866*33f37583SAndroid Build Coastguard Worker "Expected exactly one APEX file in directory"))));
867*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, HasError(WithMessage(HasSubstr("Found: 0"))));
868*33f37583SAndroid Build Coastguard Worker }
869*33f37583SAndroid Build Coastguard Worker {
870*33f37583SAndroid Build Coastguard Worker // Copy multiple files to staged dir
871*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apex.apexd_test.apex"), staged_dir);
872*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apex.apexd_test_v2.apex"), staged_dir);
873*33f37583SAndroid Build Coastguard Worker
874*33f37583SAndroid Build Coastguard Worker // Query for its file
875*33f37583SAndroid Build Coastguard Worker auto result = GetStagedApexFiles(123, {});
876*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
877*33f37583SAndroid Build Coastguard Worker "Expected exactly one APEX file in directory"))));
878*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, HasError(WithMessage(HasSubstr("Found: 2"))));
879*33f37583SAndroid Build Coastguard Worker }
880*33f37583SAndroid Build Coastguard Worker }
881*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,GetStagedApexFilesWithChildren)882*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, GetStagedApexFilesWithChildren) {
883*33f37583SAndroid Build Coastguard Worker // Create staged session
884*33f37583SAndroid Build Coastguard Worker auto parent_apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
885*33f37583SAndroid Build Coastguard Worker parent_apex_session->UpdateStateAndCommit(SessionState::STAGED);
886*33f37583SAndroid Build Coastguard Worker auto child_session_1 = CreateStagedSession("apex.apexd_test.apex", 124);
887*33f37583SAndroid Build Coastguard Worker auto child_session_2 = CreateStagedSession("apex.apexd_test.apex", 125);
888*33f37583SAndroid Build Coastguard Worker
889*33f37583SAndroid Build Coastguard Worker // Query for its file
890*33f37583SAndroid Build Coastguard Worker auto result = GetStagedApexFiles(123, {124, 125});
891*33f37583SAndroid Build Coastguard Worker
892*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
893*33f37583SAndroid Build Coastguard Worker auto child_apex_file_1 = ApexFile::Open(
894*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/apex.apexd_test.apex", GetStagedDir(124).c_str()));
895*33f37583SAndroid Build Coastguard Worker auto child_apex_file_2 = ApexFile::Open(
896*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/apex.apexd_test.apex", GetStagedDir(125).c_str()));
897*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(*result,
898*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexFileEq(ByRef(*child_apex_file_1)),
899*33f37583SAndroid Build Coastguard Worker ApexFileEq(ByRef(*child_apex_file_2))));
900*33f37583SAndroid Build Coastguard Worker }
901*33f37583SAndroid Build Coastguard Worker
902*33f37583SAndroid Build Coastguard Worker // A test fixture to use for tests that mount/unmount apexes.
903*33f37583SAndroid Build Coastguard Worker // This also supports test-purpose BlockApex via mount.
904*33f37583SAndroid Build Coastguard Worker class ApexdMountTest : public ApexdUnitTest {
905*33f37583SAndroid Build Coastguard Worker public:
ApexdMountTest()906*33f37583SAndroid Build Coastguard Worker ApexdMountTest() {
907*33f37583SAndroid Build Coastguard Worker vm_payload_disk_ = StringPrintf("%s/vm-payload", td_.path);
908*33f37583SAndroid Build Coastguard Worker }
909*33f37583SAndroid Build Coastguard Worker
UnmountOnTearDown(const std::string & apex_file)910*33f37583SAndroid Build Coastguard Worker void UnmountOnTearDown(const std::string& apex_file) {
911*33f37583SAndroid Build Coastguard Worker to_unmount_.push_back(apex_file);
912*33f37583SAndroid Build Coastguard Worker }
913*33f37583SAndroid Build Coastguard Worker
914*33f37583SAndroid Build Coastguard Worker protected:
SetUp()915*33f37583SAndroid Build Coastguard Worker void SetUp() final {
916*33f37583SAndroid Build Coastguard Worker ApexdUnitTest::SetUp();
917*33f37583SAndroid Build Coastguard Worker GetApexDatabaseForTesting().Reset();
918*33f37583SAndroid Build Coastguard Worker GetChangedActiveApexesForTesting().clear();
919*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(SetUpApexTestEnvironment(), Ok());
920*33f37583SAndroid Build Coastguard Worker }
921*33f37583SAndroid Build Coastguard Worker
TearDown()922*33f37583SAndroid Build Coastguard Worker void TearDown() final {
923*33f37583SAndroid Build Coastguard Worker ApexdUnitTest::TearDown();
924*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(false);
925*33f37583SAndroid Build Coastguard Worker for (const auto& apex : to_unmount_) {
926*33f37583SAndroid Build Coastguard Worker if (auto status = DeactivatePackage(apex); !status.ok()) {
927*33f37583SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to unmount " << apex << " : " << status.error();
928*33f37583SAndroid Build Coastguard Worker }
929*33f37583SAndroid Build Coastguard Worker }
930*33f37583SAndroid Build Coastguard Worker InitMetrics({}); // reset
931*33f37583SAndroid Build Coastguard Worker }
932*33f37583SAndroid Build Coastguard Worker
SetBlockApexEnabled(bool enabled)933*33f37583SAndroid Build Coastguard Worker void SetBlockApexEnabled(bool enabled) {
934*33f37583SAndroid Build Coastguard Worker // The first partition(1) is "metadata" partition
935*33f37583SAndroid Build Coastguard Worker base::SetProperty(kTestVmPayloadMetadataPartitionProp,
936*33f37583SAndroid Build Coastguard Worker enabled ? (vm_payload_disk_ + "1") : "");
937*33f37583SAndroid Build Coastguard Worker }
938*33f37583SAndroid Build Coastguard Worker
AddBlockApex(const std::string & apex_name,const std::string & public_key="",const std::string & root_digest="",bool is_factory=true)939*33f37583SAndroid Build Coastguard Worker std::string AddBlockApex(const std::string& apex_name,
940*33f37583SAndroid Build Coastguard Worker const std::string& public_key = "",
941*33f37583SAndroid Build Coastguard Worker const std::string& root_digest = "",
942*33f37583SAndroid Build Coastguard Worker bool is_factory = true) {
943*33f37583SAndroid Build Coastguard Worker auto apex_path = vm_payload_disk_ + std::to_string(block_device_index_++);
944*33f37583SAndroid Build Coastguard Worker auto apex_file = GetTestFile(apex_name);
945*33f37583SAndroid Build Coastguard Worker AddToMetadata(apex_name, public_key, root_digest, is_factory);
946*33f37583SAndroid Build Coastguard Worker // block_apexes_ will be disposed after each test
947*33f37583SAndroid Build Coastguard Worker auto block_apex = WriteBlockApex(apex_file, apex_path);
948*33f37583SAndroid Build Coastguard Worker if (!block_apex.ok()) {
949*33f37583SAndroid Build Coastguard Worker PLOG(ERROR) << block_apex.error();
950*33f37583SAndroid Build Coastguard Worker }
951*33f37583SAndroid Build Coastguard Worker block_apexes_.push_back(std::move(*block_apex));
952*33f37583SAndroid Build Coastguard Worker return apex_path;
953*33f37583SAndroid Build Coastguard Worker }
954*33f37583SAndroid Build Coastguard Worker
AddToMetadata(const std::string & apex_name,const std::string & public_key,const std::string & root_digest,bool is_factory)955*33f37583SAndroid Build Coastguard Worker void AddToMetadata(const std::string& apex_name,
956*33f37583SAndroid Build Coastguard Worker const std::string& public_key,
957*33f37583SAndroid Build Coastguard Worker const std::string& root_digest, bool is_factory) {
958*33f37583SAndroid Build Coastguard Worker android::microdroid::Metadata metadata;
959*33f37583SAndroid Build Coastguard Worker // The first partition is metadata partition
960*33f37583SAndroid Build Coastguard Worker auto metadata_partition = vm_payload_disk_ + "1";
961*33f37583SAndroid Build Coastguard Worker if (access(metadata_partition.c_str(), F_OK) == 0) {
962*33f37583SAndroid Build Coastguard Worker auto result = android::microdroid::ReadMetadata(metadata_partition);
963*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
964*33f37583SAndroid Build Coastguard Worker metadata = *result;
965*33f37583SAndroid Build Coastguard Worker }
966*33f37583SAndroid Build Coastguard Worker
967*33f37583SAndroid Build Coastguard Worker auto apex = metadata.add_apexes();
968*33f37583SAndroid Build Coastguard Worker apex->set_name(apex_name);
969*33f37583SAndroid Build Coastguard Worker apex->set_public_key(public_key);
970*33f37583SAndroid Build Coastguard Worker apex->set_root_digest(root_digest);
971*33f37583SAndroid Build Coastguard Worker apex->set_is_factory(is_factory);
972*33f37583SAndroid Build Coastguard Worker
973*33f37583SAndroid Build Coastguard Worker std::ofstream out(metadata_partition);
974*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(android::microdroid::WriteMetadata(metadata, out), Ok());
975*33f37583SAndroid Build Coastguard Worker }
976*33f37583SAndroid Build Coastguard Worker
977*33f37583SAndroid Build Coastguard Worker private:
978*33f37583SAndroid Build Coastguard Worker MountNamespaceRestorer restorer_;
979*33f37583SAndroid Build Coastguard Worker std::vector<std::string> to_unmount_;
980*33f37583SAndroid Build Coastguard Worker
981*33f37583SAndroid Build Coastguard Worker // Block APEX specific stuff.
982*33f37583SAndroid Build Coastguard Worker std::string vm_payload_disk_;
983*33f37583SAndroid Build Coastguard Worker int block_device_index_ = 2; // "1" is reserved for metadata;
984*33f37583SAndroid Build Coastguard Worker // This should be freed before ~MountNamespaceRestorer() because it
985*33f37583SAndroid Build Coastguard Worker // switches to the original mount namespace while block apexes are mounted
986*33f37583SAndroid Build Coastguard Worker // in test-purpose mount namespace.
987*33f37583SAndroid Build Coastguard Worker std::vector<BlockApex> block_apexes_;
988*33f37583SAndroid Build Coastguard Worker };
989*33f37583SAndroid Build Coastguard Worker
990*33f37583SAndroid Build Coastguard Worker // TODO(b/187864524): cover other negative scenarios.
TEST_F(ApexdMountTest,InstallPackageRejectsApexWithoutRebootlessSupport)991*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsApexWithoutRebootlessSupport) {
992*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("apex.apexd_test.apex");
993*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
994*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
995*33f37583SAndroid Build Coastguard Worker
996*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
997*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
998*33f37583SAndroid Build Coastguard Worker
999*33f37583SAndroid Build Coastguard Worker auto ret =
1000*33f37583SAndroid Build Coastguard Worker InstallPackage(GetTestFile("apex.apexd_test.apex"), /* force= */ false);
1001*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
1002*33f37583SAndroid Build Coastguard Worker ret,
1003*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr("does not support non-staged update"))));
1004*33f37583SAndroid Build Coastguard Worker }
1005*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsNoPreInstalledApex)1006*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsNoPreInstalledApex) {
1007*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v1.apex"),
1008*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1009*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
1010*33f37583SAndroid Build Coastguard Worker ret, HasError(WithMessage(HasSubstr(
1011*33f37583SAndroid Build Coastguard Worker "No active version found for package test.apex.rebootless"))));
1012*33f37583SAndroid Build Coastguard Worker }
1013*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsNoActiveApex)1014*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsNoActiveApex) {
1015*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1016*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1017*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1018*33f37583SAndroid Build Coastguard Worker
1019*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1020*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1021*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
1022*33f37583SAndroid Build Coastguard Worker ret, HasError(WithMessage(HasSubstr(
1023*33f37583SAndroid Build Coastguard Worker "No active version found for package test.apex.rebootless"))));
1024*33f37583SAndroid Build Coastguard Worker }
1025*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsManifestMismatch)1026*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsManifestMismatch) {
1027*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1028*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1029*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1030*33f37583SAndroid Build Coastguard Worker
1031*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1032*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1033*33f37583SAndroid Build Coastguard Worker
1034*33f37583SAndroid Build Coastguard Worker auto ret =
1035*33f37583SAndroid Build Coastguard Worker InstallPackage(GetTestFile("test.rebootless_apex_manifest_mismatch.apex"),
1036*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1037*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
1038*33f37583SAndroid Build Coastguard Worker ret,
1039*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
1040*33f37583SAndroid Build Coastguard Worker "Manifest inside filesystem does not match manifest outside it"))));
1041*33f37583SAndroid Build Coastguard Worker }
1042*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsCorrupted)1043*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsCorrupted) {
1044*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1045*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1046*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1047*33f37583SAndroid Build Coastguard Worker
1048*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1049*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1050*33f37583SAndroid Build Coastguard Worker
1051*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_corrupted.apex"),
1052*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1053*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret,
1054*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr("Can't verify /dev/block/dm-"))));
1055*33f37583SAndroid Build Coastguard Worker }
1056*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsProvidesSharedLibs)1057*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsProvidesSharedLibs) {
1058*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1059*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1060*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1061*33f37583SAndroid Build Coastguard Worker
1062*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1063*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1064*33f37583SAndroid Build Coastguard Worker
1065*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(
1066*33f37583SAndroid Build Coastguard Worker GetTestFile("test.rebootless_apex_provides_sharedlibs.apex"),
1067*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1068*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, HasError(WithMessage(HasSubstr(" is a shared libs APEX"))));
1069*33f37583SAndroid Build Coastguard Worker }
1070*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsProvidesNativeLibs)1071*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsProvidesNativeLibs) {
1072*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1073*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1074*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1075*33f37583SAndroid Build Coastguard Worker
1076*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1077*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1078*33f37583SAndroid Build Coastguard Worker
1079*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(
1080*33f37583SAndroid Build Coastguard Worker GetTestFile("test.rebootless_apex_provides_native_libs.apex"),
1081*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1082*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, HasError(WithMessage(HasSubstr(" provides native libs"))));
1083*33f37583SAndroid Build Coastguard Worker }
1084*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsRequiresSharedApexLibs)1085*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsRequiresSharedApexLibs) {
1086*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1087*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1088*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1089*33f37583SAndroid Build Coastguard Worker
1090*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1091*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1092*33f37583SAndroid Build Coastguard Worker
1093*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(
1094*33f37583SAndroid Build Coastguard Worker GetTestFile("test.rebootless_apex_requires_shared_apex_libs.apex"),
1095*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1096*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret,
1097*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(" requires shared apex libs"))));
1098*33f37583SAndroid Build Coastguard Worker }
1099*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsJniLibs)1100*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsJniLibs) {
1101*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1102*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1103*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1104*33f37583SAndroid Build Coastguard Worker
1105*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1106*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1107*33f37583SAndroid Build Coastguard Worker
1108*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_jni_libs.apex"),
1109*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1110*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, HasError(WithMessage(HasSubstr(" requires JNI libs"))));
1111*33f37583SAndroid Build Coastguard Worker }
1112*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageAcceptsAddRequiredNativeLib)1113*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageAcceptsAddRequiredNativeLib) {
1114*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1115*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1116*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1117*33f37583SAndroid Build Coastguard Worker
1118*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1119*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1120*33f37583SAndroid Build Coastguard Worker
1121*33f37583SAndroid Build Coastguard Worker auto ret =
1122*33f37583SAndroid Build Coastguard Worker InstallPackage(GetTestFile("test.rebootless_apex_add_native_lib.apex"),
1123*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1124*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1125*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1126*33f37583SAndroid Build Coastguard Worker }
1127*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageAcceptsRemoveRequiredNativeLib)1128*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageAcceptsRemoveRequiredNativeLib) {
1129*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1130*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1131*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1132*33f37583SAndroid Build Coastguard Worker
1133*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1134*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1135*33f37583SAndroid Build Coastguard Worker
1136*33f37583SAndroid Build Coastguard Worker auto ret =
1137*33f37583SAndroid Build Coastguard Worker InstallPackage(GetTestFile("test.rebootless_apex_remove_native_lib.apex"),
1138*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1139*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1140*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1141*33f37583SAndroid Build Coastguard Worker }
1142*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsAppInApex)1143*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsAppInApex) {
1144*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1145*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1146*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1147*33f37583SAndroid Build Coastguard Worker
1148*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1149*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1150*33f37583SAndroid Build Coastguard Worker
1151*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(
1152*33f37583SAndroid Build Coastguard Worker GetTestFile("test.rebootless_apex_app_in_apex.apex"), /* force= */ false);
1153*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, HasError(WithMessage(HasSubstr("contains app inside"))));
1154*33f37583SAndroid Build Coastguard Worker }
1155*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageRejectsPrivAppInApex)1156*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageRejectsPrivAppInApex) {
1157*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1158*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1159*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1160*33f37583SAndroid Build Coastguard Worker
1161*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1162*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1163*33f37583SAndroid Build Coastguard Worker
1164*33f37583SAndroid Build Coastguard Worker auto ret =
1165*33f37583SAndroid Build Coastguard Worker InstallPackage(GetTestFile("test.rebootless_apex_priv_app_in_apex.apex"),
1166*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1167*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret,
1168*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr("contains priv-app inside"))));
1169*33f37583SAndroid Build Coastguard Worker }
1170*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackagePreInstallVersionActive)1171*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackagePreInstallVersionActive) {
1172*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1173*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1174*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1175*33f37583SAndroid Build Coastguard Worker
1176*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1177*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1178*33f37583SAndroid Build Coastguard Worker
1179*33f37583SAndroid Build Coastguard Worker {
1180*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1181*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1182*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1183*33f37583SAndroid Build Coastguard Worker }
1184*33f37583SAndroid Build Coastguard Worker
1185*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1186*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1187*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1188*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1189*33f37583SAndroid Build Coastguard Worker
1190*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1191*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1192*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1193*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@2"));
1194*33f37583SAndroid Build Coastguard Worker
1195*33f37583SAndroid Build Coastguard Worker // Check that /apex/test.apex.rebootless is a bind mount of
1196*33f37583SAndroid Build Coastguard Worker // /apex/test.apex.rebootless@2.
1197*33f37583SAndroid Build Coastguard Worker auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
1198*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(manifest, Ok());
1199*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(2u, manifest->version());
1200*33f37583SAndroid Build Coastguard Worker
1201*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports upgraded version.
1202*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1203*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1204*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
1205*33f37583SAndroid Build Coastguard Worker
1206*33f37583SAndroid Build Coastguard Worker // Check that pre-installed APEX is still around
1207*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path.c_str(), F_OK))
1208*33f37583SAndroid Build Coastguard Worker << "Can't access " << file_path << " : " << strerror(errno);
1209*33f37583SAndroid Build Coastguard Worker
1210*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1211*33f37583SAndroid Build Coastguard Worker // Check that upgraded APEX is mounted on top of dm-verity device.
1212*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
1213*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless", [&](const MountedApexData& data, bool latest) {
1214*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1215*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, ret->GetPath());
1216*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name, "test.apex.rebootless@2_1");
1217*33f37583SAndroid Build Coastguard Worker });
1218*33f37583SAndroid Build Coastguard Worker }
1219*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackagePreInstallVersionActiveSamegrade)1220*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackagePreInstallVersionActiveSamegrade) {
1221*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1222*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1223*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1224*33f37583SAndroid Build Coastguard Worker
1225*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1226*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1227*33f37583SAndroid Build Coastguard Worker
1228*33f37583SAndroid Build Coastguard Worker {
1229*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1230*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1231*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1232*33f37583SAndroid Build Coastguard Worker }
1233*33f37583SAndroid Build Coastguard Worker
1234*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v1.apex"),
1235*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1236*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1237*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1238*33f37583SAndroid Build Coastguard Worker
1239*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1240*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1241*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1242*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@1"));
1243*33f37583SAndroid Build Coastguard Worker
1244*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports upgraded version.
1245*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1246*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1247*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
1248*33f37583SAndroid Build Coastguard Worker
1249*33f37583SAndroid Build Coastguard Worker // Check that pre-installed APEX is still around
1250*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path.c_str(), F_OK))
1251*33f37583SAndroid Build Coastguard Worker << "Can't access " << file_path << " : " << strerror(errno);
1252*33f37583SAndroid Build Coastguard Worker
1253*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1254*33f37583SAndroid Build Coastguard Worker // Check that upgraded APEX is mounted on top of dm-verity device.
1255*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
1256*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless", [&](const MountedApexData& data, bool latest) {
1257*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1258*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, ret->GetPath());
1259*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name, "test.apex.rebootless@1_1");
1260*33f37583SAndroid Build Coastguard Worker });
1261*33f37583SAndroid Build Coastguard Worker }
1262*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageUnloadOldApex)1263*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageUnloadOldApex) {
1264*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1265*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1266*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1267*33f37583SAndroid Build Coastguard Worker
1268*33f37583SAndroid Build Coastguard Worker bool unloaded = false;
1269*33f37583SAndroid Build Coastguard Worker bool loaded = false;
1270*33f37583SAndroid Build Coastguard Worker const std::string prop = "apex.test.apex.rebootless.ready";
1271*33f37583SAndroid Build Coastguard Worker std::thread monitor_apex_ready_prop([&]() {
1272*33f37583SAndroid Build Coastguard Worker unloaded = base::WaitForProperty(prop, "false", 10s);
1273*33f37583SAndroid Build Coastguard Worker loaded = base::WaitForProperty(prop, "true", 10s);
1274*33f37583SAndroid Build Coastguard Worker });
1275*33f37583SAndroid Build Coastguard Worker
1276*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1277*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1278*33f37583SAndroid Build Coastguard Worker
1279*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1280*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1281*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1282*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1283*33f37583SAndroid Build Coastguard Worker
1284*33f37583SAndroid Build Coastguard Worker monitor_apex_ready_prop.join();
1285*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(unloaded);
1286*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(loaded);
1287*33f37583SAndroid Build Coastguard Worker }
1288*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageWithService)1289*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageWithService) {
1290*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_service_v1.apex");
1291*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1292*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1293*33f37583SAndroid Build Coastguard Worker
1294*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1295*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1296*33f37583SAndroid Build Coastguard Worker
1297*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_service_v2.apex"),
1298*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1299*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1300*33f37583SAndroid Build Coastguard Worker auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
1301*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(manifest, Ok());
1302*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(2u, manifest->version());
1303*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1304*33f37583SAndroid Build Coastguard Worker }
1305*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageDataVersionActive)1306*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageDataVersionActive) {
1307*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("test.rebootless_apex_v1.apex");
1308*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1309*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1310*33f37583SAndroid Build Coastguard Worker
1311*33f37583SAndroid Build Coastguard Worker std::string file_path = AddDataApex("test.rebootless_apex_v1.apex");
1312*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1313*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1314*33f37583SAndroid Build Coastguard Worker
1315*33f37583SAndroid Build Coastguard Worker {
1316*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1317*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1318*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1319*33f37583SAndroid Build Coastguard Worker }
1320*33f37583SAndroid Build Coastguard Worker
1321*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1322*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1323*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1324*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1325*33f37583SAndroid Build Coastguard Worker
1326*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1327*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1328*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1329*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@2"));
1330*33f37583SAndroid Build Coastguard Worker
1331*33f37583SAndroid Build Coastguard Worker // Check that /apex/test.apex.rebootless is a bind mount of
1332*33f37583SAndroid Build Coastguard Worker // /apex/test.apex.rebootless@2.
1333*33f37583SAndroid Build Coastguard Worker auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
1334*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(manifest, Ok());
1335*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(2u, manifest->version());
1336*33f37583SAndroid Build Coastguard Worker
1337*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports upgraded version.
1338*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1339*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1340*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
1341*33f37583SAndroid Build Coastguard Worker
1342*33f37583SAndroid Build Coastguard Worker // Check that previously active APEX was deleted.
1343*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(-1, access(file_path.c_str(), F_OK));
1344*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(ENOENT, errno);
1345*33f37583SAndroid Build Coastguard Worker
1346*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1347*33f37583SAndroid Build Coastguard Worker // Check that upgraded APEX is mounted on top of dm-verity device.
1348*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
1349*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless", [&](const MountedApexData& data, bool latest) {
1350*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1351*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, ret->GetPath());
1352*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name, "test.apex.rebootless@2_1");
1353*33f37583SAndroid Build Coastguard Worker });
1354*33f37583SAndroid Build Coastguard Worker }
1355*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageResolvesPathCollision)1356*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageResolvesPathCollision) {
1357*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("test.rebootless_apex_v1.apex");
1358*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1359*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1360*33f37583SAndroid Build Coastguard Worker
1361*33f37583SAndroid Build Coastguard Worker std::string file_path = AddDataApex("test.rebootless_apex_v1.apex",
1362*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless@1_1.apex");
1363*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1364*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1365*33f37583SAndroid Build Coastguard Worker
1366*33f37583SAndroid Build Coastguard Worker {
1367*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1368*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1369*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1370*33f37583SAndroid Build Coastguard Worker }
1371*33f37583SAndroid Build Coastguard Worker
1372*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v1.apex"),
1373*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1374*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1375*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1376*33f37583SAndroid Build Coastguard Worker
1377*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1378*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1379*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1380*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@1"));
1381*33f37583SAndroid Build Coastguard Worker
1382*33f37583SAndroid Build Coastguard Worker // Check that /apex/test.apex.rebootless is a bind mount of
1383*33f37583SAndroid Build Coastguard Worker // /apex/test.apex.rebootless@2.
1384*33f37583SAndroid Build Coastguard Worker auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
1385*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(manifest, Ok());
1386*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1u, manifest->version());
1387*33f37583SAndroid Build Coastguard Worker
1388*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports upgraded version.
1389*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1390*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1391*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
1392*33f37583SAndroid Build Coastguard Worker
1393*33f37583SAndroid Build Coastguard Worker // Check that we correctly resolved active apex path collision.
1394*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(),
1395*33f37583SAndroid Build Coastguard Worker GetDataDir() + "/test.apex.rebootless@1_2.apex");
1396*33f37583SAndroid Build Coastguard Worker
1397*33f37583SAndroid Build Coastguard Worker // Check that previously active APEX was deleted.
1398*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(-1, access(file_path.c_str(), F_OK));
1399*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(ENOENT, errno);
1400*33f37583SAndroid Build Coastguard Worker
1401*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1402*33f37583SAndroid Build Coastguard Worker // Check that upgraded APEX is mounted on top of dm-verity device.
1403*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
1404*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless", [&](const MountedApexData& data, bool latest) {
1405*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1406*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, ret->GetPath());
1407*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name, "test.apex.rebootless@1_2");
1408*33f37583SAndroid Build Coastguard Worker });
1409*33f37583SAndroid Build Coastguard Worker }
1410*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageDataVersionActiveSamegrade)1411*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageDataVersionActiveSamegrade) {
1412*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("test.rebootless_apex_v1.apex");
1413*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1414*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1415*33f37583SAndroid Build Coastguard Worker
1416*33f37583SAndroid Build Coastguard Worker std::string file_path = AddDataApex("test.rebootless_apex_v2.apex");
1417*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1418*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1419*33f37583SAndroid Build Coastguard Worker
1420*33f37583SAndroid Build Coastguard Worker {
1421*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1422*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1423*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1424*33f37583SAndroid Build Coastguard Worker }
1425*33f37583SAndroid Build Coastguard Worker
1426*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1427*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1428*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1429*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1430*33f37583SAndroid Build Coastguard Worker
1431*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1432*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1433*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1434*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@2"));
1435*33f37583SAndroid Build Coastguard Worker
1436*33f37583SAndroid Build Coastguard Worker // Check that /apex/test.apex.rebootless is a bind mount of
1437*33f37583SAndroid Build Coastguard Worker // /apex/test.apex.rebootless@2.
1438*33f37583SAndroid Build Coastguard Worker auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
1439*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(manifest, Ok());
1440*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(2u, manifest->version());
1441*33f37583SAndroid Build Coastguard Worker
1442*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports upgraded version.
1443*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1444*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1445*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
1446*33f37583SAndroid Build Coastguard Worker
1447*33f37583SAndroid Build Coastguard Worker // Check that previously active APEX was deleted.
1448*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(-1, access(file_path.c_str(), F_OK));
1449*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(ENOENT, errno);
1450*33f37583SAndroid Build Coastguard Worker
1451*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1452*33f37583SAndroid Build Coastguard Worker // Check that upgraded APEX is mounted on top of dm-verity device.
1453*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
1454*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless", [&](const MountedApexData& data, bool latest) {
1455*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1456*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, ret->GetPath());
1457*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name, "test.apex.rebootless@2_1");
1458*33f37583SAndroid Build Coastguard Worker });
1459*33f37583SAndroid Build Coastguard Worker }
1460*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageUnmountFailsPreInstalledApexActive)1461*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageUnmountFailsPreInstalledApexActive) {
1462*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1463*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1464*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1465*33f37583SAndroid Build Coastguard Worker
1466*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1467*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1468*33f37583SAndroid Build Coastguard Worker
1469*33f37583SAndroid Build Coastguard Worker {
1470*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1471*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1472*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1473*33f37583SAndroid Build Coastguard Worker }
1474*33f37583SAndroid Build Coastguard Worker
1475*33f37583SAndroid Build Coastguard Worker unique_fd fd(open("/apex/test.apex.rebootless/apex_manifest.pb",
1476*33f37583SAndroid Build Coastguard Worker O_RDONLY | O_CLOEXEC));
1477*33f37583SAndroid Build Coastguard Worker ASSERT_NE(-1, fd.get());
1478*33f37583SAndroid Build Coastguard Worker
1479*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1480*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1481*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Not(Ok()));
1482*33f37583SAndroid Build Coastguard Worker
1483*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1484*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1485*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1486*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@1"));
1487*33f37583SAndroid Build Coastguard Worker
1488*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports upgraded version.
1489*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1490*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1491*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1492*33f37583SAndroid Build Coastguard Worker
1493*33f37583SAndroid Build Coastguard Worker // Check that old APEX is still around
1494*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path.c_str(), F_OK))
1495*33f37583SAndroid Build Coastguard Worker << "Can't access " << file_path << " : " << strerror(errno);
1496*33f37583SAndroid Build Coastguard Worker
1497*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1498*33f37583SAndroid Build Coastguard Worker // Check that upgraded APEX is mounted on top of dm-verity device.
1499*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("test.apex.rebootless",
1500*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
1501*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1502*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, file_path);
1503*33f37583SAndroid Build Coastguard Worker });
1504*33f37583SAndroid Build Coastguard Worker }
1505*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageUnmountFailedUpdatedApexActive)1506*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageUnmountFailedUpdatedApexActive) {
1507*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("test.rebootless_apex_v1.apex");
1508*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1509*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1510*33f37583SAndroid Build Coastguard Worker
1511*33f37583SAndroid Build Coastguard Worker std::string file_path = AddDataApex("test.rebootless_apex_v1.apex");
1512*33f37583SAndroid Build Coastguard Worker
1513*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1514*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1515*33f37583SAndroid Build Coastguard Worker
1516*33f37583SAndroid Build Coastguard Worker {
1517*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1518*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1519*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1520*33f37583SAndroid Build Coastguard Worker }
1521*33f37583SAndroid Build Coastguard Worker
1522*33f37583SAndroid Build Coastguard Worker unique_fd fd(open("/apex/test.apex.rebootless/apex_manifest.pb",
1523*33f37583SAndroid Build Coastguard Worker O_RDONLY | O_CLOEXEC));
1524*33f37583SAndroid Build Coastguard Worker ASSERT_NE(-1, fd.get());
1525*33f37583SAndroid Build Coastguard Worker
1526*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1527*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1528*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Not(Ok()));
1529*33f37583SAndroid Build Coastguard Worker
1530*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1531*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1532*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/test.apex.rebootless",
1533*33f37583SAndroid Build Coastguard Worker "/apex/test.apex.rebootless@1"));
1534*33f37583SAndroid Build Coastguard Worker
1535*33f37583SAndroid Build Coastguard Worker // Check that GetActivePackage correctly reports old apex.
1536*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("test.apex.rebootless");
1537*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1538*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1539*33f37583SAndroid Build Coastguard Worker
1540*33f37583SAndroid Build Coastguard Worker // Check that old APEX is still around
1541*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path.c_str(), F_OK))
1542*33f37583SAndroid Build Coastguard Worker << "Can't access " << file_path << " : " << strerror(errno);
1543*33f37583SAndroid Build Coastguard Worker
1544*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1545*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
1546*33f37583SAndroid Build Coastguard Worker "test.apex.rebootless", [&](const MountedApexData& data, bool latest) {
1547*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
1548*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, file_path);
1549*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name, "test.apex.rebootless@1");
1550*33f37583SAndroid Build Coastguard Worker });
1551*33f37583SAndroid Build Coastguard Worker }
1552*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,InstallPackageUpdatesApexInfoList)1553*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, InstallPackageUpdatesApexInfoList) {
1554*33f37583SAndroid Build Coastguard Worker auto apex_1 = AddPreInstalledApex("test.rebootless_apex_v1.apex");
1555*33f37583SAndroid Build Coastguard Worker auto apex_2 = AddPreInstalledApex("apex.apexd_test.apex");
1556*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1557*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1558*33f37583SAndroid Build Coastguard Worker
1559*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_1);
1560*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_2);
1561*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_1), Ok());
1562*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_2), Ok());
1563*33f37583SAndroid Build Coastguard Worker
1564*33f37583SAndroid Build Coastguard Worker // Call OnAllPackagesActivated to create /apex/apex-info-list.xml.
1565*33f37583SAndroid Build Coastguard Worker OnAllPackagesActivated(/* is_bootstrap= */ false);
1566*33f37583SAndroid Build Coastguard Worker // Check /apex/apex-info-list.xml was created.
1567*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access("/apex/apex-info-list.xml", F_OK));
1568*33f37583SAndroid Build Coastguard Worker
1569*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"),
1570*33f37583SAndroid Build Coastguard Worker /* force= */ false);
1571*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret, Ok());
1572*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(ret->GetPath());
1573*33f37583SAndroid Build Coastguard Worker
1574*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
1575*33f37583SAndroid Build Coastguard Worker auto info_list =
1576*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
1577*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
1578*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
1579*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "test.apex.rebootless",
1580*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_1,
1581*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_1,
1582*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
1583*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_1),
1584*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1585*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1586*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
1587*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
1588*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_2, /* preinstalledModulePath= */ apex_2,
1589*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
1590*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_2),
1591*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1592*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1593*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_3 = com::android::apex::ApexInfo(
1594*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "test.apex.rebootless",
1595*33f37583SAndroid Build Coastguard Worker /* modulePath= */ ret->GetPath(),
1596*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_1,
1597*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
1598*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(ret->GetPath()),
1599*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1600*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1601*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
1602*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
1603*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2),
1604*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_3)));
1605*33f37583SAndroid Build Coastguard Worker }
1606*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatePackageBannedName)1607*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatePackageBannedName) {
1608*33f37583SAndroid Build Coastguard Worker auto status = ActivatePackage(GetTestFile("sharedlibs.apex"));
1609*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status,
1610*33f37583SAndroid Build Coastguard Worker HasError(WithMessage("Package name sharedlibs is not allowed.")));
1611*33f37583SAndroid Build Coastguard Worker }
1612*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatePackageNoCode)1613*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatePackageNoCode) {
1614*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("apex.apexd_test_nocode.apex");
1615*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1616*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1617*33f37583SAndroid Build Coastguard Worker
1618*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1619*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1620*33f37583SAndroid Build Coastguard Worker
1621*33f37583SAndroid Build Coastguard Worker std::string mountinfo;
1622*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(ReadFileToString("/proc/self/mountinfo", &mountinfo));
1623*33f37583SAndroid Build Coastguard Worker bool found_apex_mountpoint = false;
1624*33f37583SAndroid Build Coastguard Worker for (const auto& line : Split(mountinfo, "\n")) {
1625*33f37583SAndroid Build Coastguard Worker std::vector<std::string> tokens = Split(line, " ");
1626*33f37583SAndroid Build Coastguard Worker // line format:
1627*33f37583SAndroid Build Coastguard Worker // mnt_id parent_mnt_id major:minor source target option propagation_type
1628*33f37583SAndroid Build Coastguard Worker // ex) 33 260:19 / /apex rw,nosuid,nodev -
1629*33f37583SAndroid Build Coastguard Worker if (tokens.size() >= 7 &&
1630*33f37583SAndroid Build Coastguard Worker tokens[4] == "/apex/com.android.apex.test_package@1") {
1631*33f37583SAndroid Build Coastguard Worker found_apex_mountpoint = true;
1632*33f37583SAndroid Build Coastguard Worker // Make sure that option contains noexec
1633*33f37583SAndroid Build Coastguard Worker std::vector<std::string> options = Split(tokens[5], ",");
1634*33f37583SAndroid Build Coastguard Worker EXPECT_THAT(options, Contains("noexec"));
1635*33f37583SAndroid Build Coastguard Worker break;
1636*33f37583SAndroid Build Coastguard Worker }
1637*33f37583SAndroid Build Coastguard Worker }
1638*33f37583SAndroid Build Coastguard Worker EXPECT_TRUE(found_apex_mountpoint);
1639*33f37583SAndroid Build Coastguard Worker }
1640*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatePackageManifestMissmatch)1641*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatePackageManifestMissmatch) {
1642*33f37583SAndroid Build Coastguard Worker std::string file_path =
1643*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_manifest_mismatch.apex");
1644*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1645*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1646*33f37583SAndroid Build Coastguard Worker
1647*33f37583SAndroid Build Coastguard Worker auto status = ActivatePackage(file_path);
1648*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
1649*33f37583SAndroid Build Coastguard Worker status,
1650*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
1651*33f37583SAndroid Build Coastguard Worker "Manifest inside filesystem does not match manifest outside it"))));
1652*33f37583SAndroid Build Coastguard Worker }
1653*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatePackage)1654*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatePackage) {
1655*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("apex.apexd_test.apex");
1656*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1657*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1658*33f37583SAndroid Build Coastguard Worker
1659*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1660*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1661*33f37583SAndroid Build Coastguard Worker
1662*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("com.android.apex.test_package");
1663*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1664*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1665*33f37583SAndroid Build Coastguard Worker
1666*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1667*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1668*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
1669*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1"));
1670*33f37583SAndroid Build Coastguard Worker
1671*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(DeactivatePackage(file_path), Ok());
1672*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(GetActivePackage("com.android.apex.test_package"), Not(Ok()));
1673*33f37583SAndroid Build Coastguard Worker
1674*33f37583SAndroid Build Coastguard Worker auto new_apex_mounts = GetApexMounts();
1675*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(new_apex_mounts.size(), 0u);
1676*33f37583SAndroid Build Coastguard Worker }
1677*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatePackageShowsUpInMountedApexDatabase)1678*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatePackageShowsUpInMountedApexDatabase) {
1679*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex("apex.apexd_test.apex");
1680*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1681*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1682*33f37583SAndroid Build Coastguard Worker
1683*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1684*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1685*33f37583SAndroid Build Coastguard Worker
1686*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("com.android.apex.test_package");
1687*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1688*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1689*33f37583SAndroid Build Coastguard Worker
1690*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1691*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1692*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
1693*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1"));
1694*33f37583SAndroid Build Coastguard Worker
1695*33f37583SAndroid Build Coastguard Worker // Check that mounted apex database contains information about our APEX.
1696*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
1697*33f37583SAndroid Build Coastguard Worker std::optional<MountedApexData> mounted_apex;
1698*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package",
1699*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& d, bool active) {
1700*33f37583SAndroid Build Coastguard Worker if (active) {
1701*33f37583SAndroid Build Coastguard Worker mounted_apex.emplace(d);
1702*33f37583SAndroid Build Coastguard Worker }
1703*33f37583SAndroid Build Coastguard Worker });
1704*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(mounted_apex)
1705*33f37583SAndroid Build Coastguard Worker << "Haven't found com.android.apex.test_package in the database of "
1706*33f37583SAndroid Build Coastguard Worker << "mounted apexes";
1707*33f37583SAndroid Build Coastguard Worker }
1708*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,DeactivePackageFreesLoopDevices)1709*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, DeactivePackageFreesLoopDevices) {
1710*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
1711*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1712*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1713*33f37583SAndroid Build Coastguard Worker
1714*33f37583SAndroid Build Coastguard Worker std::string file_path = AddDataApex("apex.apexd_test_v2.apex");
1715*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1716*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1717*33f37583SAndroid Build Coastguard Worker
1718*33f37583SAndroid Build Coastguard Worker // Get loop devices that were used to mount APEX.
1719*33f37583SAndroid Build Coastguard Worker auto children = ListChildLoopDevices("com.android.apex.test_package@2");
1720*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(children, Ok());
1721*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1u, children->size())
1722*33f37583SAndroid Build Coastguard Worker << "Unexpected number of children: " << Join(*children, ",");
1723*33f37583SAndroid Build Coastguard Worker
1724*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(DeactivatePackage(file_path), Ok());
1725*33f37583SAndroid Build Coastguard Worker for (const auto& loop : *children) {
1726*33f37583SAndroid Build Coastguard Worker struct loop_info li;
1727*33f37583SAndroid Build Coastguard Worker unique_fd fd(TEMP_FAILURE_RETRY(open(loop.c_str(), O_RDWR | O_CLOEXEC)));
1728*33f37583SAndroid Build Coastguard Worker EXPECT_NE(-1, fd.get())
1729*33f37583SAndroid Build Coastguard Worker << "Failed to open " << loop << " : " << strerror(errno);
1730*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(-1, ioctl(fd.get(), LOOP_GET_STATUS, &li))
1731*33f37583SAndroid Build Coastguard Worker << loop << " is still alive";
1732*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(ENXIO, errno) << "Unexpected errno : " << strerror(errno);
1733*33f37583SAndroid Build Coastguard Worker }
1734*33f37583SAndroid Build Coastguard Worker }
1735*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,DeactivePackageTearsDownVerityDevice)1736*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, DeactivePackageTearsDownVerityDevice) {
1737*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
1738*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1739*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1740*33f37583SAndroid Build Coastguard Worker
1741*33f37583SAndroid Build Coastguard Worker std::string file_path = AddDataApex("apex.apexd_test_v2.apex");
1742*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1743*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1744*33f37583SAndroid Build Coastguard Worker
1745*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(DeactivatePackage(file_path), Ok());
1746*33f37583SAndroid Build Coastguard Worker auto& dm = DeviceMapper::Instance();
1747*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(dm::DmDeviceState::INVALID,
1748*33f37583SAndroid Build Coastguard Worker dm.GetState("com.android.apex.test_package@2"));
1749*33f37583SAndroid Build Coastguard Worker }
1750*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivateDeactivateSharedLibsApex)1751*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivateDeactivateSharedLibsApex) {
1752*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir("/apex/sharedlibs", 0755), 0);
1753*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir("/apex/sharedlibs/lib", 0755), 0);
1754*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir("/apex/sharedlibs/lib64", 0755), 0);
1755*33f37583SAndroid Build Coastguard Worker auto deleter = make_scope_guard([]() {
1756*33f37583SAndroid Build Coastguard Worker std::error_code ec;
1757*33f37583SAndroid Build Coastguard Worker fs::remove_all("/apex/sharedlibs", ec);
1758*33f37583SAndroid Build Coastguard Worker if (ec) {
1759*33f37583SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to delete /apex/sharedlibs : " << ec;
1760*33f37583SAndroid Build Coastguard Worker }
1761*33f37583SAndroid Build Coastguard Worker });
1762*33f37583SAndroid Build Coastguard Worker
1763*33f37583SAndroid Build Coastguard Worker std::string file_path = AddPreInstalledApex(
1764*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex");
1765*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1766*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1767*33f37583SAndroid Build Coastguard Worker
1768*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
1769*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
1770*33f37583SAndroid Build Coastguard Worker
1771*33f37583SAndroid Build Coastguard Worker auto active_apex = GetActivePackage("com.android.apex.test.sharedlibs");
1772*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_apex, Ok());
1773*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(active_apex->GetPath(), file_path);
1774*33f37583SAndroid Build Coastguard Worker
1775*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1776*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1777*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test.sharedlibs@1"));
1778*33f37583SAndroid Build Coastguard Worker
1779*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(DeactivatePackage(file_path), Ok());
1780*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(GetActivePackage("com.android.apex.test.sharedlibs"), Not(Ok()));
1781*33f37583SAndroid Build Coastguard Worker
1782*33f37583SAndroid Build Coastguard Worker auto new_apex_mounts = GetApexMounts();
1783*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(new_apex_mounts.size(), 0u);
1784*33f37583SAndroid Build Coastguard Worker }
1785*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,RemoveInactiveDataApex)1786*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, RemoveInactiveDataApex) {
1787*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v2.capex");
1788*33f37583SAndroid Build Coastguard Worker // Add a decompressed apex that will not be mounted, so should be removed
1789*33f37583SAndroid Build Coastguard Worker auto decompressed_apex = StringPrintf("%s/com.android.apex.compressed@1%s",
1790*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(),
1791*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
1792*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v1.apex"),
1793*33f37583SAndroid Build Coastguard Worker decompressed_apex);
1794*33f37583SAndroid Build Coastguard Worker // Add a decompressed apex that will be mounted, so should be not be removed
1795*33f37583SAndroid Build Coastguard Worker auto active_decompressed_apex = StringPrintf(
1796*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@2%s", GetDecompressionDir().c_str(),
1797*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
1798*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v2_original.apex"),
1799*33f37583SAndroid Build Coastguard Worker active_decompressed_apex);
1800*33f37583SAndroid Build Coastguard Worker // Apex that do not have kDecompressedApexPackageSuffix, should not be removed
1801*33f37583SAndroid Build Coastguard Worker // from decompression_dir
1802*33f37583SAndroid Build Coastguard Worker auto decompressed_different_suffix =
1803*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@2%s",
1804*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kApexPackageSuffix);
1805*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v2_original.apex"),
1806*33f37583SAndroid Build Coastguard Worker decompressed_different_suffix);
1807*33f37583SAndroid Build Coastguard Worker
1808*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
1809*33f37583SAndroid Build Coastguard Worker auto data_apex = AddDataApex("apex.apexd_test.apex");
1810*33f37583SAndroid Build Coastguard Worker auto active_data_apex = AddDataApex("apex.apexd_test_v2.apex");
1811*33f37583SAndroid Build Coastguard Worker
1812*33f37583SAndroid Build Coastguard Worker // Activate some of the apex
1813*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
1814*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
1815*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(active_decompressed_apex);
1816*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(active_data_apex);
1817*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(active_decompressed_apex), Ok());
1818*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(active_data_apex), Ok());
1819*33f37583SAndroid Build Coastguard Worker // Clean up inactive apex packages
1820*33f37583SAndroid Build Coastguard Worker RemoveInactiveDataApex();
1821*33f37583SAndroid Build Coastguard Worker
1822*33f37583SAndroid Build Coastguard Worker // Verify inactive apex packages have been deleted
1823*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(*PathExists(active_decompressed_apex));
1824*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(*PathExists(active_data_apex));
1825*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(*PathExists(decompressed_different_suffix));
1826*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(*PathExists(decompressed_apex));
1827*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(*PathExists(data_apex));
1828*33f37583SAndroid Build Coastguard Worker }
1829*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapOnlyPreInstalledApexes)1830*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapOnlyPreInstalledApexes) {
1831*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
1832*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
1833*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
1834*33f37583SAndroid Build Coastguard Worker
1835*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
1836*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
1837*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
1838*33f37583SAndroid Build Coastguard Worker
1839*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1840*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1841*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
1842*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
1843*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
1844*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
1845*33f37583SAndroid Build Coastguard Worker
1846*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
1847*33f37583SAndroid Build Coastguard Worker auto info_list =
1848*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
1849*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
1850*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
1851*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
1852*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
1853*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
1854*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
1855*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
1856*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1857*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1858*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
1859*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
1860*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
1861*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
1862*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
1863*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1864*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1865*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
1866*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
1867*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
1868*33f37583SAndroid Build Coastguard Worker }
1869*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapFailsToScanPreInstalledApexes)1870*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapFailsToScanPreInstalledApexes) {
1871*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
1872*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_corrupt_superblock_apex.apex");
1873*33f37583SAndroid Build Coastguard Worker
1874*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 1);
1875*33f37583SAndroid Build Coastguard Worker }
1876*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataHasHigherVersion)1877*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataHasHigherVersion) {
1878*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
1879*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
1880*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
1881*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
1882*33f37583SAndroid Build Coastguard Worker
1883*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
1884*33f37583SAndroid Build Coastguard Worker
1885*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
1886*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
1887*33f37583SAndroid Build Coastguard Worker
1888*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1889*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1890*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
1891*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
1892*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
1893*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
1894*33f37583SAndroid Build Coastguard Worker
1895*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
1896*33f37583SAndroid Build Coastguard Worker auto info_list =
1897*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
1898*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
1899*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
1900*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
1901*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
1902*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
1903*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
1904*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
1905*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1906*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1907*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
1908*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
1909*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
1910*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
1911*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
1912*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1913*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1914*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_3 = com::android::apex::ApexInfo(
1915*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
1916*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_3,
1917*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
1918*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
1919*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
1920*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1921*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1922*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
1923*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
1924*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2),
1925*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_3)));
1926*33f37583SAndroid Build Coastguard Worker }
1927*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataHasSameVersion)1928*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataHasSameVersion) {
1929*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
1930*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
1931*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
1932*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test.apex");
1933*33f37583SAndroid Build Coastguard Worker
1934*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
1935*33f37583SAndroid Build Coastguard Worker
1936*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
1937*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
1938*33f37583SAndroid Build Coastguard Worker
1939*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1940*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1941*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
1942*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
1943*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
1944*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
1945*33f37583SAndroid Build Coastguard Worker
1946*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
1947*33f37583SAndroid Build Coastguard Worker auto info_list =
1948*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
1949*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
1950*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
1951*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
1952*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
1953*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
1954*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
1955*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
1956*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1957*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1958*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
1959*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
1960*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
1961*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
1962*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
1963*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1964*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1965*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_3 = com::android::apex::ApexInfo(
1966*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
1967*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_3,
1968*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
1969*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
1970*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
1971*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
1972*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
1973*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
1974*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
1975*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2),
1976*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_3)));
1977*33f37583SAndroid Build Coastguard Worker }
1978*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSystemHasHigherVersion)1979*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSystemHasHigherVersion) {
1980*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test_v2.apex");
1981*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
1982*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
1983*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test.apex");
1984*33f37583SAndroid Build Coastguard Worker
1985*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
1986*33f37583SAndroid Build Coastguard Worker
1987*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
1988*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
1989*33f37583SAndroid Build Coastguard Worker
1990*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
1991*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
1992*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
1993*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
1994*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
1995*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
1996*33f37583SAndroid Build Coastguard Worker
1997*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
1998*33f37583SAndroid Build Coastguard Worker auto info_list =
1999*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2000*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2001*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2002*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2003*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2004*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2005*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2006*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
2007*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2008*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2009*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
2010*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
2011*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
2012*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
2013*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
2014*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2015*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2016*33f37583SAndroid Build Coastguard Worker
2017*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2018*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
2019*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
2020*33f37583SAndroid Build Coastguard Worker }
2021*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataHasSameVersionButDifferentKey)2022*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataHasSameVersionButDifferentKey) {
2023*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2024*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
2025*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
2026*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_different_key.apex");
2027*33f37583SAndroid Build Coastguard Worker
2028*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2029*33f37583SAndroid Build Coastguard Worker
2030*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
2031*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
2032*33f37583SAndroid Build Coastguard Worker
2033*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2034*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2035*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2036*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
2037*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
2038*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
2039*33f37583SAndroid Build Coastguard Worker
2040*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2041*33f37583SAndroid Build Coastguard Worker auto info_list =
2042*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2043*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2044*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2045*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2046*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2047*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2048*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2049*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
2050*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2051*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2052*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
2053*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
2054*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
2055*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
2056*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
2057*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2058*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2059*33f37583SAndroid Build Coastguard Worker
2060*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2061*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
2062*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
2063*33f37583SAndroid Build Coastguard Worker }
2064*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataHasHigherVersionButDifferentKey)2065*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
2066*33f37583SAndroid Build Coastguard Worker OnOtaChrootBootstrapDataHasHigherVersionButDifferentKey) {
2067*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2068*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
2069*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
2070*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 =
2071*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_different_key_v2.apex");
2072*33f37583SAndroid Build Coastguard Worker
2073*33f37583SAndroid Build Coastguard Worker {
2074*33f37583SAndroid Build Coastguard Worker auto apex = ApexFile::Open(apex_path_3);
2075*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex, Ok());
2076*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<uint64_t>(apex->GetManifest().version()), 2ULL);
2077*33f37583SAndroid Build Coastguard Worker }
2078*33f37583SAndroid Build Coastguard Worker
2079*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2080*33f37583SAndroid Build Coastguard Worker
2081*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
2082*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
2083*33f37583SAndroid Build Coastguard Worker
2084*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2085*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2086*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2087*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
2088*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
2089*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
2090*33f37583SAndroid Build Coastguard Worker
2091*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2092*33f37583SAndroid Build Coastguard Worker auto info_list =
2093*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2094*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2095*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2096*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2097*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2098*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2099*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2100*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
2101*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2102*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2103*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
2104*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
2105*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
2106*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
2107*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
2108*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2109*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2110*33f37583SAndroid Build Coastguard Worker
2111*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2112*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
2113*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
2114*33f37583SAndroid Build Coastguard Worker }
2115*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataApexWithoutPreInstalledApex)2116*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataApexWithoutPreInstalledApex) {
2117*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2118*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_different_app.apex");
2119*33f37583SAndroid Build Coastguard Worker
2120*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2121*33f37583SAndroid Build Coastguard Worker
2122*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
2123*33f37583SAndroid Build Coastguard Worker
2124*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2125*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2126*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2127*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1"));
2128*33f37583SAndroid Build Coastguard Worker
2129*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2130*33f37583SAndroid Build Coastguard Worker auto info_list =
2131*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2132*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2133*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2134*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2135*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2136*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2137*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2138*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
2139*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2140*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2141*33f37583SAndroid Build Coastguard Worker
2142*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2143*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1)));
2144*33f37583SAndroid Build Coastguard Worker }
2145*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapPreInstalledSharedLibsApex)2146*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapPreInstalledSharedLibsApex) {
2147*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2148*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 = AddPreInstalledApex(
2149*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex");
2150*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
2151*33f37583SAndroid Build Coastguard Worker
2152*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2153*33f37583SAndroid Build Coastguard Worker
2154*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
2155*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
2156*33f37583SAndroid Build Coastguard Worker
2157*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2158*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2159*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2160*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
2161*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1"));
2162*33f37583SAndroid Build Coastguard Worker
2163*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2164*33f37583SAndroid Build Coastguard Worker auto info_list =
2165*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2166*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2167*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2168*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2169*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2170*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2171*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2172*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
2173*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2174*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2175*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
2176*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test.sharedlibs",
2177*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2,
2178*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_2,
2179*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2180*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_2),
2181*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2182*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2183*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_3 = com::android::apex::ApexInfo(
2184*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2185*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_3,
2186*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2187*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2188*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
2189*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2190*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2191*33f37583SAndroid Build Coastguard Worker
2192*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2193*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
2194*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2),
2195*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_3)));
2196*33f37583SAndroid Build Coastguard Worker
2197*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/sharedlibs", F_OK), 0);
2198*33f37583SAndroid Build Coastguard Worker
2199*33f37583SAndroid Build Coastguard Worker // Check /apex/sharedlibs is populated properly.
2200*33f37583SAndroid Build Coastguard Worker std::vector<std::string> sharedlibs;
2201*33f37583SAndroid Build Coastguard Worker for (const auto& p : fs::recursive_directory_iterator("/apex/sharedlibs")) {
2202*33f37583SAndroid Build Coastguard Worker if (fs::is_symlink(p)) {
2203*33f37583SAndroid Build Coastguard Worker auto src = fs::read_symlink(p.path());
2204*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(p.path().filename(), src.filename());
2205*33f37583SAndroid Build Coastguard Worker sharedlibs.push_back(p.path().parent_path().string() + "->" +
2206*33f37583SAndroid Build Coastguard Worker src.parent_path().string());
2207*33f37583SAndroid Build Coastguard Worker }
2208*33f37583SAndroid Build Coastguard Worker }
2209*33f37583SAndroid Build Coastguard Worker
2210*33f37583SAndroid Build Coastguard Worker std::vector<std::string> expected = {
2211*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib/libsharedlibtest.so->"
2212*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1/lib/libsharedlibtest.so",
2213*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib/libc++.so->"
2214*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1/lib/libc++.so",
2215*33f37583SAndroid Build Coastguard Worker };
2216*33f37583SAndroid Build Coastguard Worker
2217*33f37583SAndroid Build Coastguard Worker // On 64bit devices we also have lib64.
2218*33f37583SAndroid Build Coastguard Worker if (!GetProperty("ro.product.cpu.abilist64", "").empty()) {
2219*33f37583SAndroid Build Coastguard Worker expected.push_back(
2220*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib64/libsharedlibtest.so->"
2221*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1/lib64/libsharedlibtest.so");
2222*33f37583SAndroid Build Coastguard Worker expected.push_back(
2223*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib64/libc++.so->"
2224*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1/lib64/libc++.so");
2225*33f37583SAndroid Build Coastguard Worker }
2226*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(sharedlibs, UnorderedElementsAreArray(expected));
2227*33f37583SAndroid Build Coastguard Worker }
2228*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSharedLibsApexBothVersions)2229*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSharedLibsApexBothVersions) {
2230*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2231*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 = AddPreInstalledApex(
2232*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex");
2233*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
2234*33f37583SAndroid Build Coastguard Worker std::string apex_path_4 =
2235*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex");
2236*33f37583SAndroid Build Coastguard Worker
2237*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2238*33f37583SAndroid Build Coastguard Worker
2239*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
2240*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
2241*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_4);
2242*33f37583SAndroid Build Coastguard Worker
2243*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2244*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2245*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2246*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
2247*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1",
2248*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2"));
2249*33f37583SAndroid Build Coastguard Worker
2250*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2251*33f37583SAndroid Build Coastguard Worker auto info_list =
2252*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2253*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2254*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2255*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2256*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2257*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2258*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2259*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
2260*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2261*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2262*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
2263*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test.sharedlibs",
2264*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2,
2265*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_2,
2266*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2267*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_2),
2268*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2269*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2270*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_3 = com::android::apex::ApexInfo(
2271*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2272*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_3,
2273*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2274*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2275*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
2276*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2277*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2278*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_4 = com::android::apex::ApexInfo(
2279*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test.sharedlibs",
2280*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_4,
2281*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_2,
2282*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2283*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_4),
2284*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2285*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2286*33f37583SAndroid Build Coastguard Worker
2287*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2288*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
2289*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2),
2290*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_3),
2291*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_4)));
2292*33f37583SAndroid Build Coastguard Worker
2293*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/sharedlibs", F_OK), 0);
2294*33f37583SAndroid Build Coastguard Worker
2295*33f37583SAndroid Build Coastguard Worker // Check /apex/sharedlibs is populated properly.
2296*33f37583SAndroid Build Coastguard Worker // Because we don't want to hardcode full paths (they are pretty long and have
2297*33f37583SAndroid Build Coastguard Worker // a hash in them which might change if new prebuilts are dropped in), the
2298*33f37583SAndroid Build Coastguard Worker // assertion logic is a little bit clunky.
2299*33f37583SAndroid Build Coastguard Worker std::vector<std::string> sharedlibs;
2300*33f37583SAndroid Build Coastguard Worker for (const auto& p : fs::recursive_directory_iterator("/apex/sharedlibs")) {
2301*33f37583SAndroid Build Coastguard Worker if (fs::is_symlink(p)) {
2302*33f37583SAndroid Build Coastguard Worker auto src = fs::read_symlink(p.path());
2303*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(p.path().filename(), src.filename());
2304*33f37583SAndroid Build Coastguard Worker sharedlibs.push_back(p.path().parent_path().string() + "->" +
2305*33f37583SAndroid Build Coastguard Worker src.parent_path().string());
2306*33f37583SAndroid Build Coastguard Worker }
2307*33f37583SAndroid Build Coastguard Worker }
2308*33f37583SAndroid Build Coastguard Worker
2309*33f37583SAndroid Build Coastguard Worker std::vector<std::string> expected = {
2310*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib/libsharedlibtest.so->"
2311*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2/lib/libsharedlibtest.so",
2312*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib/libsharedlibtest.so->"
2313*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1/lib/libsharedlibtest.so",
2314*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib/libc++.so->"
2315*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2/lib/libc++.so",
2316*33f37583SAndroid Build Coastguard Worker };
2317*33f37583SAndroid Build Coastguard Worker // On 64bit devices we also have lib64.
2318*33f37583SAndroid Build Coastguard Worker if (!GetProperty("ro.product.cpu.abilist64", "").empty()) {
2319*33f37583SAndroid Build Coastguard Worker expected.push_back(
2320*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib64/libsharedlibtest.so->"
2321*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2/lib64/libsharedlibtest.so");
2322*33f37583SAndroid Build Coastguard Worker expected.push_back(
2323*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib64/libsharedlibtest.so->"
2324*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@1/lib64/libsharedlibtest.so");
2325*33f37583SAndroid Build Coastguard Worker expected.push_back(
2326*33f37583SAndroid Build Coastguard Worker "/apex/sharedlibs/lib64/libc++.so->"
2327*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2/lib64/libc++.so");
2328*33f37583SAndroid Build Coastguard Worker }
2329*33f37583SAndroid Build Coastguard Worker
2330*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(sharedlibs, UnorderedElementsAreArray(expected));
2331*33f37583SAndroid Build Coastguard Worker }
2332*33f37583SAndroid Build Coastguard Worker
2333*33f37583SAndroid Build Coastguard Worker // Test when we move from uncompressed APEX to CAPEX via ota
TEST_F(ApexdMountTest,OnOtaChrootBootstrapOnlyCompressedApexes)2334*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapOnlyCompressedApexes) {
2335*33f37583SAndroid Build Coastguard Worker std::string apex_path =
2336*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
2337*33f37583SAndroid Build Coastguard Worker
2338*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2339*33f37583SAndroid Build Coastguard Worker
2340*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted from decompression_dir
2341*33f37583SAndroid Build Coastguard Worker std::string decompressed_apex =
2342*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
2343*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2344*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_apex);
2345*33f37583SAndroid Build Coastguard Worker
2346*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2347*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2348*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2349*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2350*33f37583SAndroid Build Coastguard Worker
2351*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2352*33f37583SAndroid Build Coastguard Worker auto info_list =
2353*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2354*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2355*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2356*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2357*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_apex,
2358*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2359*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2360*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(decompressed_apex),
2361*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2362*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2363*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2364*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2365*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2366*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2367*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2368*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2369*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2370*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2371*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_apex);
2372*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2373*33f37583SAndroid Build Coastguard Worker "[email protected]");
2374*33f37583SAndroid Build Coastguard Worker });
2375*33f37583SAndroid Build Coastguard Worker }
2376*33f37583SAndroid Build Coastguard Worker
2377*33f37583SAndroid Build Coastguard Worker // Test we decompress only once even if OnOtaChrootBootstrap is called multiple
2378*33f37583SAndroid Build Coastguard Worker // times
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDecompressOnlyOnceMultipleCalls)2379*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDecompressOnlyOnceMultipleCalls) {
2380*33f37583SAndroid Build Coastguard Worker std::string apex_path =
2381*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
2382*33f37583SAndroid Build Coastguard Worker
2383*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2384*33f37583SAndroid Build Coastguard Worker
2385*33f37583SAndroid Build Coastguard Worker // Decompressed OTA APEX should be mounted
2386*33f37583SAndroid Build Coastguard Worker std::string decompressed_ota_apex =
2387*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
2388*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2389*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_ota_apex);
2390*33f37583SAndroid Build Coastguard Worker
2391*33f37583SAndroid Build Coastguard Worker // Capture the creation time of the OTA APEX
2392*33f37583SAndroid Build Coastguard Worker std::error_code ec;
2393*33f37583SAndroid Build Coastguard Worker auto last_write_time_1 = fs::last_write_time(decompressed_ota_apex, ec);
2394*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(ec) << "Failed to capture last write time of "
2395*33f37583SAndroid Build Coastguard Worker << decompressed_ota_apex;
2396*33f37583SAndroid Build Coastguard Worker
2397*33f37583SAndroid Build Coastguard Worker // Call OnOtaChrootBootstrap again. Since we do not hardlink decompressed APEX
2398*33f37583SAndroid Build Coastguard Worker // to /data/apex/active directory when in chroot, when selecting apex for
2399*33f37583SAndroid Build Coastguard Worker // activation, we will end up selecting compressed APEX again.
2400*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2401*33f37583SAndroid Build Coastguard Worker
2402*33f37583SAndroid Build Coastguard Worker // Compare write time to ensure we did not decompress again
2403*33f37583SAndroid Build Coastguard Worker auto last_write_time_2 = fs::last_write_time(decompressed_ota_apex, ec);
2404*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(ec) << "Failed to capture last write time of "
2405*33f37583SAndroid Build Coastguard Worker << decompressed_ota_apex << ec.message();
2406*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(last_write_time_1, last_write_time_2);
2407*33f37583SAndroid Build Coastguard Worker }
2408*33f37583SAndroid Build Coastguard Worker
2409*33f37583SAndroid Build Coastguard Worker // Test when we upgrade existing CAPEX to higher version via OTA
TEST_F(ApexdMountTest,OnOtaChrootBootstrapUpgradeCapex)2410*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapUpgradeCapex) {
2411*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
2412*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex",
2413*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
2414*33f37583SAndroid Build Coastguard Worker // Place a higher version capex in current built_in_dir
2415*33f37583SAndroid Build Coastguard Worker std::string apex_path =
2416*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v2.capex");
2417*33f37583SAndroid Build Coastguard Worker
2418*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2419*33f37583SAndroid Build Coastguard Worker
2420*33f37583SAndroid Build Coastguard Worker // Upgraded decompressed APEX should be mounted from decompression dir
2421*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex =
2422*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@2%s",
2423*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2424*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
2425*33f37583SAndroid Build Coastguard Worker
2426*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2427*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2428*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2429*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@2"));
2430*33f37583SAndroid Build Coastguard Worker
2431*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2432*33f37583SAndroid Build Coastguard Worker auto info_list =
2433*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2434*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2435*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2436*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2437*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_active_apex,
2438*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2439*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2440*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2441*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_active_apex),
2442*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2443*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2444*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2445*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2446*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2447*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2448*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2449*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2450*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2451*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2452*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
2453*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2454*33f37583SAndroid Build Coastguard Worker "[email protected]");
2455*33f37583SAndroid Build Coastguard Worker });
2456*33f37583SAndroid Build Coastguard Worker }
2457*33f37583SAndroid Build Coastguard Worker
2458*33f37583SAndroid Build Coastguard Worker // Test when we update existing CAPEX to same version via OTA
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSamegradeCapex)2459*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSamegradeCapex) {
2460*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
2461*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex",
2462*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
2463*33f37583SAndroid Build Coastguard Worker // Place a same version capex in current built_in_dir, under a different name
2464*33f37583SAndroid Build Coastguard Worker auto apex_path =
2465*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/different-name.capex", GetBuiltInDir().c_str());
2466*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v1.capex"), apex_path);
2467*33f37583SAndroid Build Coastguard Worker
2468*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2469*33f37583SAndroid Build Coastguard Worker
2470*33f37583SAndroid Build Coastguard Worker // Previously decompressed APEX should be mounted from decompression_dir
2471*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
2472*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
2473*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
2474*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
2475*33f37583SAndroid Build Coastguard Worker
2476*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2477*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2478*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2479*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2480*33f37583SAndroid Build Coastguard Worker
2481*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2482*33f37583SAndroid Build Coastguard Worker auto info_list =
2483*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2484*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2485*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2486*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2487*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_active_apex,
2488*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2489*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2490*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2491*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_active_apex),
2492*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2493*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2494*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2495*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2496*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2497*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2498*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2499*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2500*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2501*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2502*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
2503*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2504*33f37583SAndroid Build Coastguard Worker "[email protected]");
2505*33f37583SAndroid Build Coastguard Worker });
2506*33f37583SAndroid Build Coastguard Worker }
2507*33f37583SAndroid Build Coastguard Worker
2508*33f37583SAndroid Build Coastguard Worker // Test when we update existing CAPEX to same version, but different digest
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSamegradeCapexDifferentDigest)2509*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSamegradeCapexDifferentDigest) {
2510*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
2511*33f37583SAndroid Build Coastguard Worker auto different_digest_apex_path = PrepareCompressedApex(
2512*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed.v1_different_digest.capex",
2513*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
2514*33f37583SAndroid Build Coastguard Worker // Place a same version capex in current built_in_dir, which has different
2515*33f37583SAndroid Build Coastguard Worker // digest
2516*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
2517*33f37583SAndroid Build Coastguard Worker
2518*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2519*33f37583SAndroid Build Coastguard Worker
2520*33f37583SAndroid Build Coastguard Worker // New decompressed ota APEX should be mounted with kOtaApexPackageSuffix
2521*33f37583SAndroid Build Coastguard Worker std::string decompressed_ota_apex =
2522*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
2523*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2524*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_ota_apex);
2525*33f37583SAndroid Build Coastguard Worker
2526*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2527*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2528*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2529*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2530*33f37583SAndroid Build Coastguard Worker
2531*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2532*33f37583SAndroid Build Coastguard Worker auto info_list =
2533*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2534*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2535*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2536*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2537*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_ota_apex,
2538*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2539*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2540*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2541*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_ota_apex),
2542*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2543*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2544*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2545*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2546*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2547*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2548*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2549*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2550*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2551*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2552*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_ota_apex);
2553*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2554*33f37583SAndroid Build Coastguard Worker "[email protected]");
2555*33f37583SAndroid Build Coastguard Worker });
2556*33f37583SAndroid Build Coastguard Worker
2557*33f37583SAndroid Build Coastguard Worker // Ensure decompressed apex has same digest as pre-installed
2558*33f37583SAndroid Build Coastguard Worker auto pre_installed_apex = ApexFile::Open(apex_path);
2559*33f37583SAndroid Build Coastguard Worker auto decompressed_apex = ApexFile::Open(decompressed_ota_apex);
2560*33f37583SAndroid Build Coastguard Worker auto different_digest_apex = ApexFile::Open(different_digest_apex_path);
2561*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(
2562*33f37583SAndroid Build Coastguard Worker pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
2563*33f37583SAndroid Build Coastguard Worker GetRootDigest(*decompressed_apex));
2564*33f37583SAndroid Build Coastguard Worker ASSERT_NE(
2565*33f37583SAndroid Build Coastguard Worker pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
2566*33f37583SAndroid Build Coastguard Worker GetRootDigest(*different_digest_apex));
2567*33f37583SAndroid Build Coastguard Worker
2568*33f37583SAndroid Build Coastguard Worker // Ensure we didn't remove previous decompressed APEX
2569*33f37583SAndroid Build Coastguard Worker std::string previous_decompressed_apex = StringPrintf(
2570*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
2571*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
2572*33f37583SAndroid Build Coastguard Worker auto path_exists = PathExists(previous_decompressed_apex);
2573*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(*path_exists);
2574*33f37583SAndroid Build Coastguard Worker }
2575*33f37583SAndroid Build Coastguard Worker
2576*33f37583SAndroid Build Coastguard Worker // Test when we update existing CAPEX to same version, but different key via OTA
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSamegradeCapexDifferentKey)2577*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSamegradeCapexDifferentKey) {
2578*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
2579*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed_different_key.capex",
2580*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
2581*33f37583SAndroid Build Coastguard Worker // Place a same version capex in current built_in_dir, which has different key
2582*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
2583*33f37583SAndroid Build Coastguard Worker
2584*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2585*33f37583SAndroid Build Coastguard Worker
2586*33f37583SAndroid Build Coastguard Worker // New decompressed APEX should be mounted from ota_reserved directory
2587*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex =
2588*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
2589*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2590*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
2591*33f37583SAndroid Build Coastguard Worker
2592*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2593*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2594*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2595*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2596*33f37583SAndroid Build Coastguard Worker
2597*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2598*33f37583SAndroid Build Coastguard Worker auto info_list =
2599*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2600*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2601*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2602*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2603*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_active_apex,
2604*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2605*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2606*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2607*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_active_apex),
2608*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2609*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2610*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2611*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2612*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2613*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2614*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2615*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2616*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2617*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2618*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
2619*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2620*33f37583SAndroid Build Coastguard Worker "[email protected]");
2621*33f37583SAndroid Build Coastguard Worker });
2622*33f37583SAndroid Build Coastguard Worker }
2623*33f37583SAndroid Build Coastguard Worker
2624*33f37583SAndroid Build Coastguard Worker // Test when we remove CAPEX via OTA
TEST_F(ApexdMountTest,OnOtaChrootBootstrapCapexToApex)2625*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapCapexToApex) {
2626*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
2627*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex",
2628*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
2629*33f37583SAndroid Build Coastguard Worker // Place a uncompressed version apex in current built_in_dir
2630*33f37583SAndroid Build Coastguard Worker std::string apex_path =
2631*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.apex");
2632*33f37583SAndroid Build Coastguard Worker
2633*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2634*33f37583SAndroid Build Coastguard Worker
2635*33f37583SAndroid Build Coastguard Worker // New uncompressed APEX should be mounted
2636*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path);
2637*33f37583SAndroid Build Coastguard Worker
2638*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2639*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2640*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2641*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2642*33f37583SAndroid Build Coastguard Worker
2643*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2644*33f37583SAndroid Build Coastguard Worker auto info_list =
2645*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2646*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2647*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_uncompressed = com::android::apex::ApexInfo(
2648*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2649*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path,
2650*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2651*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2652*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path),
2653*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2654*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2655*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2656*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_uncompressed)));
2657*33f37583SAndroid Build Coastguard Worker }
2658*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDecompressedApexVersionDifferentThanCapex)2659*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
2660*33f37583SAndroid Build Coastguard Worker OnOtaChrootBootstrapDecompressedApexVersionDifferentThanCapex) {
2661*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
2662*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v2.capex",
2663*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
2664*33f37583SAndroid Build Coastguard Worker // Place a lower version capex in current built_in_dir, so that previously
2665*33f37583SAndroid Build Coastguard Worker // decompressed APEX has higher version but still doesn't get picked during
2666*33f37583SAndroid Build Coastguard Worker // selection.
2667*33f37583SAndroid Build Coastguard Worker std::string apex_path =
2668*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
2669*33f37583SAndroid Build Coastguard Worker
2670*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2671*33f37583SAndroid Build Coastguard Worker
2672*33f37583SAndroid Build Coastguard Worker // Pre-installed CAPEX should be decompressed again and mounted from
2673*33f37583SAndroid Build Coastguard Worker // decompression_dir
2674*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex =
2675*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
2676*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2677*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
2678*33f37583SAndroid Build Coastguard Worker
2679*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2680*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2681*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2682*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2683*33f37583SAndroid Build Coastguard Worker
2684*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2685*33f37583SAndroid Build Coastguard Worker auto info_list =
2686*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2687*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2688*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2689*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2690*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_active_apex,
2691*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2692*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2693*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2694*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_active_apex),
2695*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2696*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2697*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2698*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2699*33f37583SAndroid Build Coastguard Worker }
2700*33f37583SAndroid Build Coastguard Worker
2701*33f37583SAndroid Build Coastguard Worker // Test when we update CAPEX and there is a higher version present in data
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataHigherThanCapex)2702*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataHigherThanCapex) {
2703*33f37583SAndroid Build Coastguard Worker auto system_apex_path =
2704*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex");
2705*33f37583SAndroid Build Coastguard Worker auto data_apex_path =
2706*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v2_original.apex");
2707*33f37583SAndroid Build Coastguard Worker
2708*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2709*33f37583SAndroid Build Coastguard Worker
2710*33f37583SAndroid Build Coastguard Worker // Data APEX should be mounted
2711*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(data_apex_path);
2712*33f37583SAndroid Build Coastguard Worker
2713*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2714*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2715*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2716*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@2"));
2717*33f37583SAndroid Build Coastguard Worker
2718*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2719*33f37583SAndroid Build Coastguard Worker auto info_list =
2720*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2721*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2722*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_data = com::android::apex::ApexInfo(
2723*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2724*33f37583SAndroid Build Coastguard Worker /* modulePath= */ data_apex_path,
2725*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ system_apex_path,
2726*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2727*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(data_apex_path),
2728*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2729*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2730*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_system = com::android::apex::ApexInfo(
2731*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2732*33f37583SAndroid Build Coastguard Worker /* modulePath= */ system_apex_path,
2733*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ system_apex_path,
2734*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2735*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(system_apex_path),
2736*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2737*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2738*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2739*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_data),
2740*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_system)));
2741*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2742*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2743*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2744*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2745*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2746*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2747*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, data_apex_path);
2748*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2749*33f37583SAndroid Build Coastguard Worker "[email protected]");
2750*33f37583SAndroid Build Coastguard Worker });
2751*33f37583SAndroid Build Coastguard Worker }
2752*33f37583SAndroid Build Coastguard Worker
2753*33f37583SAndroid Build Coastguard Worker // Test when we update CAPEX and there is a lower version present in data
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataLowerThanCapex)2754*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataLowerThanCapex) {
2755*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v2.capex");
2756*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v1.apex");
2757*33f37583SAndroid Build Coastguard Worker
2758*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2759*33f37583SAndroid Build Coastguard Worker
2760*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted from reserved dir
2761*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex =
2762*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@2%s",
2763*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2764*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
2765*33f37583SAndroid Build Coastguard Worker
2766*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2767*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2768*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2769*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@2"));
2770*33f37583SAndroid Build Coastguard Worker
2771*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2772*33f37583SAndroid Build Coastguard Worker auto info_list =
2773*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2774*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2775*33f37583SAndroid Build Coastguard Worker auto apex_info_xml = com::android::apex::ApexInfo(
2776*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2777*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_active_apex,
2778*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2779*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2780*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2781*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_active_apex),
2782*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2783*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2784*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2785*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml)));
2786*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2787*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2788*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2789*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2790*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2791*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2792*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
2793*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2794*33f37583SAndroid Build Coastguard Worker "[email protected]");
2795*33f37583SAndroid Build Coastguard Worker });
2796*33f37583SAndroid Build Coastguard Worker }
2797*33f37583SAndroid Build Coastguard Worker
2798*33f37583SAndroid Build Coastguard Worker // Test when we update CAPEX and there is a same version present in data
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataSameAsCapex)2799*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataSameAsCapex) {
2800*33f37583SAndroid Build Coastguard Worker auto system_apex_path =
2801*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex");
2802*33f37583SAndroid Build Coastguard Worker auto data_apex_path = AddDataApex("com.android.apex.compressed.v1.apex");
2803*33f37583SAndroid Build Coastguard Worker
2804*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2805*33f37583SAndroid Build Coastguard Worker
2806*33f37583SAndroid Build Coastguard Worker // Data APEX should be mounted
2807*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(data_apex_path);
2808*33f37583SAndroid Build Coastguard Worker
2809*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2810*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2811*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2812*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2813*33f37583SAndroid Build Coastguard Worker
2814*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2815*33f37583SAndroid Build Coastguard Worker auto info_list =
2816*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2817*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2818*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_data = com::android::apex::ApexInfo(
2819*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2820*33f37583SAndroid Build Coastguard Worker /* modulePath= */ data_apex_path,
2821*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ system_apex_path,
2822*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2823*33f37583SAndroid Build Coastguard Worker /* isFactory= */ false, /* isActive= */ true, GetMTime(data_apex_path),
2824*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2825*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2826*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_system = com::android::apex::ApexInfo(
2827*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2828*33f37583SAndroid Build Coastguard Worker /* modulePath= */ system_apex_path,
2829*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ system_apex_path,
2830*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2831*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(system_apex_path),
2832*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2833*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2834*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2835*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_data),
2836*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_system)));
2837*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2838*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2839*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2840*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2841*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2842*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2843*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, data_apex_path);
2844*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2845*33f37583SAndroid Build Coastguard Worker "[email protected]");
2846*33f37583SAndroid Build Coastguard Worker });
2847*33f37583SAndroid Build Coastguard Worker }
2848*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDataHasDifferentKeyThanCapex)2849*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDataHasDifferentKeyThanCapex) {
2850*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed_different_key.capex");
2851*33f37583SAndroid Build Coastguard Worker // Place a same version capex in current built_in_dir, which has different key
2852*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
2853*33f37583SAndroid Build Coastguard Worker
2854*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2855*33f37583SAndroid Build Coastguard Worker
2856*33f37583SAndroid Build Coastguard Worker // New decompressed APEX should be mounted from ota_reserved directory
2857*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex =
2858*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s",
2859*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
2860*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
2861*33f37583SAndroid Build Coastguard Worker
2862*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2863*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2864*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
2865*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
2866*33f37583SAndroid Build Coastguard Worker
2867*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2868*33f37583SAndroid Build Coastguard Worker auto info_list =
2869*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2870*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2871*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_decompressed = com::android::apex::ApexInfo(
2872*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.compressed",
2873*33f37583SAndroid Build Coastguard Worker /* modulePath= */ decompressed_active_apex,
2874*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path,
2875*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2876*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true,
2877*33f37583SAndroid Build Coastguard Worker GetMTime(decompressed_active_apex),
2878*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2879*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2880*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2881*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
2882*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
2883*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
2884*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
2885*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
2886*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
2887*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
2888*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
2889*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
2890*33f37583SAndroid Build Coastguard Worker "[email protected]");
2891*33f37583SAndroid Build Coastguard Worker });
2892*33f37583SAndroid Build Coastguard Worker }
2893*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSystemDataStagedInSameVersion)2894*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSystemDataStagedInSameVersion) {
2895*33f37583SAndroid Build Coastguard Worker // The APEXes on system, data, and staged are all in the same version. The
2896*33f37583SAndroid Build Coastguard Worker // staged one should be picked.
2897*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2898*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test.apex");
2899*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
2900*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
2901*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 =
2902*33f37583SAndroid Build Coastguard Worker GetStagedDir(apex_session->GetId()) + "/" + "apex.apexd_test.apex";
2903*33f37583SAndroid Build Coastguard Worker
2904*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/true), 0);
2905*33f37583SAndroid Build Coastguard Worker
2906*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
2907*33f37583SAndroid Build Coastguard Worker
2908*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2909*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2910*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2911*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1"));
2912*33f37583SAndroid Build Coastguard Worker
2913*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2914*33f37583SAndroid Build Coastguard Worker auto info_list =
2915*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2916*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2917*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
2918*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2919*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2920*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2921*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
2922*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
2923*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2924*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2925*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
2926*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2927*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_3, /* preinstalledModulePath= */ apex_path_1,
2928*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ false,
2929*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_3),
2930*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2931*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2932*33f37583SAndroid Build Coastguard Worker
2933*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2934*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
2935*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
2936*33f37583SAndroid Build Coastguard Worker }
2937*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSystemNewerThanDataStaged)2938*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSystemNewerThanDataStaged) {
2939*33f37583SAndroid Build Coastguard Worker // The system one is newer than the data one and the staged one. The system
2940*33f37583SAndroid Build Coastguard Worker // one should be picked.
2941*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test_v2.apex");
2942*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test.apex");
2943*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
2944*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
2945*33f37583SAndroid Build Coastguard Worker
2946*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/true), 0);
2947*33f37583SAndroid Build Coastguard Worker
2948*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
2949*33f37583SAndroid Build Coastguard Worker
2950*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
2951*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
2952*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
2953*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2"));
2954*33f37583SAndroid Build Coastguard Worker
2955*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
2956*33f37583SAndroid Build Coastguard Worker auto info_list =
2957*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
2958*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
2959*33f37583SAndroid Build Coastguard Worker auto apex_info_xml = com::android::apex::ApexInfo(
2960*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
2961*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
2962*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
2963*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 2, /* versionName= */ "2",
2964*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
2965*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
2966*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
2967*33f37583SAndroid Build Coastguard Worker
2968*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
2969*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml)));
2970*33f37583SAndroid Build Coastguard Worker }
2971*33f37583SAndroid Build Coastguard Worker
GetSelinuxContext(const std::string & file)2972*33f37583SAndroid Build Coastguard Worker static std::string GetSelinuxContext(const std::string& file) {
2973*33f37583SAndroid Build Coastguard Worker char* ctx;
2974*33f37583SAndroid Build Coastguard Worker if (getfilecon(file.c_str(), &ctx) < 0) {
2975*33f37583SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to getfilecon " << file;
2976*33f37583SAndroid Build Coastguard Worker return "";
2977*33f37583SAndroid Build Coastguard Worker }
2978*33f37583SAndroid Build Coastguard Worker std::string result(ctx);
2979*33f37583SAndroid Build Coastguard Worker freecon(ctx);
2980*33f37583SAndroid Build Coastguard Worker return result;
2981*33f37583SAndroid Build Coastguard Worker }
2982*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapSelinuxLabelsAreCorrect)2983*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapSelinuxLabelsAreCorrect) {
2984*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
2985*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 = AddPreInstalledApex(
2986*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex");
2987*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
2988*33f37583SAndroid Build Coastguard Worker
2989*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
2990*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
2991*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
2992*33f37583SAndroid Build Coastguard Worker
2993*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(GetSelinuxContext("/apex/apex-info-list.xml"),
2994*33f37583SAndroid Build Coastguard Worker "u:object_r:apex_info_file:s0");
2995*33f37583SAndroid Build Coastguard Worker
2996*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(GetSelinuxContext("/apex/sharedlibs"),
2997*33f37583SAndroid Build Coastguard Worker "u:object_r:apex_mnt_dir:s0");
2998*33f37583SAndroid Build Coastguard Worker
2999*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(GetSelinuxContext("/apex/com.android.apex.test_package"),
3000*33f37583SAndroid Build Coastguard Worker "u:object_r:system_file:s0");
3001*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(GetSelinuxContext("/apex/com.android.apex.test_package@2"),
3002*33f37583SAndroid Build Coastguard Worker "u:object_r:system_file:s0");
3003*33f37583SAndroid Build Coastguard Worker }
3004*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapDmDevicesHaveCorrectName)3005*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnOtaChrootBootstrapDmDevicesHaveCorrectName) {
3006*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
3007*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3008*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3009*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
3010*33f37583SAndroid Build Coastguard Worker
3011*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
3012*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3013*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
3014*33f37583SAndroid Build Coastguard Worker
3015*33f37583SAndroid Build Coastguard Worker MountedApexDatabase& db = GetApexDatabaseForTesting();
3016*33f37583SAndroid Build Coastguard Worker // com.android.apex.test_package_2 should be mounted directly on top of loop
3017*33f37583SAndroid Build Coastguard Worker // device.
3018*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package_2",
3019*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3020*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3021*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(data.device_name, IsEmpty());
3022*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(data.loop_name, StartsWith("/dev"));
3023*33f37583SAndroid Build Coastguard Worker });
3024*33f37583SAndroid Build Coastguard Worker // com.android.apex.test_package should be mounted on top of dm-verity device.
3025*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package",
3026*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3027*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3028*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3029*33f37583SAndroid Build Coastguard Worker "[email protected]");
3030*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(data.loop_name, StartsWith("/dev"));
3031*33f37583SAndroid Build Coastguard Worker });
3032*33f37583SAndroid Build Coastguard Worker }
3033*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapFailsToActivatePreInstalledApexKeepsGoing)3034*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
3035*33f37583SAndroid Build Coastguard Worker OnOtaChrootBootstrapFailsToActivatePreInstalledApexKeepsGoing) {
3036*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 =
3037*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_manifest_mismatch.apex");
3038*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3039*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3040*33f37583SAndroid Build Coastguard Worker
3041*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
3042*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3043*33f37583SAndroid Build Coastguard Worker
3044*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3045*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3046*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package_2",
3047*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3048*33f37583SAndroid Build Coastguard Worker
3049*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
3050*33f37583SAndroid Build Coastguard Worker auto info_list =
3051*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
3052*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
3053*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
3054*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
3055*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
3056*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
3057*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 137, /* versionName= */ "1",
3058*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
3059*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
3060*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
3061*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
3062*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
3063*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
3064*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
3065*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
3066*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
3067*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
3068*33f37583SAndroid Build Coastguard Worker
3069*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
3070*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
3071*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
3072*33f37583SAndroid Build Coastguard Worker }
3073*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnOtaChrootBootstrapFailsToActivateDataApexFallsBackToPreInstalled)3074*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
3075*33f37583SAndroid Build Coastguard Worker OnOtaChrootBootstrapFailsToActivateDataApexFallsBackToPreInstalled) {
3076*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
3077*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3078*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3079*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 =
3080*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_manifest_mismatch.apex");
3081*33f37583SAndroid Build Coastguard Worker
3082*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(OnOtaChrootBootstrap(/*also_include_staged_apexes=*/false), 0);
3083*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
3084*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3085*33f37583SAndroid Build Coastguard Worker
3086*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3087*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3088*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3089*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
3090*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3091*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3092*33f37583SAndroid Build Coastguard Worker
3093*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
3094*33f37583SAndroid Build Coastguard Worker auto info_list =
3095*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
3096*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
3097*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
3098*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
3099*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_1,
3100*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ apex_path_1,
3101*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
3102*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
3103*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
3104*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
3105*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_2 = com::android::apex::ApexInfo(
3106*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package_2",
3107*33f37583SAndroid Build Coastguard Worker /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
3108*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
3109*33f37583SAndroid Build Coastguard Worker /* isActive= */ true, GetMTime(apex_path_2),
3110*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
3111*33f37583SAndroid Build Coastguard Worker /* partition= */ GetPartitionString());
3112*33f37583SAndroid Build Coastguard Worker
3113*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
3114*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
3115*33f37583SAndroid Build Coastguard Worker ApexInfoXmlEq(apex_info_xml_2)));
3116*33f37583SAndroid Build Coastguard Worker }
3117*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartOnlyPreInstalledApexes)3118*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartOnlyPreInstalledApexes) {
3119*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3120*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3121*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3122*33f37583SAndroid Build Coastguard Worker
3123*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
3124*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3125*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3126*33f37583SAndroid Build Coastguard Worker
3127*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3128*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3129*33f37583SAndroid Build Coastguard Worker Ok());
3130*33f37583SAndroid Build Coastguard Worker
3131*33f37583SAndroid Build Coastguard Worker OnStart();
3132*33f37583SAndroid Build Coastguard Worker
3133*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
3134*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3135*33f37583SAndroid Build Coastguard Worker
3136*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3137*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3138*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3139*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3140*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
3141*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3142*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3143*33f37583SAndroid Build Coastguard Worker }
3144*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartDataHasHigherVersion)3145*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDataHasHigherVersion) {
3146*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3147*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3148*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3149*33f37583SAndroid Build Coastguard Worker
3150*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
3151*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3152*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3153*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
3154*33f37583SAndroid Build Coastguard Worker
3155*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3156*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3157*33f37583SAndroid Build Coastguard Worker Ok());
3158*33f37583SAndroid Build Coastguard Worker
3159*33f37583SAndroid Build Coastguard Worker OnStart();
3160*33f37583SAndroid Build Coastguard Worker
3161*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3162*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
3163*33f37583SAndroid Build Coastguard Worker
3164*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3165*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3166*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3167*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3168*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
3169*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3170*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3171*33f37583SAndroid Build Coastguard Worker }
3172*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartDataHasWrongSHA)3173*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDataHasWrongSHA) {
3174*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3175*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3176*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3177*33f37583SAndroid Build Coastguard Worker
3178*33f37583SAndroid Build Coastguard Worker std::string apex_path = AddPreInstalledApex("com.android.apex.cts.shim.apex");
3179*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.cts.shim.v2_wrong_sha.apex");
3180*33f37583SAndroid Build Coastguard Worker
3181*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3182*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3183*33f37583SAndroid Build Coastguard Worker Ok());
3184*33f37583SAndroid Build Coastguard Worker
3185*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path);
3186*33f37583SAndroid Build Coastguard Worker OnStart();
3187*33f37583SAndroid Build Coastguard Worker
3188*33f37583SAndroid Build Coastguard Worker // Check system shim apex is activated instead of the data one.
3189*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3190*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3191*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.cts.shim",
3192*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.cts.shim@1"));
3193*33f37583SAndroid Build Coastguard Worker }
3194*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartDataHasSameVersion)3195*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDataHasSameVersion) {
3196*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3197*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3198*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3199*33f37583SAndroid Build Coastguard Worker
3200*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
3201*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3202*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3203*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test.apex");
3204*33f37583SAndroid Build Coastguard Worker
3205*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3206*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3207*33f37583SAndroid Build Coastguard Worker Ok());
3208*33f37583SAndroid Build Coastguard Worker
3209*33f37583SAndroid Build Coastguard Worker OnStart();
3210*33f37583SAndroid Build Coastguard Worker
3211*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3212*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
3213*33f37583SAndroid Build Coastguard Worker
3214*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3215*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3216*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3217*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3218*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
3219*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3220*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3221*33f37583SAndroid Build Coastguard Worker
3222*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3223*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from data apex, not pre-installed one.
3224*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package",
3225*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3226*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3227*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path_3);
3228*33f37583SAndroid Build Coastguard Worker });
3229*33f37583SAndroid Build Coastguard Worker }
3230*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartSystemHasHigherVersion)3231*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartSystemHasHigherVersion) {
3232*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3233*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3234*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3235*33f37583SAndroid Build Coastguard Worker
3236*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test_v2.apex");
3237*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3238*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3239*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test.apex");
3240*33f37583SAndroid Build Coastguard Worker
3241*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3242*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3243*33f37583SAndroid Build Coastguard Worker Ok());
3244*33f37583SAndroid Build Coastguard Worker
3245*33f37583SAndroid Build Coastguard Worker OnStart();
3246*33f37583SAndroid Build Coastguard Worker
3247*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
3248*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3249*33f37583SAndroid Build Coastguard Worker
3250*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3251*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3252*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3253*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3254*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
3255*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3256*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3257*33f37583SAndroid Build Coastguard Worker
3258*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3259*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from pre-installed one.
3260*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package",
3261*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3262*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3263*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path_1);
3264*33f37583SAndroid Build Coastguard Worker });
3265*33f37583SAndroid Build Coastguard Worker }
3266*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartFailsToActivateApexOnDataFallsBackToBuiltIn)3267*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartFailsToActivateApexOnDataFallsBackToBuiltIn) {
3268*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3269*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3270*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3271*33f37583SAndroid Build Coastguard Worker
3272*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
3273*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3274*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3275*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_manifest_mismatch.apex");
3276*33f37583SAndroid Build Coastguard Worker
3277*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3278*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3279*33f37583SAndroid Build Coastguard Worker Ok());
3280*33f37583SAndroid Build Coastguard Worker
3281*33f37583SAndroid Build Coastguard Worker OnStart();
3282*33f37583SAndroid Build Coastguard Worker
3283*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
3284*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3285*33f37583SAndroid Build Coastguard Worker
3286*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3287*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3288*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3289*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3290*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
3291*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3292*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3293*33f37583SAndroid Build Coastguard Worker
3294*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3295*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from pre-installed apex.
3296*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package",
3297*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3298*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3299*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path_1);
3300*33f37583SAndroid Build Coastguard Worker });
3301*33f37583SAndroid Build Coastguard Worker }
3302*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartApexOnDataHasWrongKeyFallsBackToBuiltIn)3303*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartApexOnDataHasWrongKeyFallsBackToBuiltIn) {
3304*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3305*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3306*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3307*33f37583SAndroid Build Coastguard Worker
3308*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
3309*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3310*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3311*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 =
3312*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_different_key_v2.apex");
3313*33f37583SAndroid Build Coastguard Worker
3314*33f37583SAndroid Build Coastguard Worker {
3315*33f37583SAndroid Build Coastguard Worker auto apex = ApexFile::Open(apex_path_3);
3316*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex, Ok());
3317*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<uint64_t>(apex->GetManifest().version()), 2ULL);
3318*33f37583SAndroid Build Coastguard Worker }
3319*33f37583SAndroid Build Coastguard Worker
3320*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3321*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3322*33f37583SAndroid Build Coastguard Worker Ok());
3323*33f37583SAndroid Build Coastguard Worker
3324*33f37583SAndroid Build Coastguard Worker OnStart();
3325*33f37583SAndroid Build Coastguard Worker
3326*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
3327*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3328*33f37583SAndroid Build Coastguard Worker
3329*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3330*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3331*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3332*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3333*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
3334*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3335*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3336*33f37583SAndroid Build Coastguard Worker
3337*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3338*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from pre-installed apex.
3339*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.test_package",
3340*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3341*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3342*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path_1);
3343*33f37583SAndroid Build Coastguard Worker });
3344*33f37583SAndroid Build Coastguard Worker }
3345*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartOnlyPreInstalledCapexes)3346*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartOnlyPreInstalledCapexes) {
3347*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3348*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3349*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3350*33f37583SAndroid Build Coastguard Worker
3351*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 =
3352*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3353*33f37583SAndroid Build Coastguard Worker
3354*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3355*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3356*33f37583SAndroid Build Coastguard Worker Ok());
3357*33f37583SAndroid Build Coastguard Worker
3358*33f37583SAndroid Build Coastguard Worker OnStart();
3359*33f37583SAndroid Build Coastguard Worker
3360*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted
3361*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3362*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3363*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3364*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3365*33f37583SAndroid Build Coastguard Worker
3366*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3367*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3368*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3369*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3370*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
3371*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3372*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex.
3373*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3374*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3375*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3376*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
3377*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3378*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3379*33f37583SAndroid Build Coastguard Worker });
3380*33f37583SAndroid Build Coastguard Worker }
3381*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartDataHasHigherVersionThanCapex)3382*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDataHasHigherVersionThanCapex) {
3383*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3384*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3385*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3386*33f37583SAndroid Build Coastguard Worker
3387*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3388*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3389*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v2_original.apex");
3390*33f37583SAndroid Build Coastguard Worker
3391*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3392*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3393*33f37583SAndroid Build Coastguard Worker Ok());
3394*33f37583SAndroid Build Coastguard Worker
3395*33f37583SAndroid Build Coastguard Worker OnStart();
3396*33f37583SAndroid Build Coastguard Worker
3397*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3398*33f37583SAndroid Build Coastguard Worker
3399*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3400*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3401*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3402*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3403*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@2"));
3404*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3405*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from data apex.
3406*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3407*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3408*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3409*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path_2);
3410*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3411*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3412*33f37583SAndroid Build Coastguard Worker });
3413*33f37583SAndroid Build Coastguard Worker }
3414*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartDataHasSameVersionAsCapex)3415*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDataHasSameVersionAsCapex) {
3416*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3417*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3418*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3419*33f37583SAndroid Build Coastguard Worker
3420*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3421*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 = AddDataApex("com.android.apex.compressed.v1.apex");
3422*33f37583SAndroid Build Coastguard Worker
3423*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3424*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3425*33f37583SAndroid Build Coastguard Worker Ok());
3426*33f37583SAndroid Build Coastguard Worker
3427*33f37583SAndroid Build Coastguard Worker OnStart();
3428*33f37583SAndroid Build Coastguard Worker
3429*33f37583SAndroid Build Coastguard Worker // Data APEX should be mounted
3430*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3431*33f37583SAndroid Build Coastguard Worker
3432*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3433*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3434*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3435*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3436*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
3437*33f37583SAndroid Build Coastguard Worker
3438*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3439*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from data apex, not pre-installed one.
3440*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3441*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3442*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3443*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path_2);
3444*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3445*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3446*33f37583SAndroid Build Coastguard Worker });
3447*33f37583SAndroid Build Coastguard Worker }
3448*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartSystemHasHigherVersionCapexThanData)3449*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartSystemHasHigherVersionCapexThanData) {
3450*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3451*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3452*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3453*33f37583SAndroid Build Coastguard Worker
3454*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 =
3455*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v2.capex");
3456*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v1.apex");
3457*33f37583SAndroid Build Coastguard Worker
3458*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3459*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3460*33f37583SAndroid Build Coastguard Worker Ok());
3461*33f37583SAndroid Build Coastguard Worker
3462*33f37583SAndroid Build Coastguard Worker OnStart();
3463*33f37583SAndroid Build Coastguard Worker
3464*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted
3465*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3466*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@2%s", GetDecompressionDir().c_str(),
3467*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3468*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3469*33f37583SAndroid Build Coastguard Worker
3470*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3471*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3472*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3473*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3474*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@2"));
3475*33f37583SAndroid Build Coastguard Worker
3476*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3477*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from compressed apex
3478*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3479*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3480*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3481*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
3482*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3483*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3484*33f37583SAndroid Build Coastguard Worker });
3485*33f37583SAndroid Build Coastguard Worker }
3486*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartFailsToActivateApexOnDataFallsBackToCapex)3487*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartFailsToActivateApexOnDataFallsBackToCapex) {
3488*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3489*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3490*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3491*33f37583SAndroid Build Coastguard Worker
3492*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3493*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v2_manifest_mismatch.apex");
3494*33f37583SAndroid Build Coastguard Worker
3495*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3496*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3497*33f37583SAndroid Build Coastguard Worker Ok());
3498*33f37583SAndroid Build Coastguard Worker
3499*33f37583SAndroid Build Coastguard Worker OnStart();
3500*33f37583SAndroid Build Coastguard Worker
3501*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted
3502*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3503*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3504*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3505*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3506*33f37583SAndroid Build Coastguard Worker
3507*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3508*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3509*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3510*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3511*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
3512*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3513*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex. It should also be mounted
3514*33f37583SAndroid Build Coastguard Worker // on dm-verity device.
3515*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3516*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3517*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3518*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
3519*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3520*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3521*33f37583SAndroid Build Coastguard Worker });
3522*33f37583SAndroid Build Coastguard Worker }
3523*33f37583SAndroid Build Coastguard Worker
3524*33f37583SAndroid Build Coastguard Worker // Test scenario when we fallback to capex but it already has a decompressed
3525*33f37583SAndroid Build Coastguard Worker // version on data
TEST_F(ApexdMountTest,OnStartFallbackToAlreadyDecompressedCapex)3526*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartFallbackToAlreadyDecompressedCapex) {
3527*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3528*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3529*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3530*33f37583SAndroid Build Coastguard Worker
3531*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex");
3532*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.compressed.v2_manifest_mismatch.apex");
3533*33f37583SAndroid Build Coastguard Worker
3534*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3535*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3536*33f37583SAndroid Build Coastguard Worker Ok());
3537*33f37583SAndroid Build Coastguard Worker
3538*33f37583SAndroid Build Coastguard Worker OnStart();
3539*33f37583SAndroid Build Coastguard Worker
3540*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted
3541*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3542*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3543*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3544*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3545*33f37583SAndroid Build Coastguard Worker
3546*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3547*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3548*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3549*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3550*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
3551*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3552*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex.
3553*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3554*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3555*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3556*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
3557*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3558*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3559*33f37583SAndroid Build Coastguard Worker });
3560*33f37583SAndroid Build Coastguard Worker }
3561*33f37583SAndroid Build Coastguard Worker
3562*33f37583SAndroid Build Coastguard Worker // Test scenario when we fallback to capex but it has same version as corrupt
3563*33f37583SAndroid Build Coastguard Worker // data apex
TEST_F(ApexdMountTest,OnStartFallbackToCapexSameVersion)3564*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartFallbackToCapexSameVersion) {
3565*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3566*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3567*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3568*33f37583SAndroid Build Coastguard Worker
3569*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v2.capex");
3570*33f37583SAndroid Build Coastguard Worker // Add data apex using the common naming convention for /data/apex/active
3571*33f37583SAndroid Build Coastguard Worker // directory
3572*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v2_manifest_mismatch.apex"),
3573*33f37583SAndroid Build Coastguard Worker GetDataDir() + "/[email protected]");
3574*33f37583SAndroid Build Coastguard Worker
3575*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3576*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3577*33f37583SAndroid Build Coastguard Worker Ok());
3578*33f37583SAndroid Build Coastguard Worker
3579*33f37583SAndroid Build Coastguard Worker OnStart();
3580*33f37583SAndroid Build Coastguard Worker
3581*33f37583SAndroid Build Coastguard Worker // Decompressed APEX should be mounted
3582*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3583*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@2%s", GetDecompressionDir().c_str(),
3584*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3585*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3586*33f37583SAndroid Build Coastguard Worker
3587*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3588*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3589*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3590*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3591*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@2"));
3592*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3593*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex.
3594*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3595*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3596*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3597*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
3598*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3599*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3600*33f37583SAndroid Build Coastguard Worker });
3601*33f37583SAndroid Build Coastguard Worker }
3602*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartCapexToApex)3603*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartCapexToApex) {
3604*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3605*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3606*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3607*33f37583SAndroid Build Coastguard Worker
3608*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
3609*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex",
3610*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
3611*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.apex");
3612*33f37583SAndroid Build Coastguard Worker
3613*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3614*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3615*33f37583SAndroid Build Coastguard Worker Ok());
3616*33f37583SAndroid Build Coastguard Worker
3617*33f37583SAndroid Build Coastguard Worker OnStart();
3618*33f37583SAndroid Build Coastguard Worker
3619*33f37583SAndroid Build Coastguard Worker // Uncompressed APEX should be mounted
3620*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path);
3621*33f37583SAndroid Build Coastguard Worker
3622*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3623*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3624*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3625*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3626*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
3627*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3628*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from decompressed apex.
3629*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3630*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3631*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3632*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path);
3633*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(data.device_name, IsEmpty());
3634*33f37583SAndroid Build Coastguard Worker });
3635*33f37583SAndroid Build Coastguard Worker }
3636*33f37583SAndroid Build Coastguard Worker
3637*33f37583SAndroid Build Coastguard Worker // Test to ensure we do not mount decompressed APEX from /data/apex/active
TEST_F(ApexdMountTest,OnStartOrphanedDecompressedApexInActiveDirectory)3638*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartOrphanedDecompressedApexInActiveDirectory) {
3639*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3640*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3641*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3642*33f37583SAndroid Build Coastguard Worker
3643*33f37583SAndroid Build Coastguard Worker // Place a decompressed APEX in /data/apex/active. This apex should not
3644*33f37583SAndroid Build Coastguard Worker // be mounted since it's not in correct location. Instead, the
3645*33f37583SAndroid Build Coastguard Worker // pre-installed APEX should be mounted.
3646*33f37583SAndroid Build Coastguard Worker auto decompressed_apex_in_active_dir =
3647*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1%s", GetDataDir().c_str(),
3648*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3649*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v1.apex"),
3650*33f37583SAndroid Build Coastguard Worker decompressed_apex_in_active_dir);
3651*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.apex");
3652*33f37583SAndroid Build Coastguard Worker
3653*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3654*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3655*33f37583SAndroid Build Coastguard Worker Ok());
3656*33f37583SAndroid Build Coastguard Worker
3657*33f37583SAndroid Build Coastguard Worker OnStart();
3658*33f37583SAndroid Build Coastguard Worker
3659*33f37583SAndroid Build Coastguard Worker // Pre-installed APEX should be mounted
3660*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path);
3661*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3662*33f37583SAndroid Build Coastguard Worker // Check that pre-installed APEX has been activated
3663*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3664*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3665*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3666*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, apex_path);
3667*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(data.device_name, IsEmpty());
3668*33f37583SAndroid Build Coastguard Worker });
3669*33f37583SAndroid Build Coastguard Worker }
3670*33f37583SAndroid Build Coastguard Worker
3671*33f37583SAndroid Build Coastguard Worker // Test scenario when decompressed version has different version than
3672*33f37583SAndroid Build Coastguard Worker // pre-installed CAPEX
TEST_F(ApexdMountTest,OnStartDecompressedApexVersionDifferentThanCapex)3673*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDecompressedApexVersionDifferentThanCapex) {
3674*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3675*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3676*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3677*33f37583SAndroid Build Coastguard Worker
3678*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
3679*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v2.capex",
3680*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
3681*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3682*33f37583SAndroid Build Coastguard Worker
3683*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3684*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3685*33f37583SAndroid Build Coastguard Worker Ok());
3686*33f37583SAndroid Build Coastguard Worker
3687*33f37583SAndroid Build Coastguard Worker OnStart();
3688*33f37583SAndroid Build Coastguard Worker
3689*33f37583SAndroid Build Coastguard Worker // Existing higher version decompressed APEX should be ignored and new
3690*33f37583SAndroid Build Coastguard Worker // pre-installed CAPEX should be decompressed and mounted
3691*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3692*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3693*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3694*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3695*33f37583SAndroid Build Coastguard Worker
3696*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
3697*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3698*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3699*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.compressed",
3700*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1"));
3701*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3702*33f37583SAndroid Build Coastguard Worker // Check that it was mounted from newly decompressed apex.
3703*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes("com.android.apex.compressed",
3704*33f37583SAndroid Build Coastguard Worker [&](const MountedApexData& data, bool latest) {
3705*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(latest);
3706*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.full_path, decompressed_active_apex);
3707*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(data.device_name,
3708*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed");
3709*33f37583SAndroid Build Coastguard Worker });
3710*33f37583SAndroid Build Coastguard Worker }
3711*33f37583SAndroid Build Coastguard Worker
3712*33f37583SAndroid Build Coastguard Worker // Test that ota_apex is persisted until slot switch
TEST_F(ApexdMountTest,OnStartOtaApexKeptUntilSlotSwitch)3713*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartOtaApexKeptUntilSlotSwitch) {
3714*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3715*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3716*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3717*33f37583SAndroid Build Coastguard Worker
3718*33f37583SAndroid Build Coastguard Worker // Imagine current system has v1 capex and we have v2 incoming via ota
3719*33f37583SAndroid Build Coastguard Worker auto old_capex = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3720*33f37583SAndroid Build Coastguard Worker auto ota_apex_path =
3721*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@2%s",
3722*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
3723*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.compressed.v2_original.apex"),
3724*33f37583SAndroid Build Coastguard Worker ota_apex_path.c_str());
3725*33f37583SAndroid Build Coastguard Worker
3726*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3727*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3728*33f37583SAndroid Build Coastguard Worker Ok());
3729*33f37583SAndroid Build Coastguard Worker
3730*33f37583SAndroid Build Coastguard Worker // When we call OnStart for the first time, it will decompress v1 capex and
3731*33f37583SAndroid Build Coastguard Worker // activate it, while after second call it will decompress v2 capex and
3732*33f37583SAndroid Build Coastguard Worker // activate it. We need to make sure that activated APEXes are cleaned up
3733*33f37583SAndroid Build Coastguard Worker // after test finishes.
3734*33f37583SAndroid Build Coastguard Worker auto old_decompressed_apex = StringPrintf(
3735*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3736*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3737*33f37583SAndroid Build Coastguard Worker auto new_decompressed_apex = StringPrintf(
3738*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@2%s", GetDecompressionDir().c_str(),
3739*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3740*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(old_decompressed_apex);
3741*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(new_decompressed_apex);
3742*33f37583SAndroid Build Coastguard Worker
3743*33f37583SAndroid Build Coastguard Worker // First try starting without slot switch. Since we are booting with
3744*33f37583SAndroid Build Coastguard Worker // old pre-installed capex, ota_apex should not be deleted
3745*33f37583SAndroid Build Coastguard Worker OnStart();
3746*33f37583SAndroid Build Coastguard Worker auto path_exists = PathExists(ota_apex_path);
3747*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(*path_exists);
3748*33f37583SAndroid Build Coastguard Worker
3749*33f37583SAndroid Build Coastguard Worker // When we switch slot, the pre-installed APEX will match ota_apex
3750*33f37583SAndroid Build Coastguard Worker // and the ota_apex will end up getting renamed.
3751*33f37583SAndroid Build Coastguard Worker RemoveFileIfExists(old_capex);
3752*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v2.capex");
3753*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().Reset(GetDecompressionDir());
3754*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3755*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3756*33f37583SAndroid Build Coastguard Worker Ok());
3757*33f37583SAndroid Build Coastguard Worker OnStart();
3758*33f37583SAndroid Build Coastguard Worker path_exists = PathExists(ota_apex_path);
3759*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(*path_exists);
3760*33f37583SAndroid Build Coastguard Worker }
3761*33f37583SAndroid Build Coastguard Worker
3762*33f37583SAndroid Build Coastguard Worker // Test scenario when decompressed version has same version but different
3763*33f37583SAndroid Build Coastguard Worker // digest
TEST_F(ApexdMountTest,OnStartDecompressedApexVersionSameAsCapexDifferentDigest)3764*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
3765*33f37583SAndroid Build Coastguard Worker OnStartDecompressedApexVersionSameAsCapexDifferentDigest) {
3766*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3767*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3768*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3769*33f37583SAndroid Build Coastguard Worker
3770*33f37583SAndroid Build Coastguard Worker // Push a CAPEX to system without decompressing it
3771*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3772*33f37583SAndroid Build Coastguard Worker auto pre_installed_apex = ApexFile::Open(apex_path);
3773*33f37583SAndroid Build Coastguard Worker // Now push an APEX with different root digest as decompressed APEX
3774*33f37583SAndroid Build Coastguard Worker auto decompressed_apex_path = StringPrintf(
3775*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3776*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3777*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(
3778*33f37583SAndroid Build Coastguard Worker "com.android.apex.compressed.v1_different_digest_original.apex"),
3779*33f37583SAndroid Build Coastguard Worker decompressed_apex_path);
3780*33f37583SAndroid Build Coastguard Worker auto different_digest_apex = ApexFile::Open(decompressed_apex_path);
3781*33f37583SAndroid Build Coastguard Worker auto different_digest = GetRootDigest(*different_digest_apex);
3782*33f37583SAndroid Build Coastguard Worker ASSERT_NE(
3783*33f37583SAndroid Build Coastguard Worker pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
3784*33f37583SAndroid Build Coastguard Worker different_digest);
3785*33f37583SAndroid Build Coastguard Worker
3786*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3787*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3788*33f37583SAndroid Build Coastguard Worker Ok());
3789*33f37583SAndroid Build Coastguard Worker
3790*33f37583SAndroid Build Coastguard Worker OnStart();
3791*33f37583SAndroid Build Coastguard Worker
3792*33f37583SAndroid Build Coastguard Worker // Existing same version decompressed APEX with different root digest should
3793*33f37583SAndroid Build Coastguard Worker // be ignored and the pre-installed CAPEX should be decompressed again.
3794*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_apex_path);
3795*33f37583SAndroid Build Coastguard Worker
3796*33f37583SAndroid Build Coastguard Worker // Ensure decompressed apex has same digest as pre-installed
3797*33f37583SAndroid Build Coastguard Worker auto decompressed_apex = ApexFile::Open(decompressed_apex_path);
3798*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(
3799*33f37583SAndroid Build Coastguard Worker pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
3800*33f37583SAndroid Build Coastguard Worker GetRootDigest(*decompressed_apex));
3801*33f37583SAndroid Build Coastguard Worker ASSERT_NE(GetRootDigest(*decompressed_apex), different_digest);
3802*33f37583SAndroid Build Coastguard Worker }
3803*33f37583SAndroid Build Coastguard Worker
3804*33f37583SAndroid Build Coastguard Worker // Test when decompressed APEX has different key than CAPEX
TEST_F(ApexdMountTest,OnStartDecompressedApexVersionSameAsCapexDifferentKey)3805*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDecompressedApexVersionSameAsCapexDifferentKey) {
3806*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
3807*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
3808*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
3809*33f37583SAndroid Build Coastguard Worker
3810*33f37583SAndroid Build Coastguard Worker TemporaryDir previous_built_in_dir;
3811*33f37583SAndroid Build Coastguard Worker auto different_key_apex_path =
3812*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed_different_key.capex",
3813*33f37583SAndroid Build Coastguard Worker previous_built_in_dir.path);
3814*33f37583SAndroid Build Coastguard Worker // Place a same version capex in current built_in_dir, which has different key
3815*33f37583SAndroid Build Coastguard Worker auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
3816*33f37583SAndroid Build Coastguard Worker
3817*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
3818*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
3819*33f37583SAndroid Build Coastguard Worker Ok());
3820*33f37583SAndroid Build Coastguard Worker
3821*33f37583SAndroid Build Coastguard Worker OnStart();
3822*33f37583SAndroid Build Coastguard Worker
3823*33f37583SAndroid Build Coastguard Worker // Existing same version decompressed APEX should be ignored and new
3824*33f37583SAndroid Build Coastguard Worker // pre-installed CAPEX should be decompressed and mounted
3825*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
3826*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
3827*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
3828*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
3829*33f37583SAndroid Build Coastguard Worker
3830*33f37583SAndroid Build Coastguard Worker // Ensure decompressed apex has same digest as pre-installed
3831*33f37583SAndroid Build Coastguard Worker auto pre_installed_apex = ApexFile::Open(apex_path);
3832*33f37583SAndroid Build Coastguard Worker auto decompressed_apex = ApexFile::Open(decompressed_active_apex);
3833*33f37583SAndroid Build Coastguard Worker auto different_key_apex = ApexFile::Open(different_key_apex_path);
3834*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(
3835*33f37583SAndroid Build Coastguard Worker pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
3836*33f37583SAndroid Build Coastguard Worker GetRootDigest(*decompressed_apex));
3837*33f37583SAndroid Build Coastguard Worker ASSERT_NE(
3838*33f37583SAndroid Build Coastguard Worker pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
3839*33f37583SAndroid Build Coastguard Worker GetRootDigest(*different_key_apex));
3840*33f37583SAndroid Build Coastguard Worker }
3841*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,PopulateFromMountsChecksPathPrefix)3842*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, PopulateFromMountsChecksPathPrefix) {
3843*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
3844*33f37583SAndroid Build Coastguard Worker std::string apex_path = AddDataApex("apex.apexd_test_v2.apex");
3845*33f37583SAndroid Build Coastguard Worker
3846*33f37583SAndroid Build Coastguard Worker // Mount an apex from decomrpession_dir
3847*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex");
3848*33f37583SAndroid Build Coastguard Worker std::string decompressed_apex =
3849*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1.decompressed.apex",
3850*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str());
3851*33f37583SAndroid Build Coastguard Worker
3852*33f37583SAndroid Build Coastguard Worker // Mount an apex from some other directory
3853*33f37583SAndroid Build Coastguard Worker TemporaryDir td;
3854*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3855*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apex.apexd_test_different_app.apex"), td.path);
3856*33f37583SAndroid Build Coastguard Worker std::string other_apex =
3857*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/apex.apexd_test_different_app.apex", td.path);
3858*33f37583SAndroid Build Coastguard Worker
3859*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
3860*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
3861*33f37583SAndroid Build Coastguard Worker Ok());
3862*33f37583SAndroid Build Coastguard Worker
3863*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path), Ok());
3864*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(decompressed_apex), Ok());
3865*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(other_apex), Ok());
3866*33f37583SAndroid Build Coastguard Worker
3867*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3868*33f37583SAndroid Build Coastguard Worker // Remember mount information for |other_apex|, since it won't be available in
3869*33f37583SAndroid Build Coastguard Worker // the database. We will need to tear it down manually.
3870*33f37583SAndroid Build Coastguard Worker std::optional<MountedApexData> other_apex_mount_data;
3871*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes(
3872*33f37583SAndroid Build Coastguard Worker "com.android.apex.test_package_2",
3873*33f37583SAndroid Build Coastguard Worker [&other_apex_mount_data](const MountedApexData& data, bool latest) {
3874*33f37583SAndroid Build Coastguard Worker if (latest) {
3875*33f37583SAndroid Build Coastguard Worker other_apex_mount_data.emplace(data);
3876*33f37583SAndroid Build Coastguard Worker }
3877*33f37583SAndroid Build Coastguard Worker });
3878*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path);
3879*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_apex);
3880*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(other_apex_mount_data.has_value());
3881*33f37583SAndroid Build Coastguard Worker auto deleter = make_scope_guard([&other_apex_mount_data]() {
3882*33f37583SAndroid Build Coastguard Worker if (!other_apex_mount_data.has_value()) {
3883*33f37583SAndroid Build Coastguard Worker return;
3884*33f37583SAndroid Build Coastguard Worker }
3885*33f37583SAndroid Build Coastguard Worker if (umount2("/apex/com.android.apex.test_package_2", 0) != 0) {
3886*33f37583SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to unmount /apex/com.android.apex.test_package_2";
3887*33f37583SAndroid Build Coastguard Worker }
3888*33f37583SAndroid Build Coastguard Worker auto res = Unmount(*other_apex_mount_data, /* deferred= */ false);
3889*33f37583SAndroid Build Coastguard Worker if (!res.ok()) {
3890*33f37583SAndroid Build Coastguard Worker LOG(ERROR) << res.error();
3891*33f37583SAndroid Build Coastguard Worker }
3892*33f37583SAndroid Build Coastguard Worker });
3893*33f37583SAndroid Build Coastguard Worker
3894*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3895*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3896*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3897*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
3898*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed",
3899*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1",
3900*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3901*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3902*33f37583SAndroid Build Coastguard Worker
3903*33f37583SAndroid Build Coastguard Worker // Clear the database before calling PopulateFromMounts
3904*33f37583SAndroid Build Coastguard Worker db.Reset();
3905*33f37583SAndroid Build Coastguard Worker
3906*33f37583SAndroid Build Coastguard Worker // Populate from mount
3907*33f37583SAndroid Build Coastguard Worker db.PopulateFromMounts({GetDataDir(), GetDecompressionDir()});
3908*33f37583SAndroid Build Coastguard Worker
3909*33f37583SAndroid Build Coastguard Worker // Count number of package and collect package names
3910*33f37583SAndroid Build Coastguard Worker int package_count = 0;
3911*33f37583SAndroid Build Coastguard Worker std::vector<std::string> mounted_paths;
3912*33f37583SAndroid Build Coastguard Worker db.ForallMountedApexes([&](const std::string& package,
3913*33f37583SAndroid Build Coastguard Worker const MountedApexData& data, bool latest) {
3914*33f37583SAndroid Build Coastguard Worker package_count++;
3915*33f37583SAndroid Build Coastguard Worker mounted_paths.push_back(data.full_path);
3916*33f37583SAndroid Build Coastguard Worker });
3917*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(package_count, 2);
3918*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(mounted_paths,
3919*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(apex_path, decompressed_apex));
3920*33f37583SAndroid Build Coastguard Worker }
3921*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,UnmountAll)3922*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, UnmountAll) {
3923*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
3924*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3925*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
3926*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
3927*33f37583SAndroid Build Coastguard Worker
3928*33f37583SAndroid Build Coastguard Worker // Mount an apex from decomrpession_dir
3929*33f37583SAndroid Build Coastguard Worker PrepareCompressedApex("com.android.apex.compressed.v1.capex");
3930*33f37583SAndroid Build Coastguard Worker std::string decompressed_apex =
3931*33f37583SAndroid Build Coastguard Worker StringPrintf("%s/com.android.apex.compressed@1.decompressed.apex",
3932*33f37583SAndroid Build Coastguard Worker GetDecompressionDir().c_str());
3933*33f37583SAndroid Build Coastguard Worker
3934*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
3935*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
3936*33f37583SAndroid Build Coastguard Worker Ok());
3937*33f37583SAndroid Build Coastguard Worker
3938*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_2), Ok());
3939*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_3), Ok());
3940*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(decompressed_apex), Ok());
3941*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3942*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
3943*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_apex);
3944*33f37583SAndroid Build Coastguard Worker
3945*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3946*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3947*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
3948*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
3949*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed",
3950*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.compressed@1",
3951*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
3952*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
3953*33f37583SAndroid Build Coastguard Worker
3954*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3955*33f37583SAndroid Build Coastguard Worker // UnmountAll expects apex database to empty, hence this reset.
3956*33f37583SAndroid Build Coastguard Worker db.Reset();
3957*33f37583SAndroid Build Coastguard Worker
3958*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, UnmountAll(/*also_include_staged_apexes=*/false));
3959*33f37583SAndroid Build Coastguard Worker
3960*33f37583SAndroid Build Coastguard Worker auto new_apex_mounts = GetApexMounts();
3961*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(new_apex_mounts.size(), 0u);
3962*33f37583SAndroid Build Coastguard Worker }
3963*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,UnmountAllSharedLibsApex)3964*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, UnmountAllSharedLibsApex) {
3965*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir("/apex/sharedlibs", 0755), 0);
3966*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir("/apex/sharedlibs/lib", 0755), 0);
3967*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(mkdir("/apex/sharedlibs/lib64", 0755), 0);
3968*33f37583SAndroid Build Coastguard Worker auto deleter = make_scope_guard([]() {
3969*33f37583SAndroid Build Coastguard Worker std::error_code ec;
3970*33f37583SAndroid Build Coastguard Worker fs::remove_all("/apex/sharedlibs", ec);
3971*33f37583SAndroid Build Coastguard Worker if (ec) {
3972*33f37583SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to delete /apex/sharedlibs : " << ec;
3973*33f37583SAndroid Build Coastguard Worker }
3974*33f37583SAndroid Build Coastguard Worker });
3975*33f37583SAndroid Build Coastguard Worker
3976*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex(
3977*33f37583SAndroid Build Coastguard Worker "com.android.apex.test.sharedlibs_generated.v1.libvX.apex");
3978*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
3979*33f37583SAndroid Build Coastguard Worker AddDataApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex");
3980*33f37583SAndroid Build Coastguard Worker
3981*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
3982*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
3983*33f37583SAndroid Build Coastguard Worker Ok());
3984*33f37583SAndroid Build Coastguard Worker
3985*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_1), Ok());
3986*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_2), Ok());
3987*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
3988*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
3989*33f37583SAndroid Build Coastguard Worker
3990*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
3991*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
3992*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test.sharedlibs@1",
3993*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2"));
3994*33f37583SAndroid Build Coastguard Worker
3995*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
3996*33f37583SAndroid Build Coastguard Worker // UnmountAll expects apex database to empty, hence this reset.
3997*33f37583SAndroid Build Coastguard Worker db.Reset();
3998*33f37583SAndroid Build Coastguard Worker
3999*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, UnmountAll(/*also_include_staged_apexes=*/false));
4000*33f37583SAndroid Build Coastguard Worker
4001*33f37583SAndroid Build Coastguard Worker auto new_apex_mounts = GetApexMounts();
4002*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(new_apex_mounts.size(), 0u);
4003*33f37583SAndroid Build Coastguard Worker }
4004*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,UnmountAllDeferred)4005*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, UnmountAllDeferred) {
4006*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4007*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
4008*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
4009*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
4010*33f37583SAndroid Build Coastguard Worker
4011*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4012*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4013*33f37583SAndroid Build Coastguard Worker Ok());
4014*33f37583SAndroid Build Coastguard Worker
4015*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_2), Ok());
4016*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_3), Ok());
4017*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
4018*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
4019*33f37583SAndroid Build Coastguard Worker
4020*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(GetApexMounts(),
4021*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
4022*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
4023*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
4024*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
4025*33f37583SAndroid Build Coastguard Worker
4026*33f37583SAndroid Build Coastguard Worker const std::string kDeviceName = "com.android.apex.test_package@2";
4027*33f37583SAndroid Build Coastguard Worker Result<std::vector<std::string>> loop_devices =
4028*33f37583SAndroid Build Coastguard Worker ListChildLoopDevices(kDeviceName);
4029*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(loop_devices, HasValue(Not(IsEmpty())));
4030*33f37583SAndroid Build Coastguard Worker
4031*33f37583SAndroid Build Coastguard Worker // Open a file. This should make unmounting in `UnmountAll` deferred.
4032*33f37583SAndroid Build Coastguard Worker unique_fd fd(
4033*33f37583SAndroid Build Coastguard Worker open("/apex/com.android.apex.test_package/etc/sample_prebuilt_file",
4034*33f37583SAndroid Build Coastguard Worker O_RDONLY));
4035*33f37583SAndroid Build Coastguard Worker ASSERT_GE(fd, 0) << strerror(errno);
4036*33f37583SAndroid Build Coastguard Worker
4037*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
4038*33f37583SAndroid Build Coastguard Worker // UnmountAll expects apex database to empty, hence this reset.
4039*33f37583SAndroid Build Coastguard Worker db.Reset();
4040*33f37583SAndroid Build Coastguard Worker // UnmountAll should succeed despite the open file.
4041*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(UnmountAll(/*also_include_staged_apexes=*/false), 0);
4042*33f37583SAndroid Build Coastguard Worker
4043*33f37583SAndroid Build Coastguard Worker // The mount should still be there, but it should be detached from the
4044*33f37583SAndroid Build Coastguard Worker // filesystem, so the mount point should be gone.
4045*33f37583SAndroid Build Coastguard Worker EXPECT_THAT(GetApexMounts(), IsEmpty());
4046*33f37583SAndroid Build Coastguard Worker // The DM device and the loop device should still be there.
4047*33f37583SAndroid Build Coastguard Worker auto& dm = DeviceMapper::Instance();
4048*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(dm.GetState(kDeviceName), dm::DmDeviceState::ACTIVE);
4049*33f37583SAndroid Build Coastguard Worker for (const std::string& loop_device : *loop_devices) {
4050*33f37583SAndroid Build Coastguard Worker EXPECT_THAT(GetLoopDeviceStatus(loop_device), Ok());
4051*33f37583SAndroid Build Coastguard Worker }
4052*33f37583SAndroid Build Coastguard Worker
4053*33f37583SAndroid Build Coastguard Worker // Close the file. Unmounting should be automatically performed after then.
4054*33f37583SAndroid Build Coastguard Worker fd.reset();
4055*33f37583SAndroid Build Coastguard Worker // Wait for the kernel to clean things up.
4056*33f37583SAndroid Build Coastguard Worker std::this_thread::sleep_for(std::chrono::milliseconds(300));
4057*33f37583SAndroid Build Coastguard Worker
4058*33f37583SAndroid Build Coastguard Worker // The DM device and the loop device should be gone.
4059*33f37583SAndroid Build Coastguard Worker EXPECT_EQ(dm.GetState(kDeviceName), dm::DmDeviceState::INVALID);
4060*33f37583SAndroid Build Coastguard Worker for (const std::string& loop_device : *loop_devices) {
4061*33f37583SAndroid Build Coastguard Worker EXPECT_THAT(GetLoopDeviceStatus(loop_device), HasError(WithCode(ENXIO)));
4062*33f37583SAndroid Build Coastguard Worker }
4063*33f37583SAndroid Build Coastguard Worker }
4064*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,UnmountAllStaged)4065*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, UnmountAllStaged) {
4066*33f37583SAndroid Build Coastguard Worker // Both a pre-installed apex and a staged apex are mounted. UnmountAll should
4067*33f37583SAndroid Build Coastguard Worker // unmount both.
4068*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4069*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
4070*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
4071*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_v2.apex");
4072*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test_v2.apex", 123);
4073*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4074*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 =
4075*33f37583SAndroid Build Coastguard Worker GetStagedDir(apex_session->GetId()) + "/" + "apex.apexd_test_v2.apex";
4076*33f37583SAndroid Build Coastguard Worker
4077*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4078*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4079*33f37583SAndroid Build Coastguard Worker Ok());
4080*33f37583SAndroid Build Coastguard Worker
4081*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_2), Ok());
4082*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(apex_path_3), Ok());
4083*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
4084*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
4085*33f37583SAndroid Build Coastguard Worker
4086*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
4087*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
4088*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
4089*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@2",
4090*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
4091*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1"));
4092*33f37583SAndroid Build Coastguard Worker
4093*33f37583SAndroid Build Coastguard Worker auto& db = GetApexDatabaseForTesting();
4094*33f37583SAndroid Build Coastguard Worker // UnmountAll expects apex database to empty, hence this reset.
4095*33f37583SAndroid Build Coastguard Worker db.Reset();
4096*33f37583SAndroid Build Coastguard Worker
4097*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, UnmountAll(/*also_include_staged_apexes=*/true));
4098*33f37583SAndroid Build Coastguard Worker apex_mounts = GetApexMounts();
4099*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts, IsEmpty());
4100*33f37583SAndroid Build Coastguard Worker }
4101*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmModeActivatesPreInstalled)4102*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmModeActivatesPreInstalled) {
4103*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4104*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4105*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4106*33f37583SAndroid Build Coastguard Worker
4107*33f37583SAndroid Build Coastguard Worker auto path1 = AddPreInstalledApex("apex.apexd_test.apex");
4108*33f37583SAndroid Build Coastguard Worker auto path2 = AddPreInstalledApex("apex.apexd_test_different_app.apex");
4109*33f37583SAndroid Build Coastguard Worker // In VM mode, we don't scan /data/apex
4110*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_v2.apex");
4111*33f37583SAndroid Build Coastguard Worker
4112*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, OnStartInVmMode());
4113*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path1);
4114*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path2);
4115*33f37583SAndroid Build Coastguard Worker
4116*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
4117*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
4118*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
4119*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
4120*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2",
4121*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package_2@1",
4122*33f37583SAndroid Build Coastguard Worker // Emits apex-info-list as well
4123*33f37583SAndroid Build Coastguard Worker "/apex/apex-info-list.xml"));
4124*33f37583SAndroid Build Coastguard Worker
4125*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "ready");
4126*33f37583SAndroid Build Coastguard Worker }
4127*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmModeFailsWithCapex)4128*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmModeFailsWithCapex) {
4129*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4130*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4131*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4132*33f37583SAndroid Build Coastguard Worker
4133*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v2.capex");
4134*33f37583SAndroid Build Coastguard Worker
4135*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1, OnStartInVmMode());
4136*33f37583SAndroid Build Coastguard Worker }
4137*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmModeActivatesBlockDevicesAsWell)4138*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmModeActivatesBlockDevicesAsWell) {
4139*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4140*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4141*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4142*33f37583SAndroid Build Coastguard Worker
4143*33f37583SAndroid Build Coastguard Worker // Set system property to enable block apexes
4144*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4145*33f37583SAndroid Build Coastguard Worker
4146*33f37583SAndroid Build Coastguard Worker auto path1 = AddBlockApex("apex.apexd_test.apex");
4147*33f37583SAndroid Build Coastguard Worker
4148*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, OnStartInVmMode());
4149*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path1);
4150*33f37583SAndroid Build Coastguard Worker
4151*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
4152*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
4153*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test_package",
4154*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test_package@1",
4155*33f37583SAndroid Build Coastguard Worker // Emits apex-info-list as well
4156*33f37583SAndroid Build Coastguard Worker "/apex/apex-info-list.xml"));
4157*33f37583SAndroid Build Coastguard Worker
4158*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
4159*33f37583SAndroid Build Coastguard Worker auto info_list =
4160*33f37583SAndroid Build Coastguard Worker com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
4161*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(info_list.has_value());
4162*33f37583SAndroid Build Coastguard Worker auto apex_info_xml_1 = com::android::apex::ApexInfo(
4163*33f37583SAndroid Build Coastguard Worker /* moduleName= */ "com.android.apex.test_package",
4164*33f37583SAndroid Build Coastguard Worker /* modulePath= */ path1,
4165*33f37583SAndroid Build Coastguard Worker /* preinstalledModulePath= */ path1,
4166*33f37583SAndroid Build Coastguard Worker /* versionCode= */ 1, /* versionName= */ "1",
4167*33f37583SAndroid Build Coastguard Worker /* isFactory= */ true, /* isActive= */ true, GetMTime(path1),
4168*33f37583SAndroid Build Coastguard Worker /* provideSharedApexLibs= */ false,
4169*33f37583SAndroid Build Coastguard Worker /* partition= */ GetBlockPartitionString());
4170*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(info_list->getApexInfo(),
4171*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1)));
4172*33f37583SAndroid Build Coastguard Worker }
4173*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmModeFailsWithDuplicateNames)4174*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmModeFailsWithDuplicateNames) {
4175*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4176*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4177*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4178*33f37583SAndroid Build Coastguard Worker
4179*33f37583SAndroid Build Coastguard Worker // Set system property to enable block apexes
4180*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4181*33f37583SAndroid Build Coastguard Worker
4182*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4183*33f37583SAndroid Build Coastguard Worker AddBlockApex("apex.apexd_test_v2.apex");
4184*33f37583SAndroid Build Coastguard Worker
4185*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1, OnStartInVmMode());
4186*33f37583SAndroid Build Coastguard Worker }
4187*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmSupportsMultipleSharedLibsApexes)4188*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmSupportsMultipleSharedLibsApexes) {
4189*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4190*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4191*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4192*33f37583SAndroid Build Coastguard Worker
4193*33f37583SAndroid Build Coastguard Worker auto path1 =
4194*33f37583SAndroid Build Coastguard Worker AddBlockApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex",
4195*33f37583SAndroid Build Coastguard Worker /*public_key=*/"", /*root_digest=*/"", /*is_factory=*/true);
4196*33f37583SAndroid Build Coastguard Worker auto path2 =
4197*33f37583SAndroid Build Coastguard Worker AddBlockApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex",
4198*33f37583SAndroid Build Coastguard Worker /*public_key=*/"", /*root_digest=*/"", /*is_factory=*/false);
4199*33f37583SAndroid Build Coastguard Worker
4200*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, OnStartInVmMode());
4201*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path1);
4202*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path2);
4203*33f37583SAndroid Build Coastguard Worker
4204*33f37583SAndroid Build Coastguard Worker // Btw, in case duplicates are sharedlibs apexes, both should be activated
4205*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
4206*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_mounts,
4207*33f37583SAndroid Build Coastguard Worker UnorderedElementsAre("/apex/com.android.apex.test.sharedlibs@1",
4208*33f37583SAndroid Build Coastguard Worker "/apex/com.android.apex.test.sharedlibs@2",
4209*33f37583SAndroid Build Coastguard Worker // Emits apex-info-list as well
4210*33f37583SAndroid Build Coastguard Worker "/apex/apex-info-list.xml"));
4211*33f37583SAndroid Build Coastguard Worker }
4212*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmShouldRejectInDuplicateFactoryApexes)4213*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmShouldRejectInDuplicateFactoryApexes) {
4214*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4215*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4216*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4217*33f37583SAndroid Build Coastguard Worker
4218*33f37583SAndroid Build Coastguard Worker auto path1 =
4219*33f37583SAndroid Build Coastguard Worker AddBlockApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex",
4220*33f37583SAndroid Build Coastguard Worker /*public_key=*/"", /*root_digest=*/"", /*is_factory=*/true);
4221*33f37583SAndroid Build Coastguard Worker auto path2 =
4222*33f37583SAndroid Build Coastguard Worker AddBlockApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex",
4223*33f37583SAndroid Build Coastguard Worker /*public_key=*/"", /*root_digest=*/"", /*is_factory=*/true);
4224*33f37583SAndroid Build Coastguard Worker
4225*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1, OnStartInVmMode());
4226*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path1);
4227*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path2);
4228*33f37583SAndroid Build Coastguard Worker }
4229*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmShouldRejectInDuplicateNonFactoryApexes)4230*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmShouldRejectInDuplicateNonFactoryApexes) {
4231*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4232*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4233*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4234*33f37583SAndroid Build Coastguard Worker
4235*33f37583SAndroid Build Coastguard Worker auto path1 =
4236*33f37583SAndroid Build Coastguard Worker AddBlockApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex",
4237*33f37583SAndroid Build Coastguard Worker /*public_key=*/"", /*root_digest=*/"", /*is_factory=*/false);
4238*33f37583SAndroid Build Coastguard Worker auto path2 =
4239*33f37583SAndroid Build Coastguard Worker AddBlockApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex",
4240*33f37583SAndroid Build Coastguard Worker /*public_key=*/"", /*root_digest=*/"", /*is_factory=*/false);
4241*33f37583SAndroid Build Coastguard Worker
4242*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1, OnStartInVmMode());
4243*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path1);
4244*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path2);
4245*33f37583SAndroid Build Coastguard Worker }
4246*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmModeFailsWithWrongPubkey)4247*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmModeFailsWithWrongPubkey) {
4248*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4249*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4250*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4251*33f37583SAndroid Build Coastguard Worker
4252*33f37583SAndroid Build Coastguard Worker // Set system property to enable block apexes
4253*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4254*33f37583SAndroid Build Coastguard Worker
4255*33f37583SAndroid Build Coastguard Worker AddBlockApex("apex.apexd_test.apex", /*public_key=*/"wrong pubkey");
4256*33f37583SAndroid Build Coastguard Worker
4257*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1, OnStartInVmMode());
4258*33f37583SAndroid Build Coastguard Worker }
4259*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,GetActivePackagesReturningBlockApexesAsWell)4260*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, GetActivePackagesReturningBlockApexesAsWell) {
4261*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4262*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4263*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4264*33f37583SAndroid Build Coastguard Worker
4265*33f37583SAndroid Build Coastguard Worker // Set system property to enable block apexes
4266*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4267*33f37583SAndroid Build Coastguard Worker
4268*33f37583SAndroid Build Coastguard Worker auto path1 = AddBlockApex("apex.apexd_test.apex");
4269*33f37583SAndroid Build Coastguard Worker
4270*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, OnStartInVmMode());
4271*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(path1);
4272*33f37583SAndroid Build Coastguard Worker
4273*33f37583SAndroid Build Coastguard Worker auto active_apexes = GetActivePackages();
4274*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1u, active_apexes.size());
4275*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(path1, active_apexes[0].GetPath());
4276*33f37583SAndroid Build Coastguard Worker }
4277*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartInVmModeFailsWithWrongRootDigest)4278*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartInVmModeFailsWithWrongRootDigest) {
4279*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4280*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4281*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4282*33f37583SAndroid Build Coastguard Worker
4283*33f37583SAndroid Build Coastguard Worker // Set system property to enable block apexes
4284*33f37583SAndroid Build Coastguard Worker SetBlockApexEnabled(true);
4285*33f37583SAndroid Build Coastguard Worker
4286*33f37583SAndroid Build Coastguard Worker AddBlockApex("apex.apexd_test.apex", /*public_key=*/"",
4287*33f37583SAndroid Build Coastguard Worker /*root_digest=*/"wrong root digest");
4288*33f37583SAndroid Build Coastguard Worker
4289*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1, OnStartInVmMode());
4290*33f37583SAndroid Build Coastguard Worker }
4291*33f37583SAndroid Build Coastguard Worker
4292*33f37583SAndroid Build Coastguard Worker class ApexActivationFailureTests : public ApexdMountTest {};
4293*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,BuildFingerprintDifferent)4294*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, BuildFingerprintDifferent) {
4295*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4296*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4297*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4298*33f37583SAndroid Build Coastguard Worker
4299*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
4300*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4301*33f37583SAndroid Build Coastguard Worker apex_session->SetBuildFingerprint("wrong fingerprint");
4302*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session->UpdateStateAndCommit(SessionState::STAGED));
4303*33f37583SAndroid Build Coastguard Worker
4304*33f37583SAndroid Build Coastguard Worker OnStart();
4305*33f37583SAndroid Build Coastguard Worker
4306*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4307*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4308*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4309*33f37583SAndroid Build Coastguard Worker HasSubstr("APEX build fingerprint has changed"));
4310*33f37583SAndroid Build Coastguard Worker }
4311*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,ApexFileMissingInStagingDirectory)4312*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, ApexFileMissingInStagingDirectory) {
4313*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4314*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4315*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4316*33f37583SAndroid Build Coastguard Worker
4317*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
4318*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4319*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4320*33f37583SAndroid Build Coastguard Worker // Delete the apex file in staging directory
4321*33f37583SAndroid Build Coastguard Worker DeleteDirContent(GetStagedDir(123));
4322*33f37583SAndroid Build Coastguard Worker
4323*33f37583SAndroid Build Coastguard Worker OnStart();
4324*33f37583SAndroid Build Coastguard Worker
4325*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4326*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4327*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4328*33f37583SAndroid Build Coastguard Worker HasSubstr("No APEX packages found"));
4329*33f37583SAndroid Build Coastguard Worker }
4330*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,MultipleApexFileInStagingDirectory)4331*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, MultipleApexFileInStagingDirectory) {
4332*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4333*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4334*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4335*33f37583SAndroid Build Coastguard Worker
4336*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
4337*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4338*33f37583SAndroid Build Coastguard Worker CreateStagedSession("com.android.apex.compressed.v1.apex", 123);
4339*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4340*33f37583SAndroid Build Coastguard Worker
4341*33f37583SAndroid Build Coastguard Worker OnStart();
4342*33f37583SAndroid Build Coastguard Worker
4343*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4344*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4345*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4346*33f37583SAndroid Build Coastguard Worker HasSubstr("More than one APEX package found"));
4347*33f37583SAndroid Build Coastguard Worker }
4348*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,CorruptedSuperblockApexCannotBeStaged)4349*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, CorruptedSuperblockApexCannotBeStaged) {
4350*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4351*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4352*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4353*33f37583SAndroid Build Coastguard Worker
4354*33f37583SAndroid Build Coastguard Worker auto apex_session =
4355*33f37583SAndroid Build Coastguard Worker CreateStagedSession("apex.apexd_test_corrupt_superblock_apex.apex", 123);
4356*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4357*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4358*33f37583SAndroid Build Coastguard Worker
4359*33f37583SAndroid Build Coastguard Worker OnStart();
4360*33f37583SAndroid Build Coastguard Worker
4361*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4362*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4363*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4364*33f37583SAndroid Build Coastguard Worker HasSubstr("Couldn't find filesystem magic"));
4365*33f37583SAndroid Build Coastguard Worker }
4366*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,CorruptedApexCannotBeStaged)4367*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, CorruptedApexCannotBeStaged) {
4368*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4369*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4370*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4371*33f37583SAndroid Build Coastguard Worker
4372*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("corrupted_b146895998.apex", 123);
4373*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4374*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4375*33f37583SAndroid Build Coastguard Worker
4376*33f37583SAndroid Build Coastguard Worker OnStart();
4377*33f37583SAndroid Build Coastguard Worker
4378*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4379*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4380*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4381*33f37583SAndroid Build Coastguard Worker HasSubstr("Activation failed for packages"));
4382*33f37583SAndroid Build Coastguard Worker }
4383*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,ActivatePackageImplFails)4384*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, ActivatePackageImplFails) {
4385*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4386*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4387*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4388*33f37583SAndroid Build Coastguard Worker
4389*33f37583SAndroid Build Coastguard Worker auto shim_path = AddPreInstalledApex("com.android.apex.cts.shim.apex");
4390*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4391*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(
4392*33f37583SAndroid Build Coastguard Worker instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}));
4393*33f37583SAndroid Build Coastguard Worker
4394*33f37583SAndroid Build Coastguard Worker auto apex_session =
4395*33f37583SAndroid Build Coastguard Worker CreateStagedSession("com.android.apex.cts.shim.v2_wrong_sha.apex", 123);
4396*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4397*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4398*33f37583SAndroid Build Coastguard Worker
4399*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(shim_path);
4400*33f37583SAndroid Build Coastguard Worker OnStart();
4401*33f37583SAndroid Build Coastguard Worker
4402*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4403*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4404*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4405*33f37583SAndroid Build Coastguard Worker HasSubstr("Failed to activate packages"));
4406*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->GetErrorMessage(),
4407*33f37583SAndroid Build Coastguard Worker HasSubstr("has unexpected SHA512 hash"));
4408*33f37583SAndroid Build Coastguard Worker }
4409*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,StagedSessionFailsWhenNotInFsCheckpointMode)4410*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests,
4411*33f37583SAndroid Build Coastguard Worker StagedSessionFailsWhenNotInFsCheckpointMode) {
4412*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4413*33f37583SAndroid Build Coastguard Worker checkpoint_interface.SetSupportsCheckpoint(true);
4414*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4415*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4416*33f37583SAndroid Build Coastguard Worker
4417*33f37583SAndroid Build Coastguard Worker auto pre_installed_apex = AddPreInstalledApex("apex.apexd_test.apex");
4418*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4419*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(
4420*33f37583SAndroid Build Coastguard Worker instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}));
4421*33f37583SAndroid Build Coastguard Worker
4422*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
4423*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4424*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4425*33f37583SAndroid Build Coastguard Worker
4426*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(pre_installed_apex);
4427*33f37583SAndroid Build Coastguard Worker OnStart();
4428*33f37583SAndroid Build Coastguard Worker
4429*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4430*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4431*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(apex_session->GetState(), SessionState::ACTIVATION_FAILED);
4432*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
4433*33f37583SAndroid Build Coastguard Worker apex_session->GetErrorMessage(),
4434*33f37583SAndroid Build Coastguard Worker HasSubstr("Cannot install apex session if not in fs-checkpoint mode"));
4435*33f37583SAndroid Build Coastguard Worker }
4436*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexActivationFailureTests,StagedSessionRevertsWhenInFsRollbackMode)4437*33f37583SAndroid Build Coastguard Worker TEST_F(ApexActivationFailureTests, StagedSessionRevertsWhenInFsRollbackMode) {
4438*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4439*33f37583SAndroid Build Coastguard Worker checkpoint_interface.SetSupportsCheckpoint(true);
4440*33f37583SAndroid Build Coastguard Worker checkpoint_interface.SetNeedsRollback(true);
4441*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4442*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4443*33f37583SAndroid Build Coastguard Worker
4444*33f37583SAndroid Build Coastguard Worker auto pre_installed_apex = AddPreInstalledApex("apex.apexd_test.apex");
4445*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4446*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(
4447*33f37583SAndroid Build Coastguard Worker instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}));
4448*33f37583SAndroid Build Coastguard Worker
4449*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
4450*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4451*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4452*33f37583SAndroid Build Coastguard Worker
4453*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(pre_installed_apex);
4454*33f37583SAndroid Build Coastguard Worker OnStart();
4455*33f37583SAndroid Build Coastguard Worker
4456*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(123);
4457*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(apex_session);
4458*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(apex_session->GetState(), SessionState::REVERTED);
4459*33f37583SAndroid Build Coastguard Worker }
4460*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnBootstrapCreatesEmptyDmDevices)4461*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnBootstrapCreatesEmptyDmDevices) {
4462*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4463*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
4464*33f37583SAndroid Build Coastguard Worker
4465*33f37583SAndroid Build Coastguard Worker DeviceMapper& dm = DeviceMapper::Instance();
4466*33f37583SAndroid Build Coastguard Worker
4467*33f37583SAndroid Build Coastguard Worker auto cleaner = make_scope_guard([&]() {
4468*33f37583SAndroid Build Coastguard Worker dm.DeleteDeviceIfExists("com.android.apex.test_package", 1s);
4469*33f37583SAndroid Build Coastguard Worker dm.DeleteDeviceIfExists("com.android.apex.compressed", 1s);
4470*33f37583SAndroid Build Coastguard Worker });
4471*33f37583SAndroid Build Coastguard Worker
4472*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, OnBootstrap());
4473*33f37583SAndroid Build Coastguard Worker
4474*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(dm::DmDeviceState::SUSPENDED,
4475*33f37583SAndroid Build Coastguard Worker dm.GetState("com.android.apex.test_package"));
4476*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(dm::DmDeviceState::SUSPENDED,
4477*33f37583SAndroid Build Coastguard Worker dm.GetState("com.android.apex.compressed"));
4478*33f37583SAndroid Build Coastguard Worker }
4479*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnBootstrapLoadBootstrapApexOnly)4480*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnBootstrapLoadBootstrapApexOnly) {
4481*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4482*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_bootstrap_test.apex");
4483*33f37583SAndroid Build Coastguard Worker
4484*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, OnBootstrap());
4485*33f37583SAndroid Build Coastguard Worker
4486*33f37583SAndroid Build Coastguard Worker // Check bootstrap apex was loaded
4487*33f37583SAndroid Build Coastguard Worker auto active_bootstrap_apex =
4488*33f37583SAndroid Build Coastguard Worker GetActivePackage("com.android.apex.bootstrap_test_package");
4489*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(active_bootstrap_apex, Ok());
4490*33f37583SAndroid Build Coastguard Worker // Check that non-bootstrap apex was not loaded
4491*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(GetActivePackage("com.android.apex.test_package"), Not(Ok()));
4492*33f37583SAndroid Build Coastguard Worker }
4493*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesFailKey)4494*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesFailKey) {
4495*33f37583SAndroid Build Coastguard Worker auto status =
4496*33f37583SAndroid Build Coastguard Worker StagePackages({GetTestFile("apex.apexd_test_no_inst_key.apex")});
4497*33f37583SAndroid Build Coastguard Worker
4498*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
4499*33f37583SAndroid Build Coastguard Worker status,
4500*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(("No preinstalled apex found for unverified package "
4501*33f37583SAndroid Build Coastguard Worker "com.android.apex.test_package.no_inst_key"))));
4502*33f37583SAndroid Build Coastguard Worker }
4503*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesSuccess)4504*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesSuccess) {
4505*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4506*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4507*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4508*33f37583SAndroid Build Coastguard Worker Ok());
4509*33f37583SAndroid Build Coastguard Worker
4510*33f37583SAndroid Build Coastguard Worker auto status = StagePackages({GetTestFile("apex.apexd_test.apex")});
4511*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status, Ok());
4512*33f37583SAndroid Build Coastguard Worker
4513*33f37583SAndroid Build Coastguard Worker auto staged_path = StringPrintf("%s/com.android.apex.test_package@1.apex",
4514*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
4515*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
4516*33f37583SAndroid Build Coastguard Worker }
4517*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesClearsPreviouslyActivePackage)4518*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesClearsPreviouslyActivePackage) {
4519*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4520*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4521*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4522*33f37583SAndroid Build Coastguard Worker Ok());
4523*33f37583SAndroid Build Coastguard Worker
4524*33f37583SAndroid Build Coastguard Worker auto current_apex = AddDataApex("apex.apexd_test.apex");
4525*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(current_apex.c_str(), F_OK));
4526*33f37583SAndroid Build Coastguard Worker
4527*33f37583SAndroid Build Coastguard Worker auto status = StagePackages({GetTestFile("apex.apexd_test_v2.apex")});
4528*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status, Ok());
4529*33f37583SAndroid Build Coastguard Worker
4530*33f37583SAndroid Build Coastguard Worker auto staged_path = StringPrintf("%s/com.android.apex.test_package@2.apex",
4531*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
4532*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
4533*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(-1, access(current_apex.c_str(), F_OK));
4534*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(ENOENT, errno);
4535*33f37583SAndroid Build Coastguard Worker }
4536*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesClearsPreviouslyActivePackageDowngrade)4537*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesClearsPreviouslyActivePackageDowngrade) {
4538*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4539*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4540*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4541*33f37583SAndroid Build Coastguard Worker Ok());
4542*33f37583SAndroid Build Coastguard Worker
4543*33f37583SAndroid Build Coastguard Worker auto current_apex = AddDataApex("apex.apexd_test_v2.apex");
4544*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(current_apex.c_str(), F_OK));
4545*33f37583SAndroid Build Coastguard Worker
4546*33f37583SAndroid Build Coastguard Worker auto status = StagePackages({GetTestFile("apex.apexd_test.apex")});
4547*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status, Ok());
4548*33f37583SAndroid Build Coastguard Worker
4549*33f37583SAndroid Build Coastguard Worker auto staged_path = StringPrintf("%s/com.android.apex.test_package@1.apex",
4550*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
4551*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
4552*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(-1, access(current_apex.c_str(), F_OK));
4553*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(ENOENT, errno);
4554*33f37583SAndroid Build Coastguard Worker }
4555*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesAlreadyStagedPackage)4556*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesAlreadyStagedPackage) {
4557*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4558*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4559*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4560*33f37583SAndroid Build Coastguard Worker Ok());
4561*33f37583SAndroid Build Coastguard Worker
4562*33f37583SAndroid Build Coastguard Worker auto status = StagePackages({GetTestFile("apex.apexd_test.apex")});
4563*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status, Ok());
4564*33f37583SAndroid Build Coastguard Worker
4565*33f37583SAndroid Build Coastguard Worker auto staged_path = StringPrintf("%s/com.android.apex.test_package@1.apex",
4566*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
4567*33f37583SAndroid Build Coastguard Worker struct stat stat1;
4568*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, stat(staged_path.c_str(), &stat1));
4569*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(S_ISREG(stat1.st_mode));
4570*33f37583SAndroid Build Coastguard Worker
4571*33f37583SAndroid Build Coastguard Worker {
4572*33f37583SAndroid Build Coastguard Worker auto apex = ApexFile::Open(staged_path);
4573*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex, Ok());
4574*33f37583SAndroid Build Coastguard Worker ASSERT_FALSE(apex->GetManifest().nocode());
4575*33f37583SAndroid Build Coastguard Worker }
4576*33f37583SAndroid Build Coastguard Worker
4577*33f37583SAndroid Build Coastguard Worker auto status2 = StagePackages({GetTestFile("apex.apexd_test_nocode.apex")});
4578*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status2, Ok());
4579*33f37583SAndroid Build Coastguard Worker
4580*33f37583SAndroid Build Coastguard Worker struct stat stat2;
4581*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, stat(staged_path.c_str(), &stat2));
4582*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(S_ISREG(stat2.st_mode));
4583*33f37583SAndroid Build Coastguard Worker
4584*33f37583SAndroid Build Coastguard Worker ASSERT_NE(stat1.st_ino, stat2.st_ino);
4585*33f37583SAndroid Build Coastguard Worker
4586*33f37583SAndroid Build Coastguard Worker {
4587*33f37583SAndroid Build Coastguard Worker auto apex = ApexFile::Open(staged_path);
4588*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex, Ok());
4589*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(apex->GetManifest().nocode());
4590*33f37583SAndroid Build Coastguard Worker }
4591*33f37583SAndroid Build Coastguard Worker }
4592*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesMultiplePackages)4593*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesMultiplePackages) {
4594*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test.apex");
4595*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
4596*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4597*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4598*33f37583SAndroid Build Coastguard Worker Ok());
4599*33f37583SAndroid Build Coastguard Worker
4600*33f37583SAndroid Build Coastguard Worker auto status =
4601*33f37583SAndroid Build Coastguard Worker StagePackages({GetTestFile("apex.apexd_test_v2.apex"),
4602*33f37583SAndroid Build Coastguard Worker GetTestFile("apex.apexd_test_different_app.apex")});
4603*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status, Ok());
4604*33f37583SAndroid Build Coastguard Worker
4605*33f37583SAndroid Build Coastguard Worker auto staged_path1 = StringPrintf("%s/com.android.apex.test_package@2.apex",
4606*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
4607*33f37583SAndroid Build Coastguard Worker auto staged_path2 = StringPrintf("%s/com.android.apex.test_package_2@1.apex",
4608*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
4609*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(staged_path1.c_str(), F_OK));
4610*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(staged_path2.c_str(), F_OK));
4611*33f37583SAndroid Build Coastguard Worker }
4612*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,UnstagePackages)4613*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, UnstagePackages) {
4614*33f37583SAndroid Build Coastguard Worker auto file_path1 = AddDataApex("apex.apexd_test.apex");
4615*33f37583SAndroid Build Coastguard Worker auto file_path2 = AddDataApex("apex.apexd_test_different_app.apex");
4616*33f37583SAndroid Build Coastguard Worker
4617*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(UnstagePackages({file_path1}), Ok());
4618*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(-1, access(file_path1.c_str(), F_OK));
4619*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(errno, ENOENT);
4620*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path2.c_str(), F_OK));
4621*33f37583SAndroid Build Coastguard Worker }
4622*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,UnstagePackagesEmptyInput)4623*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, UnstagePackagesEmptyInput) {
4624*33f37583SAndroid Build Coastguard Worker auto file_path1 = AddDataApex("apex.apexd_test.apex");
4625*33f37583SAndroid Build Coastguard Worker auto file_path2 = AddDataApex("apex.apexd_test_different_app.apex");
4626*33f37583SAndroid Build Coastguard Worker
4627*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(UnstagePackages({}),
4628*33f37583SAndroid Build Coastguard Worker HasError(WithMessage("Empty set of inputs")));
4629*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path1.c_str(), F_OK));
4630*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path2.c_str(), F_OK));
4631*33f37583SAndroid Build Coastguard Worker }
4632*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,UnstagePackagesFail)4633*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, UnstagePackagesFail) {
4634*33f37583SAndroid Build Coastguard Worker auto file_path1 = AddDataApex("apex.apexd_test.apex");
4635*33f37583SAndroid Build Coastguard Worker auto bad_path = GetDataDir() + "/missing.apex";
4636*33f37583SAndroid Build Coastguard Worker
4637*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(UnstagePackages({file_path1, bad_path}), Not(Ok()));
4638*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path1.c_str(), F_OK));
4639*33f37583SAndroid Build Coastguard Worker }
4640*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,UnstagePackagesFailPreInstalledApex)4641*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, UnstagePackagesFailPreInstalledApex) {
4642*33f37583SAndroid Build Coastguard Worker auto file_path1 = AddPreInstalledApex("apex.apexd_test.apex");
4643*33f37583SAndroid Build Coastguard Worker auto file_path2 = AddDataApex("apex.apexd_test_different_app.apex");
4644*33f37583SAndroid Build Coastguard Worker
4645*33f37583SAndroid Build Coastguard Worker auto& instance = ApexFileRepository::GetInstance();
4646*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(instance.AddPreInstalledApex({{GetPartition(), GetBuiltInDir()}}),
4647*33f37583SAndroid Build Coastguard Worker Ok());
4648*33f37583SAndroid Build Coastguard Worker
4649*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(UnstagePackages({file_path1, file_path2}),
4650*33f37583SAndroid Build Coastguard Worker HasError(WithMessage("Can't uninstall pre-installed apex " +
4651*33f37583SAndroid Build Coastguard Worker file_path1)));
4652*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path1.c_str(), F_OK));
4653*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(file_path2.c_str(), F_OK));
4654*33f37583SAndroid Build Coastguard Worker }
4655*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,RevertStoresCrashingNativeProcess)4656*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, RevertStoresCrashingNativeProcess) {
4657*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4658*33f37583SAndroid Build Coastguard Worker checkpoint_interface.SetSupportsCheckpoint(true);
4659*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4660*33f37583SAndroid Build Coastguard Worker
4661*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test.apex", 1543);
4662*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session, Ok());
4663*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session->UpdateStateAndCommit(SessionState::ACTIVATED),
4664*33f37583SAndroid Build Coastguard Worker Ok());
4665*33f37583SAndroid Build Coastguard Worker
4666*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(RevertActiveSessions("test_process", ""), Ok());
4667*33f37583SAndroid Build Coastguard Worker apex_session = GetSessionManager()->GetSession(1543);
4668*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_session, Ok());
4669*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(apex_session->GetCrashingNativeProcess(), "test_process");
4670*33f37583SAndroid Build Coastguard Worker }
4671*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,MountAndDeriveClasspathNoJar)4672*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, MountAndDeriveClasspathNoJar) {
4673*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_classpath.apex");
4674*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
4675*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
4676*33f37583SAndroid Build Coastguard Worker
4677*33f37583SAndroid Build Coastguard Worker // Call MountAndDeriveClassPath
4678*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(GetTestFile("apex.apexd_test.apex"));
4679*33f37583SAndroid Build Coastguard Worker auto package_name = apex_file->GetManifest().name();
4680*33f37583SAndroid Build Coastguard Worker std::vector<ApexFile> apex_files;
4681*33f37583SAndroid Build Coastguard Worker apex_files.emplace_back(std::move(*apex_file));
4682*33f37583SAndroid Build Coastguard Worker auto class_path = MountAndDeriveClassPath(apex_files);
4683*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(class_path, Ok());
4684*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(class_path->HasClassPathJars(package_name), false);
4685*33f37583SAndroid Build Coastguard Worker }
4686*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,MountAndDeriveClassPathJarsPresent)4687*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, MountAndDeriveClassPathJarsPresent) {
4688*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_classpath.apex");
4689*33f37583SAndroid Build Coastguard Worker ApexFileRepository::GetInstance().AddPreInstalledApex(
4690*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}});
4691*33f37583SAndroid Build Coastguard Worker
4692*33f37583SAndroid Build Coastguard Worker // Call MountAndDeriveClassPath
4693*33f37583SAndroid Build Coastguard Worker auto apex_file =
4694*33f37583SAndroid Build Coastguard Worker ApexFile::Open(GetTestFile("apex.apexd_test_classpath.apex"));
4695*33f37583SAndroid Build Coastguard Worker auto package_name = apex_file->GetManifest().name();
4696*33f37583SAndroid Build Coastguard Worker std::vector<ApexFile> apex_files;
4697*33f37583SAndroid Build Coastguard Worker apex_files.emplace_back(std::move(*apex_file));
4698*33f37583SAndroid Build Coastguard Worker auto class_path = MountAndDeriveClassPath(apex_files);
4699*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(class_path, Ok());
4700*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(class_path->HasClassPathJars(package_name), true);
4701*33f37583SAndroid Build Coastguard Worker }
4702*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,ProcessCompressedApexWrongSELinuxContext)4703*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, ProcessCompressedApexWrongSELinuxContext) {
4704*33f37583SAndroid Build Coastguard Worker auto compressed_apex = ApexFile::Open(
4705*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
4706*33f37583SAndroid Build Coastguard Worker
4707*33f37583SAndroid Build Coastguard Worker std::vector<ApexFileRef> compressed_apex_list;
4708*33f37583SAndroid Build Coastguard Worker compressed_apex_list.emplace_back(std::cref(*compressed_apex));
4709*33f37583SAndroid Build Coastguard Worker auto return_value =
4710*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
4711*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(return_value.size(), 1u);
4712*33f37583SAndroid Build Coastguard Worker
4713*33f37583SAndroid Build Coastguard Worker auto decompressed_apex_path = StringPrintf(
4714*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
4715*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
4716*33f37583SAndroid Build Coastguard Worker // Verify that so far it has correct context.
4717*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(kTestActiveApexSelinuxCtx,
4718*33f37583SAndroid Build Coastguard Worker GetSelinuxContext(decompressed_apex_path));
4719*33f37583SAndroid Build Coastguard Worker
4720*33f37583SAndroid Build Coastguard Worker // Manually mess up the context
4721*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, setfilecon(decompressed_apex_path.c_str(),
4722*33f37583SAndroid Build Coastguard Worker "u:object_r:apex_data_file:s0"));
4723*33f37583SAndroid Build Coastguard Worker ASSERT_EQ("u:object_r:apex_data_file:s0",
4724*33f37583SAndroid Build Coastguard Worker GetSelinuxContext(decompressed_apex_path));
4725*33f37583SAndroid Build Coastguard Worker
4726*33f37583SAndroid Build Coastguard Worker auto attempt_2 =
4727*33f37583SAndroid Build Coastguard Worker ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
4728*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(attempt_2.size(), 1u);
4729*33f37583SAndroid Build Coastguard Worker // Verify that it again has correct context.
4730*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(kTestActiveApexSelinuxCtx,
4731*33f37583SAndroid Build Coastguard Worker GetSelinuxContext(decompressed_apex_path));
4732*33f37583SAndroid Build Coastguard Worker }
4733*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartNoApexUpdated)4734*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartNoApexUpdated) {
4735*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4736*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4737*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4738*33f37583SAndroid Build Coastguard Worker
4739*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
4740*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
4741*33f37583SAndroid Build Coastguard Worker std::string apex_path_2 =
4742*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("apex.apexd_test_different_app.apex");
4743*33f37583SAndroid Build Coastguard Worker std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
4744*33f37583SAndroid Build Coastguard Worker std::string apex_path_4 =
4745*33f37583SAndroid Build Coastguard Worker AddDecompressedApex("com.android.apex.compressed.v1.apex");
4746*33f37583SAndroid Build Coastguard Worker
4747*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
4748*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
4749*33f37583SAndroid Build Coastguard Worker Ok());
4750*33f37583SAndroid Build Coastguard Worker
4751*33f37583SAndroid Build Coastguard Worker OnStart();
4752*33f37583SAndroid Build Coastguard Worker
4753*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_2);
4754*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_3);
4755*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_4);
4756*33f37583SAndroid Build Coastguard Worker
4757*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
4758*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 0u);
4759*33f37583SAndroid Build Coastguard Worker // Quick check that all apexes were mounted
4760*33f37583SAndroid Build Coastguard Worker auto apex_mounts = GetApexMounts();
4761*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(apex_mounts.size(), 6u);
4762*33f37583SAndroid Build Coastguard Worker }
4763*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,OnStartDecompressingConsideredApexUpdate)4764*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, OnStartDecompressingConsideredApexUpdate) {
4765*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4766*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4767*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4768*33f37583SAndroid Build Coastguard Worker
4769*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.compressed.v1.capex");
4770*33f37583SAndroid Build Coastguard Worker std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
4771*33f37583SAndroid Build Coastguard Worker std::string decompressed_active_apex = StringPrintf(
4772*33f37583SAndroid Build Coastguard Worker "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
4773*33f37583SAndroid Build Coastguard Worker kDecompressedApexPackageSuffix);
4774*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
4775*33f37583SAndroid Build Coastguard Worker
4776*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
4777*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
4778*33f37583SAndroid Build Coastguard Worker Ok());
4779*33f37583SAndroid Build Coastguard Worker
4780*33f37583SAndroid Build Coastguard Worker OnStart();
4781*33f37583SAndroid Build Coastguard Worker
4782*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(apex_path_1);
4783*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(decompressed_active_apex);
4784*33f37583SAndroid Build Coastguard Worker
4785*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
4786*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 1u);
4787*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(decompressed_active_apex);
4788*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_file, Ok());
4789*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(IsActiveApexChanged(*apex_file));
4790*33f37583SAndroid Build Coastguard Worker }
4791*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatesStagedSession)4792*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatesStagedSession) {
4793*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4794*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4795*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4796*33f37583SAndroid Build Coastguard Worker
4797*33f37583SAndroid Build Coastguard Worker std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
4798*33f37583SAndroid Build Coastguard Worker auto apex_session = CreateStagedSession("apex.apexd_test_v2.apex", 37);
4799*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4800*33f37583SAndroid Build Coastguard Worker
4801*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
4802*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
4803*33f37583SAndroid Build Coastguard Worker Ok());
4804*33f37583SAndroid Build Coastguard Worker
4805*33f37583SAndroid Build Coastguard Worker std::string active_apex =
4806*33f37583SAndroid Build Coastguard Worker GetDataDir() + "/" + "[email protected]";
4807*33f37583SAndroid Build Coastguard Worker
4808*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(preinstalled_apex);
4809*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(active_apex);
4810*33f37583SAndroid Build Coastguard Worker OnStart();
4811*33f37583SAndroid Build Coastguard Worker
4812*33f37583SAndroid Build Coastguard Worker // Quick check that session was activated
4813*33f37583SAndroid Build Coastguard Worker {
4814*33f37583SAndroid Build Coastguard Worker auto session = GetSessionManager()->GetSession(37);
4815*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(session, Ok());
4816*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(session->GetState(), SessionState::ACTIVATED);
4817*33f37583SAndroid Build Coastguard Worker }
4818*33f37583SAndroid Build Coastguard Worker
4819*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
4820*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 1u);
4821*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(active_apex);
4822*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_file, Ok());
4823*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(IsActiveApexChanged(*apex_file));
4824*33f37583SAndroid Build Coastguard Worker }
4825*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,FailsToActivateStagedSession)4826*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, FailsToActivateStagedSession) {
4827*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4828*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4829*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4830*33f37583SAndroid Build Coastguard Worker
4831*33f37583SAndroid Build Coastguard Worker std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
4832*33f37583SAndroid Build Coastguard Worker auto apex_session =
4833*33f37583SAndroid Build Coastguard Worker CreateStagedSession("apex.apexd_test_manifest_mismatch.apex", 73);
4834*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
4835*33f37583SAndroid Build Coastguard Worker
4836*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
4837*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
4838*33f37583SAndroid Build Coastguard Worker Ok());
4839*33f37583SAndroid Build Coastguard Worker
4840*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(preinstalled_apex);
4841*33f37583SAndroid Build Coastguard Worker OnStart();
4842*33f37583SAndroid Build Coastguard Worker
4843*33f37583SAndroid Build Coastguard Worker // Quick check that session was activated
4844*33f37583SAndroid Build Coastguard Worker {
4845*33f37583SAndroid Build Coastguard Worker auto session = GetSessionManager()->GetSession(73);
4846*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(session, Ok());
4847*33f37583SAndroid Build Coastguard Worker ASSERT_NE(session->GetState(), SessionState::ACTIVATED);
4848*33f37583SAndroid Build Coastguard Worker }
4849*33f37583SAndroid Build Coastguard Worker
4850*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
4851*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 1u);
4852*33f37583SAndroid Build Coastguard Worker
4853*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(preinstalled_apex);
4854*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_file, Ok());
4855*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(IsActiveApexChanged(*apex_file));
4856*33f37583SAndroid Build Coastguard Worker }
4857*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,FailsToActivateApexFallbacksToSystemOne)4858*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, FailsToActivateApexFallbacksToSystemOne) {
4859*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4860*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
4861*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4862*33f37583SAndroid Build Coastguard Worker
4863*33f37583SAndroid Build Coastguard Worker std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
4864*33f37583SAndroid Build Coastguard Worker AddDataApex("apex.apexd_test_manifest_mismatch.apex");
4865*33f37583SAndroid Build Coastguard Worker
4866*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ApexFileRepository::GetInstance().AddPreInstalledApex(
4867*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}),
4868*33f37583SAndroid Build Coastguard Worker Ok());
4869*33f37583SAndroid Build Coastguard Worker
4870*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(preinstalled_apex);
4871*33f37583SAndroid Build Coastguard Worker OnStart();
4872*33f37583SAndroid Build Coastguard Worker
4873*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
4874*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 1u);
4875*33f37583SAndroid Build Coastguard Worker
4876*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(preinstalled_apex);
4877*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_file, Ok());
4878*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(IsActiveApexChanged(*apex_file));
4879*33f37583SAndroid Build Coastguard Worker }
4880*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,SubmitSingleStagedSessionKeepsPreviousSessions)4881*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, SubmitSingleStagedSessionKeepsPreviousSessions) {
4882*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4883*33f37583SAndroid Build Coastguard Worker checkpoint_interface.SetSupportsCheckpoint(true);
4884*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4885*33f37583SAndroid Build Coastguard Worker
4886*33f37583SAndroid Build Coastguard Worker std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
4887*33f37583SAndroid Build Coastguard Worker
4888*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(ApexFileRepository::GetInstance().AddPreInstalledApex(
4889*33f37583SAndroid Build Coastguard Worker {{GetPartition(), GetBuiltInDir()}}));
4890*33f37583SAndroid Build Coastguard Worker
4891*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(preinstalled_apex);
4892*33f37583SAndroid Build Coastguard Worker
4893*33f37583SAndroid Build Coastguard Worker // First simulate existence of a bunch of sessions.
4894*33f37583SAndroid Build Coastguard Worker auto session1 = GetSessionManager()->CreateSession(37);
4895*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(session1);
4896*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(session1->UpdateStateAndCommit(SessionState::VERIFIED));
4897*33f37583SAndroid Build Coastguard Worker
4898*33f37583SAndroid Build Coastguard Worker auto session2 = GetSessionManager()->CreateSession(57);
4899*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(session2);
4900*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(session2->UpdateStateAndCommit(SessionState::STAGED));
4901*33f37583SAndroid Build Coastguard Worker
4902*33f37583SAndroid Build Coastguard Worker auto session3 = GetSessionManager()->CreateSession(73);
4903*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(session3);
4904*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(session3->UpdateStateAndCommit(SessionState::SUCCESS));
4905*33f37583SAndroid Build Coastguard Worker
4906*33f37583SAndroid Build Coastguard Worker PrepareStagedSession("apex.apexd_test.apex", 239);
4907*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(SubmitStagedSession(239, {}, false, false, -1));
4908*33f37583SAndroid Build Coastguard Worker
4909*33f37583SAndroid Build Coastguard Worker auto sessions = GetSessionManager()->GetSessions();
4910*33f37583SAndroid Build Coastguard Worker std::sort(
4911*33f37583SAndroid Build Coastguard Worker sessions.begin(), sessions.end(),
4912*33f37583SAndroid Build Coastguard Worker [](const auto& s1, const auto& s2) { return s1.GetId() < s2.GetId(); });
4913*33f37583SAndroid Build Coastguard Worker
4914*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(4u, sessions.size());
4915*33f37583SAndroid Build Coastguard Worker
4916*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(37, sessions[0].GetId());
4917*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(SessionState::VERIFIED, sessions[0].GetState());
4918*33f37583SAndroid Build Coastguard Worker
4919*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(57, sessions[1].GetId());
4920*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(SessionState::STAGED, sessions[1].GetState());
4921*33f37583SAndroid Build Coastguard Worker
4922*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(73, sessions[2].GetId());
4923*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(SessionState::SUCCESS, sessions[2].GetState());
4924*33f37583SAndroid Build Coastguard Worker
4925*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(239, sessions[3].GetId());
4926*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(SessionState::VERIFIED, sessions[3].GetState());
4927*33f37583SAndroid Build Coastguard Worker }
4928*33f37583SAndroid Build Coastguard Worker
4929*33f37583SAndroid Build Coastguard Worker struct SpyMetrics : Metrics {
4930*33f37583SAndroid Build Coastguard Worker std::vector<std::tuple<InstallType, bool, ApexFileInfo>> requested;
4931*33f37583SAndroid Build Coastguard Worker std::vector<std::tuple<std::string, InstallResult>> ended;
4932*33f37583SAndroid Build Coastguard Worker
SendInstallationRequestedandroid::apex::SpyMetrics4933*33f37583SAndroid Build Coastguard Worker void SendInstallationRequested(InstallType install_type, bool is_rollback,
4934*33f37583SAndroid Build Coastguard Worker const ApexFileInfo& info) override {
4935*33f37583SAndroid Build Coastguard Worker requested.emplace_back(install_type, is_rollback, info);
4936*33f37583SAndroid Build Coastguard Worker }
SendInstallationEndedandroid::apex::SpyMetrics4937*33f37583SAndroid Build Coastguard Worker void SendInstallationEnded(const std::string& file_hash,
4938*33f37583SAndroid Build Coastguard Worker InstallResult result) override {
4939*33f37583SAndroid Build Coastguard Worker ended.emplace_back(file_hash, result);
4940*33f37583SAndroid Build Coastguard Worker }
4941*33f37583SAndroid Build Coastguard Worker };
4942*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,SendEventOnSubmitStagedSession)4943*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, SendEventOnSubmitStagedSession) {
4944*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
4945*33f37583SAndroid Build Coastguard Worker checkpoint_interface.SetSupportsCheckpoint(true);
4946*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
4947*33f37583SAndroid Build Coastguard Worker
4948*33f37583SAndroid Build Coastguard Worker InitMetrics(std::make_unique<SpyMetrics>());
4949*33f37583SAndroid Build Coastguard Worker
4950*33f37583SAndroid Build Coastguard Worker std::string preinstalled_apex =
4951*33f37583SAndroid Build Coastguard Worker AddPreInstalledApex("com.android.apex.vendor.foo.apex");
4952*33f37583SAndroid Build Coastguard Worker
4953*33f37583SAndroid Build Coastguard Worker // Test APEX is a "vendor" APEX. Preinstalled partition should be vendor.
4954*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(ApexFileRepository::GetInstance().AddPreInstalledApex(
4955*33f37583SAndroid Build Coastguard Worker {{ApexPartition::Vendor, GetBuiltInDir()}}));
4956*33f37583SAndroid Build Coastguard Worker
4957*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(preinstalled_apex);
4958*33f37583SAndroid Build Coastguard Worker OnStart();
4959*33f37583SAndroid Build Coastguard Worker // checkvintf needs apex-info-list.xml to identify vendor APEXes.
4960*33f37583SAndroid Build Coastguard Worker // OnAllPackagesActivated() generates it.
4961*33f37583SAndroid Build Coastguard Worker OnAllPackagesActivated(/*bootstrap*/ false);
4962*33f37583SAndroid Build Coastguard Worker
4963*33f37583SAndroid Build Coastguard Worker PrepareStagedSession("com.android.apex.vendor.foo.with_vintf.apex", 239);
4964*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(SubmitStagedSession(239, {}, false, false, -1));
4965*33f37583SAndroid Build Coastguard Worker
4966*33f37583SAndroid Build Coastguard Worker auto spy = std::unique_ptr<SpyMetrics>(
4967*33f37583SAndroid Build Coastguard Worker static_cast<SpyMetrics*>(InitMetrics(nullptr).release()));
4968*33f37583SAndroid Build Coastguard Worker ASSERT_NE(nullptr, spy.get());
4969*33f37583SAndroid Build Coastguard Worker
4970*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1u, spy->requested.size());
4971*33f37583SAndroid Build Coastguard Worker const auto& requested = spy->requested[0];
4972*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(InstallType::Staged, std::get<0>(requested));
4973*33f37583SAndroid Build Coastguard Worker ASSERT_EQ("com.android.apex.vendor.foo"s, std::get<2>(requested).name);
4974*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(std::get<2>(requested).hals, ElementsAre("android.apex.foo@1"s));
4975*33f37583SAndroid Build Coastguard Worker
4976*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0u, spy->ended.size());
4977*33f37583SAndroid Build Coastguard Worker }
4978*33f37583SAndroid Build Coastguard Worker
TEST(Loop,CreateWithApexFile)4979*33f37583SAndroid Build Coastguard Worker TEST(Loop, CreateWithApexFile) {
4980*33f37583SAndroid Build Coastguard Worker auto apex = ApexFile::Open(GetTestFile("apex.apexd_test.apex"));
4981*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex, Ok());
4982*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(apex->GetImageOffset().has_value());
4983*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(apex->GetImageSize().has_value());
4984*33f37583SAndroid Build Coastguard Worker
4985*33f37583SAndroid Build Coastguard Worker auto loop = loop::CreateAndConfigureLoopDevice(apex->GetPath(),
4986*33f37583SAndroid Build Coastguard Worker apex->GetImageOffset().value(),
4987*33f37583SAndroid Build Coastguard Worker apex->GetImageSize().value());
4988*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(loop, Ok());
4989*33f37583SAndroid Build Coastguard Worker }
4990*33f37583SAndroid Build Coastguard Worker
TEST(Loop,NoSuchFile)4991*33f37583SAndroid Build Coastguard Worker TEST(Loop, NoSuchFile) {
4992*33f37583SAndroid Build Coastguard Worker CaptureStderr();
4993*33f37583SAndroid Build Coastguard Worker {
4994*33f37583SAndroid Build Coastguard Worker auto loop = loop::CreateAndConfigureLoopDevice("invalid_path", 0, 0);
4995*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(loop, Not(Ok()));
4996*33f37583SAndroid Build Coastguard Worker }
4997*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(GetCapturedStderr(), "");
4998*33f37583SAndroid Build Coastguard Worker }
4999*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,SubmitStagedSessionSucceedVerifiedBrandNewApex)5000*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, SubmitStagedSessionSucceedVerifiedBrandNewApex) {
5001*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5002*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5003*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5004*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir;
5005*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5006*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5007*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5008*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5009*33f37583SAndroid Build Coastguard Worker
5010*33f37583SAndroid Build Coastguard Worker PrepareStagedSession("com.android.apex.brand.new.apex", 239);
5011*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(SubmitStagedSession(239, {}, false, false, -1));
5012*33f37583SAndroid Build Coastguard Worker
5013*33f37583SAndroid Build Coastguard Worker auto sessions = GetSessionManager()->GetSessions();
5014*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1u, sessions.size());
5015*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(239, sessions[0].GetId());
5016*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(SessionState::VERIFIED, sessions[0].GetState());
5017*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5018*33f37583SAndroid Build Coastguard Worker }
5019*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,SubmitStagedSessionSucceedVerifiedBrandNewApexWithActiveVersion)5020*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
5021*33f37583SAndroid Build Coastguard Worker SubmitStagedSessionSucceedVerifiedBrandNewApexWithActiveVersion) {
5022*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5023*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5024*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5025*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir, data_dir;
5026*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5027*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5028*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.brand.new.apex"), data_dir.path);
5029*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5030*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5031*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(file_repository.AddDataApex(data_dir.path));
5032*33f37583SAndroid Build Coastguard Worker
5033*33f37583SAndroid Build Coastguard Worker PrepareStagedSession("com.android.apex.brand.new.v2.apex", 239);
5034*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(SubmitStagedSession(239, {}, false, false, -1));
5035*33f37583SAndroid Build Coastguard Worker
5036*33f37583SAndroid Build Coastguard Worker auto sessions = GetSessionManager()->GetSessions();
5037*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(1u, sessions.size());
5038*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(239, sessions[0].GetId());
5039*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(SessionState::VERIFIED, sessions[0].GetState());
5040*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5041*33f37583SAndroid Build Coastguard Worker }
5042*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,SubmitStagedSessionFailBrandNewApexMismatchActiveVersion)5043*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest,
5044*33f37583SAndroid Build Coastguard Worker SubmitStagedSessionFailBrandNewApexMismatchActiveVersion) {
5045*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5046*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5047*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5048*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir, data_dir;
5049*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5050*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5051*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(
5052*33f37583SAndroid Build Coastguard Worker "apexd_testdata/com.android.apex.brand.new.another.avbpubkey"),
5053*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5054*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("com.android.apex.brand.new.apex"), data_dir.path);
5055*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5056*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5057*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(file_repository.AddDataApex(data_dir.path));
5058*33f37583SAndroid Build Coastguard Worker
5059*33f37583SAndroid Build Coastguard Worker PrepareStagedSession("com.android.apex.brand.new.v2.diffkey.apex", 239);
5060*33f37583SAndroid Build Coastguard Worker auto ret = SubmitStagedSession(239, {}, false, false, -1);
5061*33f37583SAndroid Build Coastguard Worker
5062*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
5063*33f37583SAndroid Build Coastguard Worker ret,
5064*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(("Brand-new APEX public key doesn't match existing "
5065*33f37583SAndroid Build Coastguard Worker "active APEX: com.android.apex.brand.new"))));
5066*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5067*33f37583SAndroid Build Coastguard Worker }
5068*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,SubmitStagedSessionFailBrandNewApexDisabled)5069*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, SubmitStagedSessionFailBrandNewApexDisabled) {
5070*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5071*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5072*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir;
5073*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5074*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5075*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5076*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5077*33f37583SAndroid Build Coastguard Worker
5078*33f37583SAndroid Build Coastguard Worker PrepareStagedSession("com.android.apex.brand.new.apex", 239);
5079*33f37583SAndroid Build Coastguard Worker auto ret = SubmitStagedSession(239, {}, false, false, -1);
5080*33f37583SAndroid Build Coastguard Worker
5081*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ret,
5082*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(("No preinstalled apex found for unverified "
5083*33f37583SAndroid Build Coastguard Worker "package com.android.apex.brand.new"))));
5084*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5085*33f37583SAndroid Build Coastguard Worker }
5086*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesSucceedVerifiedBrandNewApex)5087*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesSucceedVerifiedBrandNewApex) {
5088*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5089*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5090*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5091*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir;
5092*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5093*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5094*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5095*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5096*33f37583SAndroid Build Coastguard Worker
5097*33f37583SAndroid Build Coastguard Worker auto status = StagePackages({GetTestFile("com.android.apex.brand.new.apex")});
5098*33f37583SAndroid Build Coastguard Worker
5099*33f37583SAndroid Build Coastguard Worker ASSERT_RESULT_OK(status);
5100*33f37583SAndroid Build Coastguard Worker auto staged_path = StringPrintf("%s/com.android.apex.brand.new@1.apex",
5101*33f37583SAndroid Build Coastguard Worker GetDataDir().c_str());
5102*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
5103*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5104*33f37583SAndroid Build Coastguard Worker }
5105*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdUnitTest,StagePackagesFailUnverifiedBrandNewApex)5106*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdUnitTest, StagePackagesFailUnverifiedBrandNewApex) {
5107*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5108*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5109*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5110*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir;
5111*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(
5112*33f37583SAndroid Build Coastguard Worker "apexd_testdata/com.android.apex.brand.new.another.avbpubkey"),
5113*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5114*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5115*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5116*33f37583SAndroid Build Coastguard Worker
5117*33f37583SAndroid Build Coastguard Worker auto status = StagePackages({GetTestFile("com.android.apex.brand.new.apex")});
5118*33f37583SAndroid Build Coastguard Worker
5119*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(status,
5120*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(("No preinstalled apex found for unverified "
5121*33f37583SAndroid Build Coastguard Worker "package com.android.apex.brand.new"))));
5122*33f37583SAndroid Build Coastguard Worker
5123*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5124*33f37583SAndroid Build Coastguard Worker }
5125*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatesStagedSessionSucceedVerifiedBrandNewApex)5126*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatesStagedSessionSucceedVerifiedBrandNewApex) {
5127*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
5128*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
5129*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
5130*33f37583SAndroid Build Coastguard Worker
5131*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5132*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5133*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5134*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir;
5135*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5136*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5137*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5138*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5139*33f37583SAndroid Build Coastguard Worker
5140*33f37583SAndroid Build Coastguard Worker auto apex_session =
5141*33f37583SAndroid Build Coastguard Worker CreateStagedSession("com.android.apex.brand.new.apex", 37);
5142*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
5143*33f37583SAndroid Build Coastguard Worker
5144*33f37583SAndroid Build Coastguard Worker std::string active_apex =
5145*33f37583SAndroid Build Coastguard Worker GetDataDir() + "/" + "[email protected]";
5146*33f37583SAndroid Build Coastguard Worker
5147*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(active_apex);
5148*33f37583SAndroid Build Coastguard Worker OnStart();
5149*33f37583SAndroid Build Coastguard Worker
5150*33f37583SAndroid Build Coastguard Worker // Quick check that session was activated
5151*33f37583SAndroid Build Coastguard Worker {
5152*33f37583SAndroid Build Coastguard Worker auto session = GetSessionManager()->GetSession(37);
5153*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(session, Ok());
5154*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(session->GetState(), SessionState::ACTIVATED);
5155*33f37583SAndroid Build Coastguard Worker }
5156*33f37583SAndroid Build Coastguard Worker
5157*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
5158*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 1u);
5159*33f37583SAndroid Build Coastguard Worker auto apex_file = ApexFile::Open(active_apex);
5160*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(apex_file, Ok());
5161*33f37583SAndroid Build Coastguard Worker ASSERT_TRUE(IsActiveApexChanged(*apex_file));
5162*33f37583SAndroid Build Coastguard Worker
5163*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5164*33f37583SAndroid Build Coastguard Worker }
5165*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,ActivatesStagedSessionFailUnverifiedBrandNewApex)5166*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, ActivatesStagedSessionFailUnverifiedBrandNewApex) {
5167*33f37583SAndroid Build Coastguard Worker MockCheckpointInterface checkpoint_interface;
5168*33f37583SAndroid Build Coastguard Worker // Need to call InitializeVold before calling OnStart
5169*33f37583SAndroid Build Coastguard Worker InitializeVold(&checkpoint_interface);
5170*33f37583SAndroid Build Coastguard Worker
5171*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5172*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5173*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5174*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir;
5175*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile(
5176*33f37583SAndroid Build Coastguard Worker "apexd_testdata/com.android.apex.brand.new.another.avbpubkey"),
5177*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5178*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5179*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5180*33f37583SAndroid Build Coastguard Worker
5181*33f37583SAndroid Build Coastguard Worker auto apex_session =
5182*33f37583SAndroid Build Coastguard Worker CreateStagedSession("com.android.apex.brand.new.apex", 37);
5183*33f37583SAndroid Build Coastguard Worker apex_session->UpdateStateAndCommit(SessionState::STAGED);
5184*33f37583SAndroid Build Coastguard Worker
5185*33f37583SAndroid Build Coastguard Worker std::string active_apex =
5186*33f37583SAndroid Build Coastguard Worker GetDataDir() + "/" + "[email protected]";
5187*33f37583SAndroid Build Coastguard Worker
5188*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(active_apex);
5189*33f37583SAndroid Build Coastguard Worker OnStart();
5190*33f37583SAndroid Build Coastguard Worker
5191*33f37583SAndroid Build Coastguard Worker // Quick check that session was activated
5192*33f37583SAndroid Build Coastguard Worker {
5193*33f37583SAndroid Build Coastguard Worker auto session = GetSessionManager()->GetSession(37);
5194*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(session, Ok());
5195*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(session->GetState(), SessionState::ACTIVATION_FAILED);
5196*33f37583SAndroid Build Coastguard Worker }
5197*33f37583SAndroid Build Coastguard Worker
5198*33f37583SAndroid Build Coastguard Worker auto updated_apexes = GetChangedActiveApexesForTesting();
5199*33f37583SAndroid Build Coastguard Worker ASSERT_EQ(updated_apexes.size(), 0u);
5200*33f37583SAndroid Build Coastguard Worker
5201*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5202*33f37583SAndroid Build Coastguard Worker }
5203*33f37583SAndroid Build Coastguard Worker
TEST_F(ApexdMountTest,NonStagedUpdateFailVerifiedBrandNewApex)5204*33f37583SAndroid Build Coastguard Worker TEST_F(ApexdMountTest, NonStagedUpdateFailVerifiedBrandNewApex) {
5205*33f37583SAndroid Build Coastguard Worker ApexFileRepository::EnableBrandNewApex();
5206*33f37583SAndroid Build Coastguard Worker auto& file_repository = ApexFileRepository::GetInstance();
5207*33f37583SAndroid Build Coastguard Worker const auto partition = ApexPartition::System;
5208*33f37583SAndroid Build Coastguard Worker TemporaryDir trusted_key_dir, data_dir;
5209*33f37583SAndroid Build Coastguard Worker fs::copy(GetTestFile("apexd_testdata/com.android.apex.brand.new.avbpubkey"),
5210*33f37583SAndroid Build Coastguard Worker trusted_key_dir.path);
5211*33f37583SAndroid Build Coastguard Worker file_repository.AddBrandNewApexCredentialAndBlocklist(
5212*33f37583SAndroid Build Coastguard Worker {{partition, trusted_key_dir.path}});
5213*33f37583SAndroid Build Coastguard Worker auto file_path = AddDataApex("com.android.apex.brand.new.apex");
5214*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(ActivatePackage(file_path), Ok());
5215*33f37583SAndroid Build Coastguard Worker UnmountOnTearDown(file_path);
5216*33f37583SAndroid Build Coastguard Worker
5217*33f37583SAndroid Build Coastguard Worker auto ret = InstallPackage(GetTestFile("com.android.apex.brand.new.apex"),
5218*33f37583SAndroid Build Coastguard Worker /* force= */ false);
5219*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
5220*33f37583SAndroid Build Coastguard Worker ret,
5221*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr("No preinstalled apex found for package "
5222*33f37583SAndroid Build Coastguard Worker "com.android.apex.brand.new"))));
5223*33f37583SAndroid Build Coastguard Worker
5224*33f37583SAndroid Build Coastguard Worker file_repository.Reset();
5225*33f37583SAndroid Build Coastguard Worker }
5226*33f37583SAndroid Build Coastguard Worker
5227*33f37583SAndroid Build Coastguard Worker class LogTestToLogcat : public ::testing::EmptyTestEventListener {
OnTestStart(const::testing::TestInfo & test_info)5228*33f37583SAndroid Build Coastguard Worker void OnTestStart(const ::testing::TestInfo& test_info) override {
5229*33f37583SAndroid Build Coastguard Worker #ifdef __ANDROID__
5230*33f37583SAndroid Build Coastguard Worker using base::LogId;
5231*33f37583SAndroid Build Coastguard Worker using base::LogSeverity;
5232*33f37583SAndroid Build Coastguard Worker using base::StringPrintf;
5233*33f37583SAndroid Build Coastguard Worker base::LogdLogger l;
5234*33f37583SAndroid Build Coastguard Worker std::string msg =
5235*33f37583SAndroid Build Coastguard Worker StringPrintf("=== %s::%s (%s:%d)", test_info.test_suite_name(),
5236*33f37583SAndroid Build Coastguard Worker test_info.name(), test_info.file(), test_info.line());
5237*33f37583SAndroid Build Coastguard Worker l(LogId::MAIN, LogSeverity::INFO, "ApexTestCases", __FILE__, __LINE__,
5238*33f37583SAndroid Build Coastguard Worker msg.c_str());
5239*33f37583SAndroid Build Coastguard Worker #else
5240*33f37583SAndroid Build Coastguard Worker UNUSED(test_info);
5241*33f37583SAndroid Build Coastguard Worker #endif
5242*33f37583SAndroid Build Coastguard Worker }
5243*33f37583SAndroid Build Coastguard Worker };
5244*33f37583SAndroid Build Coastguard Worker
5245*33f37583SAndroid Build Coastguard Worker } // namespace apex
5246*33f37583SAndroid Build Coastguard Worker } // namespace android
5247*33f37583SAndroid Build Coastguard Worker
main(int argc,char ** argv)5248*33f37583SAndroid Build Coastguard Worker int main(int argc, char** argv) {
5249*33f37583SAndroid Build Coastguard Worker ::testing::InitGoogleTest(&argc, argv);
5250*33f37583SAndroid Build Coastguard Worker android::base::InitLogging(argv, &android::base::StderrLogger);
5251*33f37583SAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::VERBOSE);
5252*33f37583SAndroid Build Coastguard Worker ::testing::UnitTest::GetInstance()->listeners().Append(
5253*33f37583SAndroid Build Coastguard Worker new android::apex::LogTestToLogcat());
5254*33f37583SAndroid Build Coastguard Worker return RUN_ALL_TESTS();
5255*33f37583SAndroid Build Coastguard Worker }
5256