blob: 86aed2748c0cc9dff9fa025578c22e35d5aff18d [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));
55
56 void mountIncFsFails() {
57 ON_CALL(*this, mountIncFs(_, _, _, _))
58 .WillByDefault(
59 Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
60 }
61 void mountIncFsInvalidControlParcel() {
62 ON_CALL(*this, mountIncFs(_, _, _, _))
63 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
64 }
65 void mountIncFsSuccess() {
66 ON_CALL(*this, mountIncFs(_, _, _, _))
67 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
68 }
69 void bindMountFails() {
70 ON_CALL(*this, bindMount(_, _))
71 .WillByDefault(Return(
72 binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
73 }
74 void bindMountSuccess() {
75 ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
76 }
77 binder::Status getInvalidControlParcel(const std::string& imagePath,
78 const std::string& targetDir, int32_t flags,
79 IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080080 _aidl_return = {};
Songchun Fan3c82a302019-11-29 14:23:45 -080081 return binder::Status::ok();
82 }
83 binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
84 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080085 _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
86 _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
87 _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
Songchun Fan3c82a302019-11-29 14:23:45 -080088 return binder::Status::ok();
89 }
90
91private:
92 TemporaryFile cmdFile;
93 TemporaryFile logFile;
Songchun Fan3c82a302019-11-29 14:23:45 -080094};
95
Songchun Fan68645c42020-02-27 15:57:35 -080096class FakeDataLoader : public IDataLoader {
Songchun Fan3c82a302019-11-29 14:23:45 -080097public:
Songchun Fan68645c42020-02-27 15:57:35 -080098 IBinder* onAsBinder() override { return nullptr; }
99 binder::Status create(int32_t, const DataLoaderParamsParcel&, const FileSystemControlParcel&,
100 const sp<IDataLoaderStatusListener>&) override {
101 return binder::Status::ok();
102 }
Alex Buynytskyyb6e02f72020-03-17 18:12:23 -0700103 binder::Status start(int32_t) override { return binder::Status::ok(); }
104 binder::Status stop(int32_t) override { return binder::Status::ok(); }
105 binder::Status destroy(int32_t) override { return binder::Status::ok(); }
106 binder::Status prepareImage(int32_t,
107 const std::vector<InstallationFileParcel>&,
Songchun Fan68645c42020-02-27 15:57:35 -0800108 const std::vector<std::string>&) override {
109 return binder::Status::ok();
110 }
111};
112
113class MockDataLoaderManager : public DataLoaderManagerWrapper {
114public:
115 MOCK_CONST_METHOD5(initializeDataLoader,
116 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
117 const FileSystemControlParcel& control,
Songchun Fan3c82a302019-11-29 14:23:45 -0800118 const sp<IDataLoaderStatusListener>& listener,
119 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800120 MOCK_CONST_METHOD2(getDataLoader,
121 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Songchun Fan3c82a302019-11-29 14:23:45 -0800122 MOCK_CONST_METHOD1(destroyDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800123
Songchun Fan68645c42020-02-27 15:57:35 -0800124 binder::Status initializeDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
125 const FileSystemControlParcel& control,
126 const sp<IDataLoaderStatusListener>& listener,
127 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800128 mId = mountId;
129 mListener = listener;
130 *_aidl_return = true;
131 return binder::Status::ok();
132 }
133
Songchun Fan68645c42020-02-27 15:57:35 -0800134 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
135 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800136 return binder::Status::ok();
137 }
138
Songchun Fan68645c42020-02-27 15:57:35 -0800139 void initializeDataLoaderFails() {
140 ON_CALL(*this, initializeDataLoader(_, _, _, _, _))
Songchun Fan3c82a302019-11-29 14:23:45 -0800141 .WillByDefault(Return(
142 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
143 }
Songchun Fan68645c42020-02-27 15:57:35 -0800144 void initializeDataLoaderSuccess() {
145 ON_CALL(*this, initializeDataLoader(_, _, _, _, _))
146 .WillByDefault(Invoke(this, &MockDataLoaderManager::initializeDataLoaderOk));
Songchun Fan3c82a302019-11-29 14:23:45 -0800147 }
Songchun Fan68645c42020-02-27 15:57:35 -0800148 void getDataLoaderSuccess() {
149 ON_CALL(*this, getDataLoader(_, _))
150 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
Songchun Fan3c82a302019-11-29 14:23:45 -0800151 }
152 void setDataLoaderStatusNotReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800153 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800154 }
155 void setDataLoaderStatusReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800156 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800157 }
158
159private:
160 int mId;
161 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800162 sp<IDataLoader> mDataLoader = sp<IDataLoader>(new FakeDataLoader());
Songchun Fan3c82a302019-11-29 14:23:45 -0800163};
164
165class MockIncFs : public IncFsWrapper {
166public:
Songchun Fan20d6ef22020-03-03 09:47:15 -0800167 MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
Songchun Fan3c82a302019-11-29 14:23:45 -0800168 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800169 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800170 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800171 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
172 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
173 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
174 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800175 MOCK_CONST_METHOD3(link,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800176 ErrorCode(const Control& control, std::string_view from, std::string_view to));
177 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Yurii Zubrytskyie82cdd72020-04-01 12:19:26 -0700178 MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
Songchun Fan9b753082020-02-26 13:08:06 -0800179 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks));
Songchun Fan3c82a302019-11-29 14:23:45 -0800180
181 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
182 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800183 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800184 metadata::Mount m;
185 m.mutable_storage()->set_id(100);
186 m.mutable_loader()->set_package_name("com.test");
187 m.mutable_loader()->set_arguments("com.uri");
188 const auto metadata = m.SerializeAsString();
189 m.mutable_loader()->release_arguments();
190 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800191 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800192 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800193 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800194 metadata::Storage st;
195 st.set_id(100);
196 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800197 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800198 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800199 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800200 metadata::BindPoint bp;
201 std::string destPath = "dest";
202 std::string srcPath = "src";
203 bp.set_storage_id(100);
204 bp.set_allocated_dest_path(&destPath);
205 bp.set_allocated_source_subdir(&srcPath);
206 const auto metadata = bp.SerializeAsString();
207 bp.release_source_subdir();
208 bp.release_dest_path();
209 return std::vector<char>(metadata.begin(), metadata.end());
210 }
211};
212
213class MockServiceManager : public ServiceManagerWrapper {
214public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800215 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Songchun Fan68645c42020-02-27 15:57:35 -0800216 std::unique_ptr<MockDataLoaderManager> manager,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800217 std::unique_ptr<MockIncFs> incfs)
218 : mVold(std::move(vold)),
Songchun Fan68645c42020-02-27 15:57:35 -0800219 mDataLoaderManager(std::move(manager)),
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800220 mIncFs(std::move(incfs)) {}
221 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800222 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
223 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800224 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800225 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800226
227private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800228 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800229 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800230 std::unique_ptr<MockIncFs> mIncFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800231};
232
233// --- IncrementalServiceTest ---
234
Songchun Fan3c82a302019-11-29 14:23:45 -0800235class IncrementalServiceTest : public testing::Test {
236public:
237 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800238 auto vold = std::make_unique<NiceMock<MockVoldService>>();
239 mVold = vold.get();
Songchun Fan68645c42020-02-27 15:57:35 -0800240 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>();
241 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800242 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
243 mIncFs = incFs.get();
244 mIncrementalService =
245 std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
246 std::move(
Songchun Fan68645c42020-02-27 15:57:35 -0800247 dataloaderManager),
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800248 std::move(incFs)),
249 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800250 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800251 mDataLoaderParcel.arguments = "uri";
Songchun Fan3c82a302019-11-29 14:23:45 -0800252 mIncrementalService->onSystemReady();
253 }
254
255 void setUpExistingMountDir(const std::string& rootDir) {
256 const auto dir = rootDir + "/dir1";
257 const auto mountDir = dir + "/mount";
258 const auto backingDir = dir + "/backing_store";
259 const auto storageDir = mountDir + "/st0";
260 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
261 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
262 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
263 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
264 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
265 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
266 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
267 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800268 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
269 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
270 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
271 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
272 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
273 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800274 }
275
276protected:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800277 NiceMock<MockVoldService>* mVold;
278 NiceMock<MockIncFs>* mIncFs;
Songchun Fan68645c42020-02-27 15:57:35 -0800279 NiceMock<MockDataLoaderManager>* mDataLoaderManager;
Songchun Fan3c82a302019-11-29 14:23:45 -0800280 std::unique_ptr<IncrementalService> mIncrementalService;
281 TemporaryDir mRootDir;
282 DataLoaderParamsParcel mDataLoaderParcel;
283};
284
Songchun Fan3c82a302019-11-29 14:23:45 -0800285TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
286 mVold->mountIncFsFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800287 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800288 TemporaryDir tempDir;
289 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800290 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800291 IncrementalService::CreateOptions::CreateNew);
292 ASSERT_LT(storageId, 0);
293}
294
295TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
296 mVold->mountIncFsInvalidControlParcel();
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, testCreateStorageMakeFileFails) {
306 mVold->mountIncFsSuccess();
307 mIncFs->makeFileFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800308 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
309 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800310 EXPECT_CALL(*mVold, unmountIncFs(_));
311 TemporaryDir tempDir;
312 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800313 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800314 IncrementalService::CreateOptions::CreateNew);
315 ASSERT_LT(storageId, 0);
316}
317
318TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
319 mVold->mountIncFsSuccess();
320 mIncFs->makeFileSuccess();
321 mVold->bindMountFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800322 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
323 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800324 EXPECT_CALL(*mVold, unmountIncFs(_));
325 TemporaryDir tempDir;
326 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800327 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800328 IncrementalService::CreateOptions::CreateNew);
329 ASSERT_LT(storageId, 0);
330}
331
332TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
333 mVold->mountIncFsSuccess();
334 mIncFs->makeFileSuccess();
335 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800336 mDataLoaderManager->initializeDataLoaderFails();
337 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800338 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
339 TemporaryDir tempDir;
340 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800341 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800342 IncrementalService::CreateOptions::CreateNew);
343 ASSERT_LT(storageId, 0);
344}
345
346TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
347 mVold->mountIncFsSuccess();
348 mIncFs->makeFileSuccess();
349 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800350 mDataLoaderManager->initializeDataLoaderSuccess();
351 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800352 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
353 TemporaryDir tempDir;
354 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800355 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800356 IncrementalService::CreateOptions::CreateNew);
357 ASSERT_GE(storageId, 0);
358 mIncrementalService->deleteStorage(storageId);
359}
360
361TEST_F(IncrementalServiceTest, testOnStatusNotReady) {
362 mVold->mountIncFsSuccess();
363 mIncFs->makeFileSuccess();
364 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800365 mDataLoaderManager->initializeDataLoaderSuccess();
366 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800367 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
368 TemporaryDir tempDir;
369 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800370 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800371 IncrementalService::CreateOptions::CreateNew);
372 ASSERT_GE(storageId, 0);
Songchun Fan68645c42020-02-27 15:57:35 -0800373 mDataLoaderManager->setDataLoaderStatusNotReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800374}
375
376TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) {
377 mVold->mountIncFsSuccess();
378 mIncFs->makeFileSuccess();
379 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800380 mDataLoaderManager->initializeDataLoaderSuccess();
381 mDataLoaderManager->getDataLoaderSuccess();
382 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800383 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
384 TemporaryDir tempDir;
385 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800386 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800387 IncrementalService::CreateOptions::CreateNew);
388 ASSERT_GE(storageId, 0);
Songchun Fan68645c42020-02-27 15:57:35 -0800389 mDataLoaderManager->setDataLoaderStatusReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800390 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
391}
392
393TEST_F(IncrementalServiceTest, testMakeDirectory) {
394 mVold->mountIncFsSuccess();
395 mIncFs->makeFileSuccess();
396 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800397 mDataLoaderManager->initializeDataLoaderSuccess();
398 mDataLoaderManager->getDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800399 TemporaryDir tempDir;
400 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800401 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800402 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800403 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -0800404
Songchun Fan103ba1d2020-02-03 17:32:32 -0800405 std::string tempPath(tempDir.path);
406 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800407 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800408 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800409
Songchun Fan103ba1d2020-02-03 17:32:32 -0800410 // Expecting incfs to call makeDir on a path like:
411 // /data/local/tmp/TemporaryDir-06yixG/data_local_tmp_TemporaryDir-xwdFhT/mount/st_1_0/test
412 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800413 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
414 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800415}
416
417TEST_F(IncrementalServiceTest, testMakeDirectories) {
418 mVold->mountIncFsSuccess();
419 mIncFs->makeFileSuccess();
420 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800421 mDataLoaderManager->initializeDataLoaderSuccess();
422 mDataLoaderManager->getDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800423 TemporaryDir tempDir;
424 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800425 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800426 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800427 auto first = "first"sv;
428 auto second = "second"sv;
429 auto third = "third"sv;
Songchun Fan103ba1d2020-02-03 17:32:32 -0800430
431 std::string tempPath(tempDir.path);
432 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800433 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800434
Songchun Fan3c82a302019-11-29 14:23:45 -0800435 InSequence seq;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800436 auto parent_path = std::string(first) + "/" + std::string(second);
437 auto dir_path = parent_path + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800438
439 std::string normalized_first_path = mount_dir + "/mount/st_1_0/" + std::string(first);
440 std::string normalized_parent_path = mount_dir + "/mount/st_1_0/" + parent_path;
441 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
442
443 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _))
444 .WillOnce(Return(-ENOENT));
445 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
446 .WillOnce(Return(-ENOENT));
447 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_first_path), _))
448 .WillOnce(Return(0));
449 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
450 .WillOnce(Return(0));
451 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)).WillOnce(Return(0));
452 auto res = mIncrementalService->makeDirs(storageId, normalized_dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800453 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800454}
455} // namespace android::os::incremental