blob: aca6ca49e805c178a762b4307a48fe3142376afa [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
96class MockIncrementalManager : public IncrementalManagerWrapper {
97public:
98 MOCK_CONST_METHOD5(prepareDataLoader,
99 binder::Status(int32_t mountId, const FileSystemControlParcel& control,
100 const DataLoaderParamsParcel& params,
101 const sp<IDataLoaderStatusListener>& listener,
102 bool* _aidl_return));
103 MOCK_CONST_METHOD2(startDataLoader, binder::Status(int32_t mountId, bool* _aidl_return));
104 MOCK_CONST_METHOD1(destroyDataLoader, binder::Status(int32_t mountId));
105 MOCK_CONST_METHOD3(newFileForDataLoader,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800106 binder::Status(int32_t mountId, FileId fileId,
Songchun Fan3c82a302019-11-29 14:23:45 -0800107 const ::std::vector<uint8_t>& metadata));
108 MOCK_CONST_METHOD1(showHealthBlockedUI, binder::Status(int32_t mountId));
109
110 binder::Status prepareDataLoaderOk(int32_t mountId, const FileSystemControlParcel& control,
111 const DataLoaderParamsParcel& params,
112 const sp<IDataLoaderStatusListener>& listener,
113 bool* _aidl_return) {
114 mId = mountId;
115 mListener = listener;
116 *_aidl_return = true;
117 return binder::Status::ok();
118 }
119
120 binder::Status startDataLoaderOk(int32_t mountId, bool* _aidl_return) {
121 *_aidl_return = true;
122 return binder::Status::ok();
123 }
124
125 void prepareDataLoaderFails() {
126 ON_CALL(*this, prepareDataLoader(_, _, _, _, _))
127 .WillByDefault(Return(
128 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
129 }
130 void prepareDataLoaderSuccess() {
131 ON_CALL(*this, prepareDataLoader(_, _, _, _, _))
132 .WillByDefault(Invoke(this, &MockIncrementalManager::prepareDataLoaderOk));
133 }
134 void startDataLoaderSuccess() {
135 ON_CALL(*this, startDataLoader(_, _))
136 .WillByDefault(Invoke(this, &MockIncrementalManager::startDataLoaderOk));
137 }
138 void setDataLoaderStatusNotReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800139 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800140 }
141 void setDataLoaderStatusReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800142 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800143 }
144
145private:
146 int mId;
147 sp<IDataLoaderStatusListener> mListener;
148};
149
150class MockIncFs : public IncFsWrapper {
151public:
152 MOCK_CONST_METHOD5(makeFile,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800153 ErrorCode(Control control, std::string_view path, int mode, FileId id,
154 NewFileParams params));
155 MOCK_CONST_METHOD3(makeDir, ErrorCode(Control control, std::string_view path, int mode));
156 MOCK_CONST_METHOD2(getMetadata, RawMetadata(Control control, FileId fileid));
157 MOCK_CONST_METHOD2(getMetadata, RawMetadata(Control control, std::string_view path));
158 MOCK_CONST_METHOD2(getFileId, FileId(Control control, std::string_view path));
159 MOCK_CONST_METHOD3(link,
160 ErrorCode(Control control, std::string_view from, std::string_view to));
161 MOCK_CONST_METHOD2(unlink, ErrorCode(Control control, std::string_view path));
162 MOCK_CONST_METHOD2(openWrite, base::unique_fd(Control control, FileId id));
Songchun Fan9b753082020-02-26 13:08:06 -0800163 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks));
Songchun Fan3c82a302019-11-29 14:23:45 -0800164
165 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
166 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800167 RawMetadata getMountInfoMetadata(Control control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800168 metadata::Mount m;
169 m.mutable_storage()->set_id(100);
170 m.mutable_loader()->set_package_name("com.test");
171 m.mutable_loader()->set_arguments("com.uri");
172 const auto metadata = m.SerializeAsString();
173 m.mutable_loader()->release_arguments();
174 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800175 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800176 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800177 RawMetadata getStorageMetadata(Control control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800178 metadata::Storage st;
179 st.set_id(100);
180 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800181 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800182 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800183 RawMetadata getBindPointMetadata(Control control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800184 metadata::BindPoint bp;
185 std::string destPath = "dest";
186 std::string srcPath = "src";
187 bp.set_storage_id(100);
188 bp.set_allocated_dest_path(&destPath);
189 bp.set_allocated_source_subdir(&srcPath);
190 const auto metadata = bp.SerializeAsString();
191 bp.release_source_subdir();
192 bp.release_dest_path();
193 return std::vector<char>(metadata.begin(), metadata.end());
194 }
195};
196
197class MockServiceManager : public ServiceManagerWrapper {
198public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800199 MockServiceManager(std::unique_ptr<MockVoldService> vold,
200 std::unique_ptr<MockIncrementalManager> manager,
201 std::unique_ptr<MockIncFs> incfs)
202 : mVold(std::move(vold)),
203 mIncrementalManager(std::move(manager)),
204 mIncFs(std::move(incfs)) {}
205 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
206 std::unique_ptr<IncrementalManagerWrapper> getIncrementalManager() final {
207 return std::move(mIncrementalManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800208 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800209 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800210
211private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800212 std::unique_ptr<MockVoldService> mVold;
213 std::unique_ptr<MockIncrementalManager> mIncrementalManager;
214 std::unique_ptr<MockIncFs> mIncFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800215};
216
217// --- IncrementalServiceTest ---
218
Songchun Fan3c82a302019-11-29 14:23:45 -0800219class IncrementalServiceTest : public testing::Test {
220public:
221 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800222 auto vold = std::make_unique<NiceMock<MockVoldService>>();
223 mVold = vold.get();
224 auto incrementalManager = std::make_unique<NiceMock<MockIncrementalManager>>();
225 mIncrementalManager = incrementalManager.get();
226 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
227 mIncFs = incFs.get();
228 mIncrementalService =
229 std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
230 std::move(
231 incrementalManager),
232 std::move(incFs)),
233 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800234 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800235 mDataLoaderParcel.arguments = "uri";
Songchun Fan3c82a302019-11-29 14:23:45 -0800236 mIncrementalService->onSystemReady();
237 }
238
239 void setUpExistingMountDir(const std::string& rootDir) {
240 const auto dir = rootDir + "/dir1";
241 const auto mountDir = dir + "/mount";
242 const auto backingDir = dir + "/backing_store";
243 const auto storageDir = mountDir + "/st0";
244 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
245 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
246 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
247 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
248 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
249 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
250 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
251 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800252 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
253 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
254 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
255 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
256 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
257 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800258 }
259
260protected:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800261 NiceMock<MockVoldService>* mVold;
262 NiceMock<MockIncFs>* mIncFs;
263 NiceMock<MockIncrementalManager>* mIncrementalManager;
Songchun Fan3c82a302019-11-29 14:23:45 -0800264 std::unique_ptr<IncrementalService> mIncrementalService;
265 TemporaryDir mRootDir;
266 DataLoaderParamsParcel mDataLoaderParcel;
267};
268
Songchun Fan3c82a302019-11-29 14:23:45 -0800269TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
270 mVold->mountIncFsFails();
271 EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
272 TemporaryDir tempDir;
273 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800274 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800275 IncrementalService::CreateOptions::CreateNew);
276 ASSERT_LT(storageId, 0);
277}
278
279TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
280 mVold->mountIncFsInvalidControlParcel();
281 EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
282 TemporaryDir tempDir;
283 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800284 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800285 IncrementalService::CreateOptions::CreateNew);
286 ASSERT_LT(storageId, 0);
287}
288
289TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
290 mVold->mountIncFsSuccess();
291 mIncFs->makeFileFails();
292 EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
293 EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
294 EXPECT_CALL(*mVold, unmountIncFs(_));
295 TemporaryDir tempDir;
296 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800297 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800298 IncrementalService::CreateOptions::CreateNew);
299 ASSERT_LT(storageId, 0);
300}
301
302TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
303 mVold->mountIncFsSuccess();
304 mIncFs->makeFileSuccess();
305 mVold->bindMountFails();
306 EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
307 EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
308 EXPECT_CALL(*mVold, unmountIncFs(_));
309 TemporaryDir tempDir;
310 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800311 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800312 IncrementalService::CreateOptions::CreateNew);
313 ASSERT_LT(storageId, 0);
314}
315
316TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
317 mVold->mountIncFsSuccess();
318 mIncFs->makeFileSuccess();
319 mVold->bindMountSuccess();
320 mIncrementalManager->prepareDataLoaderFails();
321 EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
322 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
323 TemporaryDir tempDir;
324 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800325 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800326 IncrementalService::CreateOptions::CreateNew);
327 ASSERT_LT(storageId, 0);
328}
329
330TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
331 mVold->mountIncFsSuccess();
332 mIncFs->makeFileSuccess();
333 mVold->bindMountSuccess();
334 mIncrementalManager->prepareDataLoaderSuccess();
335 EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
336 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
337 TemporaryDir tempDir;
338 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800339 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800340 IncrementalService::CreateOptions::CreateNew);
341 ASSERT_GE(storageId, 0);
342 mIncrementalService->deleteStorage(storageId);
343}
344
345TEST_F(IncrementalServiceTest, testOnStatusNotReady) {
346 mVold->mountIncFsSuccess();
347 mIncFs->makeFileSuccess();
348 mVold->bindMountSuccess();
349 mIncrementalManager->prepareDataLoaderSuccess();
350 EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
351 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
352 TemporaryDir tempDir;
353 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800354 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800355 IncrementalService::CreateOptions::CreateNew);
356 ASSERT_GE(storageId, 0);
357 mIncrementalManager->setDataLoaderStatusNotReady();
358}
359
360TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) {
361 mVold->mountIncFsSuccess();
362 mIncFs->makeFileSuccess();
363 mVold->bindMountSuccess();
364 mIncrementalManager->prepareDataLoaderSuccess();
365 mIncrementalManager->startDataLoaderSuccess();
366 EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
367 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);
373 mIncrementalManager->setDataLoaderStatusReady();
374 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
375}
376
377TEST_F(IncrementalServiceTest, testMakeDirectory) {
378 mVold->mountIncFsSuccess();
379 mIncFs->makeFileSuccess();
380 mVold->bindMountSuccess();
381 mIncrementalManager->prepareDataLoaderSuccess();
382 mIncrementalManager->startDataLoaderSuccess();
383 TemporaryDir tempDir;
384 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800385 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800386 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800387 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -0800388
Songchun Fan103ba1d2020-02-03 17:32:32 -0800389 std::string tempPath(tempDir.path);
390 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800391 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800392 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800393
Songchun Fan103ba1d2020-02-03 17:32:32 -0800394 // Expecting incfs to call makeDir on a path like:
395 // /data/local/tmp/TemporaryDir-06yixG/data_local_tmp_TemporaryDir-xwdFhT/mount/st_1_0/test
396 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800397 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
398 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800399}
400
401TEST_F(IncrementalServiceTest, testMakeDirectories) {
402 mVold->mountIncFsSuccess();
403 mIncFs->makeFileSuccess();
404 mVold->bindMountSuccess();
405 mIncrementalManager->prepareDataLoaderSuccess();
406 mIncrementalManager->startDataLoaderSuccess();
407 TemporaryDir tempDir;
408 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800409 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800410 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800411 auto first = "first"sv;
412 auto second = "second"sv;
413 auto third = "third"sv;
Songchun Fan103ba1d2020-02-03 17:32:32 -0800414
415 std::string tempPath(tempDir.path);
416 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800417 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800418
Songchun Fan3c82a302019-11-29 14:23:45 -0800419 InSequence seq;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800420 auto parent_path = std::string(first) + "/" + std::string(second);
421 auto dir_path = parent_path + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800422
423 std::string normalized_first_path = mount_dir + "/mount/st_1_0/" + std::string(first);
424 std::string normalized_parent_path = mount_dir + "/mount/st_1_0/" + parent_path;
425 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
426
427 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _))
428 .WillOnce(Return(-ENOENT));
429 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
430 .WillOnce(Return(-ENOENT));
431 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_first_path), _))
432 .WillOnce(Return(0));
433 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
434 .WillOnce(Return(0));
435 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)).WillOnce(Return(0));
436 auto res = mIncrementalService->makeDirs(storageId, normalized_dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800437 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800438}
439} // namespace android::os::incremental