blob: 117dca8c37b3a768d6958f86d841cf02e85a926f [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
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700134 void initializeDataLoaderSuccess() {
135 ON_CALL(*this, initializeDataLoader(_, _, _, _, _))
136 .WillByDefault(Invoke(this, &MockDataLoaderManager::initializeDataLoaderOk));
137 }
138 void initializeDataLoaderFails() {
139 ON_CALL(*this, initializeDataLoader(_, _, _, _, _))
140 .WillByDefault(Return(
141 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
142 }
143 void getDataLoaderSuccess() {
144 ON_CALL(*this, getDataLoader(_, _))
145 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
146 }
147 void destroyDataLoaderOk() {
148 ON_CALL(*this, destroyDataLoader(_))
149 .WillByDefault(Invoke(this, &MockDataLoaderManager::setDataLoaderStatusDestroyed));
150 }
Songchun Fan68645c42020-02-27 15:57:35 -0800151 binder::Status initializeDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
152 const FileSystemControlParcel& control,
153 const sp<IDataLoaderStatusListener>& listener,
154 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800155 mId = mountId;
156 mListener = listener;
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700157 mServiceConnector = control.service;
Songchun Fan3c82a302019-11-29 14:23:45 -0800158 *_aidl_return = true;
159 return binder::Status::ok();
160 }
Songchun Fan68645c42020-02-27 15:57:35 -0800161 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
162 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800163 return binder::Status::ok();
164 }
Songchun Fan3c82a302019-11-29 14:23:45 -0800165 void setDataLoaderStatusNotReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800166 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800167 }
168 void setDataLoaderStatusReady() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800169 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800170 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700171 binder::Status setDataLoaderStatusDestroyed(int32_t id) {
172 if (mListener) {
173 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
174 }
175 return binder::Status::ok();
176 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700177 int32_t setStorageParams(bool enableReadLogs) {
178 int32_t result = -1;
179 EXPECT_NE(mServiceConnector.get(), nullptr);
180 EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
181 return result;
182 }
183
Songchun Fan3c82a302019-11-29 14:23:45 -0800184private:
185 int mId;
186 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700187 sp<IIncrementalServiceConnector> mServiceConnector;
Songchun Fan68645c42020-02-27 15:57:35 -0800188 sp<IDataLoader> mDataLoader = sp<IDataLoader>(new FakeDataLoader());
Songchun Fan3c82a302019-11-29 14:23:45 -0800189};
190
191class MockIncFs : public IncFsWrapper {
192public:
Songchun Fan20d6ef22020-03-03 09:47:15 -0800193 MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
Songchun Fan3c82a302019-11-29 14:23:45 -0800194 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800195 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800196 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800197 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
198 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
199 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
200 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800201 MOCK_CONST_METHOD3(link,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800202 ErrorCode(const Control& control, std::string_view from, std::string_view to));
203 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Yurii Zubrytskyie82cdd72020-04-01 12:19:26 -0700204 MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
Songchun Fan9b753082020-02-26 13:08:06 -0800205 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks));
Songchun Fan3c82a302019-11-29 14:23:45 -0800206
207 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
208 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800209 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800210 metadata::Mount m;
211 m.mutable_storage()->set_id(100);
212 m.mutable_loader()->set_package_name("com.test");
213 m.mutable_loader()->set_arguments("com.uri");
214 const auto metadata = m.SerializeAsString();
215 m.mutable_loader()->release_arguments();
216 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800217 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800218 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800219 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800220 metadata::Storage st;
221 st.set_id(100);
222 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800223 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800224 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800225 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800226 metadata::BindPoint bp;
227 std::string destPath = "dest";
228 std::string srcPath = "src";
229 bp.set_storage_id(100);
230 bp.set_allocated_dest_path(&destPath);
231 bp.set_allocated_source_subdir(&srcPath);
232 const auto metadata = bp.SerializeAsString();
233 bp.release_source_subdir();
234 bp.release_dest_path();
235 return std::vector<char>(metadata.begin(), metadata.end());
236 }
237};
238
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700239class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700240public:
241 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700242 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700243 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
244
245 void checkPermissionSuccess() {
246 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
247 }
248 void checkPermissionFails() {
249 ON_CALL(*this, checkPermission(_, _, _))
250 .WillByDefault(
251 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
252 }
253 void initializeStartWatchingMode() {
254 ON_CALL(*this, startWatchingMode(_, _, _))
255 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
256 }
257 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
258 mStoredCallback = cb;
259 }
260
261 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700262};
263
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700264class MockJniWrapper : public JniWrapper {
265public:
266 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
267
268 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(1); }
269};
270
Songchun Fan3c82a302019-11-29 14:23:45 -0800271class MockServiceManager : public ServiceManagerWrapper {
272public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800273 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700274 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700275 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700276 std::unique_ptr<MockAppOpsManager> appOpsManager,
277 std::unique_ptr<MockJniWrapper> jni)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800278 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700279 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700280 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700281 mAppOpsManager(std::move(appOpsManager)),
282 mJni(std::move(jni)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800283 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800284 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
285 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800286 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800287 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700288 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final { return std::move(mAppOpsManager); }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700289 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800290
291private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800292 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800293 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800294 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700295 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700296 std::unique_ptr<MockJniWrapper> mJni;
Songchun Fan3c82a302019-11-29 14:23:45 -0800297};
298
299// --- IncrementalServiceTest ---
300
Songchun Fan3c82a302019-11-29 14:23:45 -0800301class IncrementalServiceTest : public testing::Test {
302public:
303 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800304 auto vold = std::make_unique<NiceMock<MockVoldService>>();
305 mVold = vold.get();
Songchun Fan68645c42020-02-27 15:57:35 -0800306 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>();
307 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800308 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
309 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700310 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
311 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700312 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
313 mJni = jni.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800314 mIncrementalService =
315 std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700316 std::move(
317 dataloaderManager),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700318 std::move(incFs),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700319 std::move(appOps),
320 std::move(jni)),
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800321 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800322 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800323 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700324 mDataLoaderManager->destroyDataLoaderOk();
Songchun Fan3c82a302019-11-29 14:23:45 -0800325 mIncrementalService->onSystemReady();
326 }
327
328 void setUpExistingMountDir(const std::string& rootDir) {
329 const auto dir = rootDir + "/dir1";
330 const auto mountDir = dir + "/mount";
331 const auto backingDir = dir + "/backing_store";
332 const auto storageDir = mountDir + "/st0";
333 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
334 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
335 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
336 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
337 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
338 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
339 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
340 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800341 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
342 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
343 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
344 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
345 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
346 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800347 }
348
349protected:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800350 NiceMock<MockVoldService>* mVold;
351 NiceMock<MockIncFs>* mIncFs;
Songchun Fan68645c42020-02-27 15:57:35 -0800352 NiceMock<MockDataLoaderManager>* mDataLoaderManager;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700353 NiceMock<MockAppOpsManager>* mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700354 NiceMock<MockJniWrapper>* mJni;
Songchun Fan3c82a302019-11-29 14:23:45 -0800355 std::unique_ptr<IncrementalService> mIncrementalService;
356 TemporaryDir mRootDir;
357 DataLoaderParamsParcel mDataLoaderParcel;
358};
359
Songchun Fan3c82a302019-11-29 14:23:45 -0800360TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
361 mVold->mountIncFsFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800362 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800363 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_LT(storageId, 0);
368}
369
370TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
371 mVold->mountIncFsInvalidControlParcel();
Songchun Fan68645c42020-02-27 15:57:35 -0800372 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700373 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800374 TemporaryDir tempDir;
375 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800376 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800377 IncrementalService::CreateOptions::CreateNew);
378 ASSERT_LT(storageId, 0);
379}
380
381TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
382 mVold->mountIncFsSuccess();
383 mIncFs->makeFileFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800384 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700385 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800386 EXPECT_CALL(*mVold, unmountIncFs(_));
387 TemporaryDir tempDir;
388 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800389 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800390 IncrementalService::CreateOptions::CreateNew);
391 ASSERT_LT(storageId, 0);
392}
393
394TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
395 mVold->mountIncFsSuccess();
396 mIncFs->makeFileSuccess();
397 mVold->bindMountFails();
Songchun Fan68645c42020-02-27 15:57:35 -0800398 EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700399 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800400 EXPECT_CALL(*mVold, unmountIncFs(_));
401 TemporaryDir tempDir;
402 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800403 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800404 IncrementalService::CreateOptions::CreateNew);
405 ASSERT_LT(storageId, 0);
406}
407
408TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
409 mVold->mountIncFsSuccess();
410 mIncFs->makeFileSuccess();
411 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800412 mDataLoaderManager->initializeDataLoaderFails();
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700413 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800414 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
415 TemporaryDir tempDir;
416 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800417 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800418 IncrementalService::CreateOptions::CreateNew);
419 ASSERT_LT(storageId, 0);
420}
421
422TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
423 mVold->mountIncFsSuccess();
424 mIncFs->makeFileSuccess();
425 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800426 mDataLoaderManager->initializeDataLoaderSuccess();
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700427 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800428 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
429 TemporaryDir tempDir;
430 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800431 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800432 IncrementalService::CreateOptions::CreateNew);
433 ASSERT_GE(storageId, 0);
434 mIncrementalService->deleteStorage(storageId);
435}
436
437TEST_F(IncrementalServiceTest, testOnStatusNotReady) {
438 mVold->mountIncFsSuccess();
439 mIncFs->makeFileSuccess();
440 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800441 mDataLoaderManager->initializeDataLoaderSuccess();
442 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800443 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
444 TemporaryDir tempDir;
445 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800446 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800447 IncrementalService::CreateOptions::CreateNew);
448 ASSERT_GE(storageId, 0);
Songchun Fan68645c42020-02-27 15:57:35 -0800449 mDataLoaderManager->setDataLoaderStatusNotReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800450}
451
452TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) {
453 mVold->mountIncFsSuccess();
454 mIncFs->makeFileSuccess();
455 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800456 mDataLoaderManager->initializeDataLoaderSuccess();
457 mDataLoaderManager->getDataLoaderSuccess();
458 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
Songchun Fan3c82a302019-11-29 14:23:45 -0800459 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
460 TemporaryDir tempDir;
461 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800462 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800463 IncrementalService::CreateOptions::CreateNew);
464 ASSERT_GE(storageId, 0);
Songchun Fan68645c42020-02-27 15:57:35 -0800465 mDataLoaderManager->setDataLoaderStatusReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800466 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
467}
468
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700469TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
470 mVold->mountIncFsSuccess();
471 mIncFs->makeFileSuccess();
472 mVold->bindMountSuccess();
473 mVold->setIncFsMountOptionsSuccess();
474 mDataLoaderManager->initializeDataLoaderSuccess();
475 mDataLoaderManager->getDataLoaderSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700476 mAppOpsManager->checkPermissionSuccess();
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700477 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
478 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700479 // We are calling setIncFsMountOptions(true).
480 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
481 // After setIncFsMountOptions succeeded expecting to start watching.
482 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
483 // Not expecting callback removal.
484 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700485 TemporaryDir tempDir;
486 int storageId =
487 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
488 IncrementalService::CreateOptions::CreateNew);
489 ASSERT_GE(storageId, 0);
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700490 ASSERT_GE(mDataLoaderManager->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700491}
492
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700493TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
494 mVold->mountIncFsSuccess();
495 mIncFs->makeFileSuccess();
496 mVold->bindMountSuccess();
497 mVold->setIncFsMountOptionsSuccess();
498 mDataLoaderManager->initializeDataLoaderSuccess();
499 mDataLoaderManager->getDataLoaderSuccess();
500 mAppOpsManager->checkPermissionSuccess();
501 mAppOpsManager->initializeStartWatchingMode();
502 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
503 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
504 // We are calling setIncFsMountOptions(true).
505 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
506 // setIncFsMountOptions(false) is called on the callback.
507 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
508 // After setIncFsMountOptions succeeded expecting to start watching.
509 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
510 // After callback is called, disable read logs and remove callback.
511 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
512 TemporaryDir tempDir;
513 int storageId =
514 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
515 IncrementalService::CreateOptions::CreateNew);
516 ASSERT_GE(storageId, 0);
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700517 ASSERT_GE(mDataLoaderManager->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700518 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
519 mAppOpsManager->mStoredCallback->opChanged(0, {});
520}
521
522TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
523 mVold->mountIncFsSuccess();
524 mIncFs->makeFileSuccess();
525 mVold->bindMountSuccess();
526 mDataLoaderManager->initializeDataLoaderSuccess();
527 mDataLoaderManager->getDataLoaderSuccess();
528 mAppOpsManager->checkPermissionFails();
529 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
530 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
531 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
532 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
533 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
534 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
535 TemporaryDir tempDir;
536 int storageId =
537 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
538 IncrementalService::CreateOptions::CreateNew);
539 ASSERT_GE(storageId, 0);
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700540 ASSERT_LT(mDataLoaderManager->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700541}
542
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700543TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
544 mVold->mountIncFsSuccess();
545 mIncFs->makeFileSuccess();
546 mVold->bindMountSuccess();
547 mVold->setIncFsMountOptionsFails();
548 mDataLoaderManager->initializeDataLoaderSuccess();
549 mDataLoaderManager->getDataLoaderSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700550 mAppOpsManager->checkPermissionSuccess();
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700551 EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
552 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700553 // We are calling setIncFsMountOptions.
554 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
555 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
556 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
557 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700558 TemporaryDir tempDir;
559 int storageId =
560 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
561 IncrementalService::CreateOptions::CreateNew);
562 ASSERT_GE(storageId, 0);
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700563 ASSERT_LT(mDataLoaderManager->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700564}
565
Songchun Fan3c82a302019-11-29 14:23:45 -0800566TEST_F(IncrementalServiceTest, testMakeDirectory) {
567 mVold->mountIncFsSuccess();
568 mIncFs->makeFileSuccess();
569 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800570 mDataLoaderManager->initializeDataLoaderSuccess();
571 mDataLoaderManager->getDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800572 TemporaryDir tempDir;
573 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800574 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800575 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800576 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -0800577
Songchun Fan103ba1d2020-02-03 17:32:32 -0800578 std::string tempPath(tempDir.path);
579 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800580 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800581 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800582
Songchun Fan103ba1d2020-02-03 17:32:32 -0800583 // Expecting incfs to call makeDir on a path like:
584 // /data/local/tmp/TemporaryDir-06yixG/data_local_tmp_TemporaryDir-xwdFhT/mount/st_1_0/test
585 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800586 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
587 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800588}
589
590TEST_F(IncrementalServiceTest, testMakeDirectories) {
591 mVold->mountIncFsSuccess();
592 mIncFs->makeFileSuccess();
593 mVold->bindMountSuccess();
Songchun Fan68645c42020-02-27 15:57:35 -0800594 mDataLoaderManager->initializeDataLoaderSuccess();
595 mDataLoaderManager->getDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800596 TemporaryDir tempDir;
597 int storageId =
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800598 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
Songchun Fan3c82a302019-11-29 14:23:45 -0800599 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800600 auto first = "first"sv;
601 auto second = "second"sv;
602 auto third = "third"sv;
Songchun Fan103ba1d2020-02-03 17:32:32 -0800603
604 std::string tempPath(tempDir.path);
605 std::replace(tempPath.begin(), tempPath.end(), '/', '_');
Songchun Fan1124fd32020-02-10 12:49:41 -0800606 std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800607
Songchun Fan3c82a302019-11-29 14:23:45 -0800608 InSequence seq;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800609 auto parent_path = std::string(first) + "/" + std::string(second);
610 auto dir_path = parent_path + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -0800611
612 std::string normalized_first_path = mount_dir + "/mount/st_1_0/" + std::string(first);
613 std::string normalized_parent_path = mount_dir + "/mount/st_1_0/" + parent_path;
614 std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
615
616 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _))
617 .WillOnce(Return(-ENOENT));
618 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
619 .WillOnce(Return(-ENOENT));
620 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_first_path), _))
621 .WillOnce(Return(0));
622 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
623 .WillOnce(Return(0));
624 EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)).WillOnce(Return(0));
625 auto res = mIncrementalService->makeDirs(storageId, normalized_dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800626 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800627}
628} // namespace android::os::incremental