blob: cde38fbb3ca259d71306afffdc2ab12d275292bf [file] [log] [blame]
Songchun Fan3c82a302019-11-29 14:23:45 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android-base/file.h>
18#include <android-base/logging.h>
19#include <android-base/unique_fd.h>
20#include <binder/ParcelFileDescriptor.h>
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23#include <utils/Log.h>
24
25#include <future>
26
27#include "IncrementalService.h"
28#include "Metadata.pb.h"
29#include "ServiceWrappers.h"
30
31using namespace testing;
32using namespace android::incremental;
33using namespace std::literals;
34using testing::_;
35using testing::Invoke;
36using testing::NiceMock;
37
38#undef LOG_TAG
39#define LOG_TAG "IncrementalServiceTest"
40
41using namespace android::incfs;
42using namespace android::content::pm;
43
44namespace android::os::incremental {
45
46class MockVoldService : public VoldServiceWrapper {
47public:
48 MOCK_CONST_METHOD4(mountIncFs,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080049 binder::Status(const std::string& backingPath, const std::string& targetDir,
Songchun Fan3c82a302019-11-29 14:23:45 -080050 int32_t flags,
51 IncrementalFileSystemControlParcel* _aidl_return));
52 MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
53 MOCK_CONST_METHOD2(bindMount,
54 binder::Status(const std::string& sourceDir, const std::string& argetDir));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070055 MOCK_CONST_METHOD2(setIncFsMountOptions,
56 binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&, bool));
Songchun Fan3c82a302019-11-29 14:23:45 -080057
58 void mountIncFsFails() {
59 ON_CALL(*this, mountIncFs(_, _, _, _))
60 .WillByDefault(
61 Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
62 }
63 void mountIncFsInvalidControlParcel() {
64 ON_CALL(*this, mountIncFs(_, _, _, _))
65 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
66 }
67 void mountIncFsSuccess() {
68 ON_CALL(*this, mountIncFs(_, _, _, _))
69 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
70 }
71 void bindMountFails() {
72 ON_CALL(*this, bindMount(_, _))
73 .WillByDefault(Return(
74 binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
75 }
76 void bindMountSuccess() {
77 ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
78 }
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070079 void setIncFsMountOptionsFails() const {
80 ON_CALL(*this, setIncFsMountOptions(_, _))
81 .WillByDefault(
82 Return(binder::Status::fromExceptionCode(1, String8("failed to set options"))));
83 }
84 void setIncFsMountOptionsSuccess() {
85 ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
86 }
Songchun Fan3c82a302019-11-29 14:23:45 -080087 binder::Status getInvalidControlParcel(const std::string& imagePath,
88 const std::string& targetDir, int32_t flags,
89 IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080090 _aidl_return = {};
Songchun Fan3c82a302019-11-29 14:23:45 -080091 return binder::Status::ok();
92 }
93 binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
94 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080095 _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
96 _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
97 _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
Songchun Fan3c82a302019-11-29 14:23:45 -080098 return binder::Status::ok();
99 }
100
101private:
102 TemporaryFile cmdFile;
103 TemporaryFile logFile;
Songchun Fan3c82a302019-11-29 14:23:45 -0800104};
105
Songchun Fan68645c42020-02-27 15:57:35 -0800106class FakeDataLoader : public IDataLoader {
Songchun Fan3c82a302019-11-29 14:23:45 -0800107public:
Songchun Fan68645c42020-02-27 15:57:35 -0800108 IBinder* onAsBinder() override { return nullptr; }
109 binder::Status create(int32_t, const DataLoaderParamsParcel&, const FileSystemControlParcel&,
110 const sp<IDataLoaderStatusListener>&) override {
111 return binder::Status::ok();
112 }
Alex Buynytskyyb6e02f72020-03-17 18:12:23 -0700113 binder::Status start(int32_t) override { return binder::Status::ok(); }
114 binder::Status stop(int32_t) override { return binder::Status::ok(); }
115 binder::Status destroy(int32_t) override { return binder::Status::ok(); }
116 binder::Status prepareImage(int32_t,
117 const std::vector<InstallationFileParcel>&,
Songchun Fan68645c42020-02-27 15:57:35 -0800118 const std::vector<std::string>&) override {
119 return binder::Status::ok();
120 }
121};
122
123class MockDataLoaderManager : public DataLoaderManagerWrapper {
124public:
125 MOCK_CONST_METHOD5(initializeDataLoader,
126 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
127 const FileSystemControlParcel& control,
Songchun Fan3c82a302019-11-29 14:23:45 -0800128 const sp<IDataLoaderStatusListener>& listener,
129 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800130 MOCK_CONST_METHOD2(getDataLoader,
131 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Songchun Fan3c82a302019-11-29 14:23:45 -0800132 MOCK_CONST_METHOD1(destroyDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800133
Songchun Fan68645c42020-02-27 15:57:35 -0800134 binder::Status initializeDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
135 const FileSystemControlParcel& control,
136 const sp<IDataLoaderStatusListener>& listener,
137 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800138 mId = mountId;
139 mListener = listener;
140 *_aidl_return = true;
141 return binder::Status::ok();
142 }
143
Songchun Fan68645c42020-02-27 15:57:35 -0800144 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
145 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800146 return binder::Status::ok();
147 }
148
Songchun Fan68645c42020-02-27 15:57:35 -0800149 void initializeDataLoaderFails() {
150 ON_CALL(*this, initializeDataLoader(_, _, _, _, _))
Songchun Fan3c82a302019-11-29 14:23:45 -0800151 .WillByDefault(Return(
152 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
153 }
Songchun Fan68645c42020-02-27 15:57:35 -0800154 void initializeDataLoaderSuccess() {
155 ON_CALL(*this, initializeDataLoader(_, _, _, _, _))
156 .WillByDefault(Invoke(this, &MockDataLoaderManager::initializeDataLoaderOk));
Songchun Fan3c82a302019-11-29 14:23:45 -0800157 }
Songchun Fan68645c42020-02-27 15:57:35 -0800158 void getDataLoaderSuccess() {
159 ON_CALL(*this, getDataLoader(_, _))
160 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
Songchun Fan3c82a302019-11-29 14:23:45 -0800161 }
162 void setDataLoaderStatusNotReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800163 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800164 }
165 void setDataLoaderStatusReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800166 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800167 }
168
169private:
170 int mId;
171 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800172 sp<IDataLoader> mDataLoader = sp<IDataLoader>(new FakeDataLoader());
Songchun Fan3c82a302019-11-29 14:23:45 -0800173};
174
175class MockIncFs : public IncFsWrapper {
176public:
Songchun Fan20d6ef22020-03-03 09:47:15 -0800177 MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
Songchun Fan3c82a302019-11-29 14:23:45 -0800178 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800179 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800180 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800181 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
182 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
183 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
184 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800185 MOCK_CONST_METHOD3(link,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800186 ErrorCode(const Control& control, std::string_view from, std::string_view to));
187 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Yurii Zubrytskyie82cdd72020-04-01 12:19:26 -0700188 MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
Songchun Fan9b753082020-02-26 13:08:06 -0800189 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks));
Songchun Fan3c82a302019-11-29 14:23:45 -0800190
191 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
192 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800193 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800194 metadata::Mount m;
195 m.mutable_storage()->set_id(100);
196 m.mutable_loader()->set_package_name("com.test");
197 m.mutable_loader()->set_arguments("com.uri");
198 const auto metadata = m.SerializeAsString();
199 m.mutable_loader()->release_arguments();
200 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800201 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800202 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800203 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800204 metadata::Storage st;
205 st.set_id(100);
206 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800207 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800208 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800209 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800210 metadata::BindPoint bp;
211 std::string destPath = "dest";
212 std::string srcPath = "src";
213 bp.set_storage_id(100);
214 bp.set_allocated_dest_path(&destPath);
215 bp.set_allocated_source_subdir(&srcPath);
216 const auto metadata = bp.SerializeAsString();
217 bp.release_source_subdir();
218 bp.release_dest_path();
219 return std::vector<char>(metadata.begin(), metadata.end());
220 }
221};
222
223class MockServiceManager : public ServiceManagerWrapper {
224public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800225 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Songchun Fan68645c42020-02-27 15:57:35 -0800226 std::unique_ptr<MockDataLoaderManager> manager,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800227 std::unique_ptr<MockIncFs> incfs)
228 : mVold(std::move(vold)),
Songchun Fan68645c42020-02-27 15:57:35 -0800229 mDataLoaderManager(std::move(manager)),
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800230 mIncFs(std::move(incfs)) {}
231 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800232 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
233 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800234 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800235 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800236
237private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800238 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800239 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800240 std::unique_ptr<MockIncFs> mIncFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800241};
242
243// --- IncrementalServiceTest ---
244
Songchun Fan3c82a302019-11-29 14:23:45 -0800245class IncrementalServiceTest : public testing::Test {
246public:
247 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800248 auto vold = std::make_unique<NiceMock<MockVoldService>>();
249 mVold = vold.get();
Songchun Fan68645c42020-02-27 15:57:35 -0800250 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>();
251 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800252 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
253 mIncFs = incFs.get();
254 mIncrementalService =
255 std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
256 std::move(
Songchun Fan68645c42020-02-27 15:57:35 -0800257 dataloaderManager),
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800258 std::move(incFs)),
259 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800260 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800261 mDataLoaderParcel.arguments = "uri";
Songchun Fan3c82a302019-11-29 14:23:45 -0800262 mIncrementalService->onSystemReady();
263 }
264
265 void setUpExistingMountDir(const std::string& rootDir) {
266 const auto dir = rootDir + "/dir1";
267 const auto mountDir = dir + "/mount";
268 const auto backingDir = dir + "/backing_store";
269 const auto storageDir = mountDir + "/st0";
270 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
271 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
272 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
273 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
274 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
275 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
276 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
277 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800278 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
279 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
280 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
281 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
282 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
283 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800284 }
285
286protected:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800287 NiceMock<MockVoldService>* mVold;
288 NiceMock<MockIncFs>* mIncFs;
Songchun Fan68645c42020-02-27 15:57:35 -0800289 NiceMock<MockDataLoaderManager>* mDataLoaderManager;
Songchun Fan3c82a302019-11-29 14:23:45 -0800290 std::unique_ptr<IncrementalService> mIncrementalService;
291 TemporaryDir mRootDir;
292 DataLoaderParamsParcel mDataLoaderParcel;
293};
294
Songchun Fan3c82a302019-11-29 14:23:45 -0800295TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
296 mVold->mountIncFsFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800297 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800298 TemporaryDir tempDir;
299 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800300 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800301 IncrementalService::CreateOptions::CreateNew);
302 ASSERT_LT(storageId, 0);
303}
304
305TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
306 mVold->mountIncFsInvalidControlParcel();
Songchun Fan68645c42020-02-27 15:57:35 -0800307 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800308 TemporaryDir tempDir;
309 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800310 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800311 IncrementalService::CreateOptions::CreateNew);
312 ASSERT_LT(storageId, 0);
313}
314
315TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
316 mVold->mountIncFsSuccess();
317 mIncFs->makeFileFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800318 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
319 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800320 EXPECT_CALL(*mVold, unmountIncFs(_));
321 TemporaryDir tempDir;
322 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800323 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800324 IncrementalService::CreateOptions::CreateNew);
325 ASSERT_LT(storageId, 0);
326}
327
328TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
329 mVold->mountIncFsSuccess();
330 mIncFs->makeFileSuccess();
331 mVold->bindMountFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800332 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
333 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800334 EXPECT_CALL(*mVold, unmountIncFs(_));
335 TemporaryDir tempDir;
336 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800337 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800338 IncrementalService::CreateOptions::CreateNew);
339 ASSERT_LT(storageId, 0);
340}
341
342TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
343 mVold->mountIncFsSuccess();
344 mIncFs->makeFileSuccess();
345 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800346 mDataLoaderManager->initializeDataLoaderFails();
347 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800348 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
349 TemporaryDir tempDir;
350 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800351 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800352 IncrementalService::CreateOptions::CreateNew);
353 ASSERT_LT(storageId, 0);
354}
355
356TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
357 mVold->mountIncFsSuccess();
358 mIncFs->makeFileSuccess();
359 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800360 mDataLoaderManager->initializeDataLoaderSuccess();
361 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800362 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
363 TemporaryDir tempDir;
364 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800365 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800366 IncrementalService::CreateOptions::CreateNew);
367 ASSERT_GE(storageId, 0);
368 mIncrementalService->deleteStorage(storageId);
369}
370
371TEST_F(IncrementalServiceTest, testOnStatusNotReady) {
372 mVold->mountIncFsSuccess();
373 mIncFs->makeFileSuccess();
374 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800375 mDataLoaderManager->initializeDataLoaderSuccess();
376 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800377 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
378 TemporaryDir tempDir;
379 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800380 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800381 IncrementalService::CreateOptions::CreateNew);
382 ASSERT_GE(storageId, 0);
Songchun Fan68645c42020-02-27 15:57:35 -0800383 mDataLoaderManager->setDataLoaderStatusNotReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800384}
385
386TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) {
387 mVold->mountIncFsSuccess();
388 mIncFs->makeFileSuccess();
389 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800390 mDataLoaderManager->initializeDataLoaderSuccess();
391 mDataLoaderManager->getDataLoaderSuccess();
392 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800393 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
394 TemporaryDir tempDir;
395 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800396 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800397 IncrementalService::CreateOptions::CreateNew);
398 ASSERT_GE(storageId, 0);
Songchun Fan68645c42020-02-27 15:57:35 -0800399 mDataLoaderManager->setDataLoaderStatusReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800400 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
401}
402
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700403TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
404 mVold->mountIncFsSuccess();
405 mIncFs->makeFileSuccess();
406 mVold->bindMountSuccess();
407 mVold->setIncFsMountOptionsSuccess();
408 mDataLoaderManager->initializeDataLoaderSuccess();
409 mDataLoaderManager->getDataLoaderSuccess();
410 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
411 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
412 EXPECT_CALL(*mVold, setIncFsMountOptions(_, _));
413 TemporaryDir tempDir;
414 int storageId =
415 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
416 IncrementalService::CreateOptions::CreateNew);
417 ASSERT_GE(storageId, 0);
418 ASSERT_GE(mIncrementalService->setStorageParams(storageId, true), 0);
419}
420
421TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
422 mVold->mountIncFsSuccess();
423 mIncFs->makeFileSuccess();
424 mVold->bindMountSuccess();
425 mVold->setIncFsMountOptionsFails();
426 mDataLoaderManager->initializeDataLoaderSuccess();
427 mDataLoaderManager->getDataLoaderSuccess();
428 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
429 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
430 EXPECT_CALL(*mVold, setIncFsMountOptions(_, _));
431 TemporaryDir tempDir;
432 int storageId =
433 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
434 IncrementalService::CreateOptions::CreateNew);
435 ASSERT_GE(storageId, 0);
436 ASSERT_LT(mIncrementalService->setStorageParams(storageId, true), 0);
437}
438
Songchun Fan3c82a302019-11-29 14:23:45 -0800439TEST_F(IncrementalServiceTest, testMakeDirectory) {
440 mVold->mountIncFsSuccess();
441 mIncFs->makeFileSuccess();
442 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800443 mDataLoaderManager->initializeDataLoaderSuccess();
444 mDataLoaderManager->getDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800445 TemporaryDir tempDir;
446 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800447 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800448 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800449 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -0800450
Songchun Fan103ba1d2020-02-03 17:32:32 -0800451 std::string tempPath(tempDir.path);
452 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800453 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800454 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800455
Songchun Fan103ba1d2020-02-03 17:32:32 -0800456 // Expecting incfs to call makeDir on a path like:
457 // /data/local/tmp/TemporaryDir-06yixG/data_local_tmp_TemporaryDir-xwdFhT/mount/st_1_0/test
458 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800459 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
460 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800461}
462
463TEST_F(IncrementalServiceTest, testMakeDirectories) {
464 mVold->mountIncFsSuccess();
465 mIncFs->makeFileSuccess();
466 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800467 mDataLoaderManager->initializeDataLoaderSuccess();
468 mDataLoaderManager->getDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800469 TemporaryDir tempDir;
470 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800471 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800472 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800473 auto first = "first"sv;
474 auto second = "second"sv;
475 auto third = "third"sv;
Songchun Fan103ba1d2020-02-03 17:32:32 -0800476
477 std::string tempPath(tempDir.path);
478 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800479 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800480
Songchun Fan3c82a302019-11-29 14:23:45 -0800481 InSequence seq;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800482 auto parent_path = std::string(first) + "/" + std::string(second);
483 auto dir_path = parent_path + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800484
485 std::string normalized_first_path = mount_dir + "/mount/st_1_0/" + std::string(first);
486 std::string normalized_parent_path = mount_dir + "/mount/st_1_0/" + parent_path;
487 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
488
489 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _))
490 .WillOnce(Return(-ENOENT));
491 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
492 .WillOnce(Return(-ENOENT));
493 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_first_path), _))
494 .WillOnce(Return(0));
495 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
496 .WillOnce(Return(0));
497 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)).WillOnce(Return(0));
498 auto res = mIncrementalService->makeDirs(storageId, normalized_dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800499 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800500}
501} // namespace android::os::incremental