blob: 8713f9d3d8210ee264c3db918382ab33fabe718d [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
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -070025#include <chrono>
Songchun Fan3c82a302019-11-29 14:23:45 -080026#include <future>
27
28#include "IncrementalService.h"
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070029#include "IncrementalServiceValidation.h"
Songchun Fan3c82a302019-11-29 14:23:45 -080030#include "Metadata.pb.h"
31#include "ServiceWrappers.h"
32
33using namespace testing;
34using namespace android::incremental;
35using namespace std::literals;
36using testing::_;
37using testing::Invoke;
38using testing::NiceMock;
39
40#undef LOG_TAG
41#define LOG_TAG "IncrementalServiceTest"
42
43using namespace android::incfs;
44using namespace android::content::pm;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080045using PerUidReadTimeouts = android::os::incremental::PerUidReadTimeouts;
Songchun Fan3c82a302019-11-29 14:23:45 -080046
47namespace android::os::incremental {
48
49class MockVoldService : public VoldServiceWrapper {
50public:
51 MOCK_CONST_METHOD4(mountIncFs,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080052 binder::Status(const std::string& backingPath, const std::string& targetDir,
Songchun Fan3c82a302019-11-29 14:23:45 -080053 int32_t flags,
54 IncrementalFileSystemControlParcel* _aidl_return));
55 MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
56 MOCK_CONST_METHOD2(bindMount,
57 binder::Status(const std::string& sourceDir, const std::string& argetDir));
Songchun Fan374f7652020-08-20 08:40:29 -070058 MOCK_CONST_METHOD2(
59 setIncFsMountOptions,
60 binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
61 bool));
Songchun Fan3c82a302019-11-29 14:23:45 -080062
63 void mountIncFsFails() {
64 ON_CALL(*this, mountIncFs(_, _, _, _))
65 .WillByDefault(
66 Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
67 }
68 void mountIncFsInvalidControlParcel() {
69 ON_CALL(*this, mountIncFs(_, _, _, _))
70 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
71 }
72 void mountIncFsSuccess() {
73 ON_CALL(*this, mountIncFs(_, _, _, _))
74 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
75 }
76 void bindMountFails() {
77 ON_CALL(*this, bindMount(_, _))
78 .WillByDefault(Return(
79 binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
80 }
81 void bindMountSuccess() {
82 ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
83 }
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070084 void setIncFsMountOptionsFails() const {
85 ON_CALL(*this, setIncFsMountOptions(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -070086 .WillByDefault(Return(
87 binder::Status::fromExceptionCode(1, String8("failed to set options"))));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070088 }
89 void setIncFsMountOptionsSuccess() {
90 ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
91 }
Songchun Fan3c82a302019-11-29 14:23:45 -080092 binder::Status getInvalidControlParcel(const std::string& imagePath,
93 const std::string& targetDir, int32_t flags,
94 IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080095 _aidl_return = {};
Songchun Fan3c82a302019-11-29 14:23:45 -080096 return binder::Status::ok();
97 }
98 binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
99 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800100 _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
101 _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
102 _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
Songchun Fan3c82a302019-11-29 14:23:45 -0800103 return binder::Status::ok();
104 }
105
106private:
107 TemporaryFile cmdFile;
108 TemporaryFile logFile;
Songchun Fan3c82a302019-11-29 14:23:45 -0800109};
110
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700111class MockDataLoader : public IDataLoader {
Songchun Fan3c82a302019-11-29 14:23:45 -0800112public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700113 MockDataLoader() {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700114 ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk));
115 ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk));
116 ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk));
117 ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk));
118 ON_CALL(*this, prepareImage(_, _, _))
119 .WillByDefault(Invoke(this, &MockDataLoader::prepareImageOk));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700120 }
Songchun Fan68645c42020-02-27 15:57:35 -0800121 IBinder* onAsBinder() override { return nullptr; }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700122 MOCK_METHOD4(create,
123 binder::Status(int32_t id, const DataLoaderParamsParcel& params,
124 const FileSystemControlParcel& control,
125 const sp<IDataLoaderStatusListener>& listener));
126 MOCK_METHOD1(start, binder::Status(int32_t id));
127 MOCK_METHOD1(stop, binder::Status(int32_t id));
128 MOCK_METHOD1(destroy, binder::Status(int32_t id));
129 MOCK_METHOD3(prepareImage,
130 binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles,
131 const std::vector<std::string>& removedFiles));
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700132
133 void initializeCreateOkNoStatus() {
134 ON_CALL(*this, create(_, _, _, _))
135 .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus));
136 }
137
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700138 binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params,
139 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700140 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700141 createOkNoStatus(id, params, control, listener);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700142 if (mListener) {
143 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED);
144 }
145 return binder::Status::ok();
146 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700147 binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
148 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700149 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700150 mServiceConnector = control.service;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700151 mListener = listener;
152 return binder::Status::ok();
153 }
154 binder::Status startOk(int32_t id) {
155 if (mListener) {
156 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
157 }
158 return binder::Status::ok();
159 }
160 binder::Status stopOk(int32_t id) {
161 if (mListener) {
162 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
163 }
164 return binder::Status::ok();
165 }
166 binder::Status destroyOk(int32_t id) {
167 if (mListener) {
168 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
169 }
170 mListener = nullptr;
171 return binder::Status::ok();
172 }
173 binder::Status prepareImageOk(int32_t id,
174 const ::std::vector<content::pm::InstallationFileParcel>&,
175 const ::std::vector<::std::string>&) {
176 if (mListener) {
177 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
178 }
179 return binder::Status::ok();
180 }
Songchun Fan2570ec02020-10-08 17:22:33 -0700181 binder::Status storageError(int32_t id) {
182 if (mListener) {
183 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_STORAGE_ERROR);
184 }
185 return binder::Status::ok();
186 }
187 binder::Status transportError(int32_t id) {
188 if (mListener) {
189 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_INTEGRITY_ERROR);
190 }
191 return binder::Status::ok();
192 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700193 int32_t setStorageParams(bool enableReadLogs) {
194 int32_t result = -1;
195 EXPECT_NE(mServiceConnector.get(), nullptr);
196 EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
197 return result;
198 }
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700199
200private:
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700201 sp<IIncrementalServiceConnector> mServiceConnector;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700202 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800203};
204
205class MockDataLoaderManager : public DataLoaderManagerWrapper {
206public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700207 MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
208 EXPECT_TRUE(mDataLoaderHolder != nullptr);
209 }
210
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700211 MOCK_CONST_METHOD4(bindToDataLoader,
Songchun Fan68645c42020-02-27 15:57:35 -0800212 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
Songchun Fan3c82a302019-11-29 14:23:45 -0800213 const sp<IDataLoaderStatusListener>& listener,
214 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800215 MOCK_CONST_METHOD2(getDataLoader,
216 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700217 MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800218
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700219 void bindToDataLoaderSuccess() {
220 ON_CALL(*this, bindToDataLoader(_, _, _, _))
221 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700222 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700223 void bindToDataLoaderFails() {
224 ON_CALL(*this, bindToDataLoader(_, _, _, _))
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700225 .WillByDefault(Return(
226 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
227 }
228 void getDataLoaderSuccess() {
229 ON_CALL(*this, getDataLoader(_, _))
230 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
231 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700232 void unbindFromDataLoaderSuccess() {
233 ON_CALL(*this, unbindFromDataLoader(_))
234 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700235 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700236 binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
237 const sp<IDataLoaderStatusListener>& listener,
238 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800239 mId = mountId;
240 mListener = listener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700241 mDataLoader = mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800242 *_aidl_return = true;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700243 if (mListener) {
244 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
245 }
246 return binder::Status::ok();
Songchun Fan3c82a302019-11-29 14:23:45 -0800247 }
Songchun Fan68645c42020-02-27 15:57:35 -0800248 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
249 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800250 return binder::Status::ok();
251 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700252 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800253 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800254 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700255 void setDataLoaderStatusStarted() {
256 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
257 }
258 void setDataLoaderStatusDestroyed() {
259 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
260 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700261 void setDataLoaderStatusUnavailable() {
262 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
263 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700264 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700265 if (mDataLoader) {
266 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
267 return status;
268 }
269 mDataLoader = nullptr;
270 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700271 if (mListener) {
272 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
273 }
274 return binder::Status::ok();
275 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700276
Songchun Fan3c82a302019-11-29 14:23:45 -0800277private:
278 int mId;
279 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700280 sp<IDataLoader> mDataLoader;
281 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800282};
283
284class MockIncFs : public IncFsWrapper {
285public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700286 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
287 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800288 MOCK_CONST_METHOD4(createControl,
289 Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
290 IncFsFd blocksWritten));
Songchun Fan3c82a302019-11-29 14:23:45 -0800291 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800292 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800293 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800294 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700295 MOCK_CONST_METHOD3(makeDirs,
296 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800297 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
298 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
299 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan6944f1e2020-11-06 15:24:24 -0800300 MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
Songchun Fan374f7652020-08-20 08:40:29 -0700301 MOCK_CONST_METHOD2(countFilledBlocks,
302 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
303 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800304 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700305 ErrorCode(const Control& control, std::string_view from,
306 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800307 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700308 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700309 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700310 MOCK_CONST_METHOD3(waitForPendingReads,
311 WaitResult(const Control& control, std::chrono::milliseconds timeout,
312 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800313 MOCK_CONST_METHOD2(setUidReadTimeouts,
314 ErrorCode(const Control& control,
315 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700316
317 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800318
319 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
320 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700321
322 void countFilledBlocksSuccess() {
323 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
324 }
325
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700326 void countFilledBlocksFullyLoaded() {
327 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
328 }
329
Songchun Fan374f7652020-08-20 08:40:29 -0700330 void countFilledBlocksFails() {
331 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
332 }
333
334 void countFilledBlocksEmpty() {
335 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
336 }
337
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700338 void openMountSuccess() {
339 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
340 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700341
342 // 1000ms
343 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700344 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700345 .WillByDefault(
346 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
347 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
348 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
349 return android::incfs::WaitResult::HaveData;
350 }));
351 }
352
353 void waitForPendingReadsTimeout() {
354 ON_CALL(*this, waitForPendingReads(_, _, _))
355 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700356 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700357
358 static constexpr auto kPendingReadsFd = 42;
359 Control openMountForHealth(std::string_view) {
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800360 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700361 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700362
Songchun Fan20d6ef22020-03-03 09:47:15 -0800363 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800364 metadata::Mount m;
365 m.mutable_storage()->set_id(100);
366 m.mutable_loader()->set_package_name("com.test");
367 m.mutable_loader()->set_arguments("com.uri");
368 const auto metadata = m.SerializeAsString();
369 m.mutable_loader()->release_arguments();
370 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800371 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800372 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800373 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800374 metadata::Storage st;
375 st.set_id(100);
376 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800377 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800378 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800379 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800380 metadata::BindPoint bp;
381 std::string destPath = "dest";
382 std::string srcPath = "src";
383 bp.set_storage_id(100);
384 bp.set_allocated_dest_path(&destPath);
385 bp.set_allocated_source_subdir(&srcPath);
386 const auto metadata = bp.SerializeAsString();
387 bp.release_source_subdir();
388 bp.release_dest_path();
389 return std::vector<char>(metadata.begin(), metadata.end());
390 }
391};
392
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700393class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700394public:
395 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700396 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700397 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
398
399 void checkPermissionSuccess() {
400 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
401 }
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -0800402 void checkPermissionNoCrossUsers() {
403 ON_CALL(*this,
404 checkPermission("android.permission.LOADER_USAGE_STATS",
405 "android:loader_usage_stats", _))
406 .WillByDefault(Return(android::incremental::Ok()));
407 ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
408 .WillByDefault(
409 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
410 }
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700411 void checkPermissionFails() {
412 ON_CALL(*this, checkPermission(_, _, _))
413 .WillByDefault(
414 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
415 }
416 void initializeStartWatchingMode() {
417 ON_CALL(*this, startWatchingMode(_, _, _))
418 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
419 }
420 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
421 mStoredCallback = cb;
422 }
423
424 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700425};
426
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700427class MockJniWrapper : public JniWrapper {
428public:
429 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
430
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700431 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700432};
433
434class MockLooperWrapper : public LooperWrapper {
435public:
436 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
437 MOCK_METHOD1(removeFd, int(int));
438 MOCK_METHOD0(wake, void());
439 MOCK_METHOD1(pollAll, int(int));
440
441 MockLooperWrapper() {
442 ON_CALL(*this, addFd(_, _, _, _, _))
443 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
444 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700445 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700446 }
447
448 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
449 mCallback = callback;
450 mCallbackData = data;
451 return 0;
452 }
453
454 int clearCallback(int) {
455 mCallback = nullptr;
456 mCallbackData = nullptr;
457 return 0;
458 }
459
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700460 int wait10Ms(int) {
461 // This is called from a loop in runCmdLooper.
462 // Sleeping for 10ms only to avoid busy looping.
463 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700464 return 0;
465 }
466
467 android::Looper_callbackFunc mCallback = nullptr;
468 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700469};
470
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700471class MockTimedQueueWrapper : public TimedQueueWrapper {
472public:
473 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
474 MOCK_METHOD1(removeJobs, void(MountId));
475 MOCK_METHOD0(stop, void());
476
477 MockTimedQueueWrapper() {
478 ON_CALL(*this, addJob(_, _, _))
479 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
480 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
481 }
482
483 void storeJob(MountId id, Milliseconds after, Job what) {
484 mId = id;
485 mAfter = after;
486 mWhat = std::move(what);
487 }
488
489 void clearJob(MountId id) {
490 if (mId == id) {
491 mAfter = {};
492 mWhat = {};
493 }
494 }
495
496 MountId mId = -1;
497 Milliseconds mAfter;
498 Job mWhat;
499};
500
Songchun Fan374f7652020-08-20 08:40:29 -0700501class MockFsWrapper : public FsWrapper {
502public:
503 MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
504 void hasNoFile() {
505 ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
506 }
507 void hasFiles() {
508 ON_CALL(*this, listFilesRecursive(_))
509 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
510 }
511 std::vector<std::string> fakeFiles(std::string_view directoryPath) {
512 return {"base.apk", "split.apk", "lib/a.so"};
513 }
514};
515
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700516class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
517public:
518 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
519
520 MockStorageHealthListener() {
521 ON_CALL(*this, onHealthStatus(_, _))
522 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
523 }
524
525 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
526 mStorageId = storageId;
527 mStatus = status;
528 return binder::Status::ok();
529 }
530
531 int32_t mStorageId = -1;
532 int32_t mStatus = -1;
533};
534
Songchun Fana7098592020-09-03 11:45:53 -0700535class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
536public:
537 MockStorageLoadingProgressListener() = default;
538 MOCK_METHOD2(onStorageLoadingProgressChanged,
539 binder::Status(int32_t storageId, float progress));
540 MOCK_METHOD0(onAsBinder, IBinder*());
541};
542
Songchun Fan3c82a302019-11-29 14:23:45 -0800543class MockServiceManager : public ServiceManagerWrapper {
544public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800545 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700546 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700547 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700548 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700549 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700550 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700551 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700552 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Songchun Fan374f7652020-08-20 08:40:29 -0700553 std::unique_ptr<MockFsWrapper> fs)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800554 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700555 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700556 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700557 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700558 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700559 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700560 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700561 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Songchun Fan374f7652020-08-20 08:40:29 -0700562 mFs(std::move(fs)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800563 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800564 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
565 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800566 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800567 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700568 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
569 return std::move(mAppOpsManager);
570 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700571 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700572 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700573 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700574 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
575 return std::move(mProgressUpdateJobQueue);
576 }
Songchun Fan374f7652020-08-20 08:40:29 -0700577 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800578
579private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800580 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800581 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800582 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700583 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700584 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700585 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700586 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700587 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700588 std::unique_ptr<MockFsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800589};
590
591// --- IncrementalServiceTest ---
592
Songchun Fan3c82a302019-11-29 14:23:45 -0800593class IncrementalServiceTest : public testing::Test {
594public:
595 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800596 auto vold = std::make_unique<NiceMock<MockVoldService>>();
597 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700598 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
599 mDataLoader = dataLoader.get();
600 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800601 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800602 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
603 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700604 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
605 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700606 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
607 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700608 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
609 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700610 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
611 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700612 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
613 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700614 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
615 mFs = fs.get();
Songchun Fana7098592020-09-03 11:45:53 -0700616 mIncrementalService = std::make_unique<
617 IncrementalService>(MockServiceManager(std::move(vold),
618 std::move(dataloaderManager),
619 std::move(incFs), std::move(appOps),
620 std::move(jni), std::move(looper),
621 std::move(timedQueue),
622 std::move(progressUpdateJobQueue),
623 std::move(fs)),
624 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800625 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800626 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700627 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800628 mIncrementalService->onSystemReady();
Songchun Fan374f7652020-08-20 08:40:29 -0700629 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800630 }
631
632 void setUpExistingMountDir(const std::string& rootDir) {
633 const auto dir = rootDir + "/dir1";
634 const auto mountDir = dir + "/mount";
635 const auto backingDir = dir + "/backing_store";
636 const auto storageDir = mountDir + "/st0";
637 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
638 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
639 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
640 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
641 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
642 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
643 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
644 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800645 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
646 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
647 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
648 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
649 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
650 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800651 }
652
Songchun Fan374f7652020-08-20 08:40:29 -0700653 void setupSuccess() {
654 mVold->mountIncFsSuccess();
655 mIncFs->makeFileSuccess();
656 mVold->bindMountSuccess();
657 mDataLoaderManager->bindToDataLoaderSuccess();
658 mDataLoaderManager->getDataLoaderSuccess();
659 }
660
Songchun Fan3c82a302019-11-29 14:23:45 -0800661protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700662 NiceMock<MockVoldService>* mVold = nullptr;
663 NiceMock<MockIncFs>* mIncFs = nullptr;
664 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
665 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
666 NiceMock<MockJniWrapper>* mJni = nullptr;
667 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700668 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700669 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700670 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700671 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800672 std::unique_ptr<IncrementalService> mIncrementalService;
673 TemporaryDir mRootDir;
674 DataLoaderParamsParcel mDataLoaderParcel;
675};
676
Songchun Fan3c82a302019-11-29 14:23:45 -0800677TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
678 mVold->mountIncFsFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700679 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800680 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800681 int storageId =
682 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
683 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800684 ASSERT_LT(storageId, 0);
685}
686
687TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
688 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700689 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
690 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800691 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800692 int storageId =
693 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
694 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800695 ASSERT_LT(storageId, 0);
696}
697
698TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
699 mVold->mountIncFsSuccess();
700 mIncFs->makeFileFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700701 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
702 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800703 EXPECT_CALL(*mVold, unmountIncFs(_));
704 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800705 int storageId =
706 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
707 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800708 ASSERT_LT(storageId, 0);
709}
710
711TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
712 mVold->mountIncFsSuccess();
713 mIncFs->makeFileSuccess();
714 mVold->bindMountFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700715 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
716 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800717 EXPECT_CALL(*mVold, unmountIncFs(_));
718 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800719 int storageId =
720 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
721 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800722 ASSERT_LT(storageId, 0);
723}
724
725TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
726 mVold->mountIncFsSuccess();
727 mIncFs->makeFileSuccess();
728 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700729 mDataLoaderManager->bindToDataLoaderFails();
730 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
731 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700732 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
733 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
734 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800735 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
736 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800737 int storageId =
738 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
739 IncrementalService::CreateOptions::CreateNew);
740 ASSERT_GE(storageId, 0);
741 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800742}
743
744TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700745 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800746 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700747 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800748 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
749 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800750 int storageId =
751 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
752 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800753 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800754 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800755 mIncrementalService->deleteStorage(storageId);
756}
757
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700758TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700759 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
760 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700761 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800762 EXPECT_CALL(*mDataLoader, start(_)).Times(2);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700763 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800764 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
765 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800766 int storageId =
767 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
768 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800769 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800770 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700771 // Simulated crash/other connection breakage.
772 mDataLoaderManager->setDataLoaderStatusDestroyed();
773}
774
775TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700776 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700777 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
778 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700779 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
780 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
781 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
782 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
783 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800784 int storageId =
785 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
786 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700787 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800788 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
789 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700790 mDataLoaderManager->setDataLoaderStatusCreated();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700791 mDataLoaderManager->setDataLoaderStatusStarted();
792}
793
794TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700795 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700796 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
797 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800798 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700799 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
800 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
801 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
802 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800803 int storageId =
804 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
805 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700806 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800807 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
808 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700809 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800810}
811
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700812TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700813 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700814 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
815 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
816 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
817 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
818 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
819 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
820 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800821 int storageId =
822 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
823 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700824 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800825 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
826 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700827 mDataLoaderManager->setDataLoaderStatusUnavailable();
828}
829
830TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700831 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700832 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700833 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -0700834
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700835 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700836 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700837 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
838 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700839 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700840 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
841 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
842 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
843 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800844 int storageId =
845 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
846 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700847 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800848 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
849 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700850 mDataLoaderManager->setDataLoaderStatusUnavailable();
851 ASSERT_NE(nullptr, mLooper->mCallback);
852 ASSERT_NE(nullptr, mLooper->mCallbackData);
853 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
854}
855
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700856TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700857 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700858
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700859 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
860 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
861 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
862 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
863 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
864 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
865 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
866 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
867 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
868
869 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
870 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
871 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
872 .Times(2);
873 EXPECT_CALL(*listenerMock,
874 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
875 .Times(1);
876 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
877 .Times(1);
878 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
879 .Times(2);
880
881 StorageHealthCheckParams params;
882 params.blockedTimeoutMs = 10000;
883 params.unhealthyTimeoutMs = 20000;
884 params.unhealthyMonitoringMs = 30000;
885
886 using MS = std::chrono::milliseconds;
887 using MCS = std::chrono::microseconds;
888
889 const auto blockedTimeout = MS(params.blockedTimeoutMs);
890 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
891 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
892
893 const uint64_t kFirstTimestampUs = 1000000000ll;
894 const uint64_t kBlockedTimestampUs =
895 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
896 const uint64_t kUnhealthyTimestampUs =
897 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
898
899 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800900 int storageId =
901 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
902 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700903 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800904 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
905 std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700906
907 // Healthy state, registered for pending reads.
908 ASSERT_NE(nullptr, mLooper->mCallback);
909 ASSERT_NE(nullptr, mLooper->mCallbackData);
910 ASSERT_EQ(storageId, listener->mStorageId);
911 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
912
913 // Looper/epoll callback.
914 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
915 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
916
917 // Unregister from pending reads and wait.
918 ASSERT_EQ(nullptr, mLooper->mCallback);
919 ASSERT_EQ(nullptr, mLooper->mCallbackData);
920 ASSERT_EQ(storageId, listener->mStorageId);
921 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
922 // Timed callback present.
923 ASSERT_EQ(storageId, mTimedQueue->mId);
924 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
925 auto timedCallback = mTimedQueue->mWhat;
926 mTimedQueue->clearJob(storageId);
927
928 // Timed job callback for blocked.
929 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
930 timedCallback();
931
932 // Still not registered, and blocked.
933 ASSERT_EQ(nullptr, mLooper->mCallback);
934 ASSERT_EQ(nullptr, mLooper->mCallbackData);
935 ASSERT_EQ(storageId, listener->mStorageId);
936 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
937 // Timed callback present.
938 ASSERT_EQ(storageId, mTimedQueue->mId);
939 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
940 timedCallback = mTimedQueue->mWhat;
941 mTimedQueue->clearJob(storageId);
942
943 // Timed job callback for unhealthy.
944 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
945 timedCallback();
946
947 // Still not registered, and blocked.
948 ASSERT_EQ(nullptr, mLooper->mCallback);
949 ASSERT_EQ(nullptr, mLooper->mCallbackData);
950 ASSERT_EQ(storageId, listener->mStorageId);
951 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
952 // Timed callback present.
953 ASSERT_EQ(storageId, mTimedQueue->mId);
954 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
955 timedCallback = mTimedQueue->mWhat;
956 mTimedQueue->clearJob(storageId);
957
958 // One more unhealthy.
959 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
960 timedCallback();
961
962 // Still not registered, and blocked.
963 ASSERT_EQ(nullptr, mLooper->mCallback);
964 ASSERT_EQ(nullptr, mLooper->mCallbackData);
965 ASSERT_EQ(storageId, listener->mStorageId);
966 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
967 // Timed callback present.
968 ASSERT_EQ(storageId, mTimedQueue->mId);
969 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
970 timedCallback = mTimedQueue->mWhat;
971 mTimedQueue->clearJob(storageId);
972
973 // And now healthy.
974 mIncFs->waitForPendingReadsTimeout();
975 timedCallback();
976
977 // Healthy state, registered for pending reads.
978 ASSERT_NE(nullptr, mLooper->mCallback);
979 ASSERT_NE(nullptr, mLooper->mCallbackData);
980 ASSERT_EQ(storageId, listener->mStorageId);
981 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
982}
983
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700984TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700985 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700986 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700987
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700988 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700989 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700990 // We are calling setIncFsMountOptions(true).
991 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
992 // After setIncFsMountOptions succeeded expecting to start watching.
993 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
994 // Not expecting callback removal.
995 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700996 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800997 int storageId =
998 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
999 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001000 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001001 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1002 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001003 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001004}
1005
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001006TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001007 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001008 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001009
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001010 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1011 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1012 // Enabling and then disabling readlogs.
1013 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1014 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1015 // After setIncFsMountOptions succeeded expecting to start watching.
1016 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1017 // Not expecting callback removal.
1018 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1019 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001020 int storageId =
1021 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1022 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001023 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001024 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1025 {}, {}));
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001026 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1027 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001028 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001029 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1030}
1031
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001032TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001033 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001034 mAppOpsManager->checkPermissionSuccess();
1035 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001036
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001037 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001038 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1039 // We are calling setIncFsMountOptions(true).
1040 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1041 // setIncFsMountOptions(false) is called on the callback.
1042 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1043 // After setIncFsMountOptions succeeded expecting to start watching.
1044 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1045 // After callback is called, disable read logs and remove callback.
1046 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1047 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001048 int storageId =
1049 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1050 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001051 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001052 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1053 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001054 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001055 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1056 mAppOpsManager->mStoredCallback->opChanged(0, {});
1057}
1058
1059TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001060 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001061
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001062 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001063 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1064 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1065 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1066 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1067 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1068 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001069 int storageId =
1070 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1071 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001072 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001073 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1074 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001075 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001076}
1077
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001078TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
1079 mAppOpsManager->checkPermissionNoCrossUsers();
1080
1081 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1082 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1083 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1084 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1085 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1086 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1087 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001088 int storageId =
1089 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1090 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001091 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001092 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1093 {}, {}));
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001094 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1095}
1096
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001097TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001098 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001099 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001100
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001101 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001102 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001103 // We are calling setIncFsMountOptions.
1104 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1105 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1106 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1107 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001108 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001109 int storageId =
1110 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1111 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001112 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001113 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1114 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001115 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001116}
1117
Songchun Fan3c82a302019-11-29 14:23:45 -08001118TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001119 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001120 int storageId =
1121 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1122 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001123 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001124
Songchun Fan103ba1d2020-02-03 17:32:32 -08001125 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001126 // <root>/*/mount/<storage>/test
1127 EXPECT_CALL(*mIncFs,
1128 makeDir(_, Truly([&](std::string_view arg) {
1129 return arg.starts_with(mRootDir.path) &&
1130 arg.ends_with("/mount/st_1_0/" + dir_path);
1131 }),
1132 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001133 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1134 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001135}
1136
1137TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001138 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001139 int storageId =
1140 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1141 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001142 auto first = "first"sv;
1143 auto second = "second"sv;
1144 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001145 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001146
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001147 EXPECT_CALL(*mIncFs,
1148 makeDirs(_, Truly([&](std::string_view arg) {
1149 return arg.starts_with(mRootDir.path) &&
1150 arg.ends_with("/mount/st_1_0/" + dir_path);
1151 }),
1152 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001153 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001154 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001155}
Songchun Fan374f7652020-08-20 08:40:29 -07001156
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001157TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1158 mIncFs->countFilledBlocksFails();
1159 mFs->hasNoFile();
1160
1161 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001162 int storageId =
1163 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1164 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001165 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1166}
1167
1168TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1169 mIncFs->countFilledBlocksFails();
1170 mFs->hasFiles();
1171
1172 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001173 int storageId =
1174 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1175 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001176 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1177 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1178}
1179
1180TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1181 mIncFs->countFilledBlocksEmpty();
1182 mFs->hasFiles();
1183
1184 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001185 int storageId =
1186 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1187 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001188 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1189 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1190}
1191
1192TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1193 mIncFs->countFilledBlocksFullyLoaded();
1194 mFs->hasFiles();
1195
1196 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001197 int storageId =
1198 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1199 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001200 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1201 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1202}
1203
Songchun Fan425862f2020-08-25 13:12:16 -07001204TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001205 mIncFs->countFilledBlocksSuccess();
1206 mFs->hasNoFile();
1207
1208 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001209 int storageId =
1210 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1211 IncrementalService::CreateOptions::CreateNew);
1212 ASSERT_EQ(1,
1213 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1214 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001215}
1216
1217TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1218 mIncFs->countFilledBlocksFails();
1219 mFs->hasFiles();
1220
1221 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001222 int storageId =
1223 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1224 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001225 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001226 ASSERT_EQ(-1,
1227 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1228 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001229}
1230
Songchun Fan425862f2020-08-25 13:12:16 -07001231TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001232 mIncFs->countFilledBlocksEmpty();
1233 mFs->hasFiles();
1234
1235 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001236 int storageId =
1237 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1238 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001239 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001240 ASSERT_EQ(1,
1241 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1242 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001243}
1244
1245TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1246 mIncFs->countFilledBlocksSuccess();
1247 mFs->hasFiles();
1248
1249 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001250 int storageId =
1251 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1252 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001253 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001254 ASSERT_EQ(0.5,
1255 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1256 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001257}
Songchun Fana7098592020-09-03 11:45:53 -07001258
1259TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1260 mIncFs->countFilledBlocksSuccess();
1261 mFs->hasFiles();
1262
1263 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001264 int storageId =
1265 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1266 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001267 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1268 new NiceMock<MockStorageLoadingProgressListener>};
1269 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1270 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1271 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1272 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1273 // Timed callback present.
1274 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1275 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1276 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1277 timedCallback();
1278 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1279 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1280 mIncrementalService->unregisterLoadingProgressListener(storageId);
1281 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1282}
1283
1284TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1285 mIncFs->countFilledBlocksFails();
1286 mFs->hasFiles();
1287
1288 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001289 int storageId =
1290 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1291 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001292 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1293 new NiceMock<MockStorageLoadingProgressListener>};
1294 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1295 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1296 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1297}
Songchun Fan2570ec02020-10-08 17:22:33 -07001298
1299TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1300 mIncFs->openMountSuccess();
1301 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1302 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1303 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1304
1305 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001306 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001307 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1308 IncrementalService::CreateOptions::CreateNew);
Songchun Fan2570ec02020-10-08 17:22:33 -07001309 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001310 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener,
1311 {});
1312
Songchun Fan2570ec02020-10-08 17:22:33 -07001313 StorageHealthCheckParams newParams;
1314 newParams.blockedTimeoutMs = 10000;
1315 newParams.unhealthyTimeoutMs = 20000;
1316 newParams.unhealthyMonitoringMs = 30000;
1317 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1318 newListener));
1319
1320 using MS = std::chrono::milliseconds;
1321 using MCS = std::chrono::microseconds;
1322
1323 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1324 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1325
1326 const uint64_t kFirstTimestampUs = 1000000000ll;
1327 const uint64_t kBlockedTimestampUs =
1328 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1329 const uint64_t kUnhealthyTimestampUs =
1330 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1331
1332 // test that old listener was not called
1333 EXPECT_CALL(*listener.get(),
1334 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1335 .Times(0);
1336 EXPECT_CALL(*newListenerMock,
1337 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1338 .Times(1);
1339 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1340 .Times(1);
1341 EXPECT_CALL(*newListenerMock,
1342 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1343 .Times(1);
1344 EXPECT_CALL(*newListenerMock,
1345 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1346 .Times(1);
1347 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1348 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1349
1350 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1351 ASSERT_EQ(storageId, newListener->mStorageId);
1352
1353 auto timedCallback = mTimedQueue->mWhat;
1354 mTimedQueue->clearJob(storageId);
1355
1356 // test when health status is blocked with transport error
1357 mDataLoader->transportError(storageId);
1358 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1359 timedCallback();
1360 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1361 timedCallback = mTimedQueue->mWhat;
1362 mTimedQueue->clearJob(storageId);
1363
1364 // test when health status is blocked with storage error
1365 mDataLoader->storageError(storageId);
1366 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1367 timedCallback();
1368 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1369 timedCallback = mTimedQueue->mWhat;
1370 mTimedQueue->clearJob(storageId);
1371
1372 // test when health status is unhealthy with transport error
1373 mDataLoader->transportError(storageId);
1374 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1375 timedCallback();
1376 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1377 mTimedQueue->clearJob(storageId);
1378}
1379
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001380static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1381 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1382 std::vector<PerUidReadTimeouts> result;
1383 for (auto&& tuple : tuples) {
1384 result.emplace_back();
1385 auto& timeouts = result.back();
1386 timeouts.uid = std::get<0>(tuple);
1387 timeouts.minTimeUs = std::get<1>(tuple);
1388 timeouts.minPendingTimeUs = std::get<2>(tuple);
1389 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1390 }
1391 return result;
1392}
1393
1394static ErrorCode checkPerUidTimeouts(const Control& control,
1395 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1396 std::vector<PerUidReadTimeouts> expected =
1397 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1398 EXPECT_EQ(expected, perUidReadTimeouts);
1399 return 0;
1400}
1401
1402static ErrorCode checkPerUidTimeoutsEmpty(
1403 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1404 EXPECT_EQ(0u, perUidReadTimeouts.size());
1405 return 0;
1406}
1407
1408TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
1409 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
1410 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1411 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001412 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001413 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1414 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
1415 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1416 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1417 TemporaryDir tempDir;
1418 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001419 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1420 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001421 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001422 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1423 createPerUidTimeouts(
1424 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001425}
1426
1427TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1428 mVold->setIncFsMountOptionsSuccess();
1429 mAppOpsManager->checkPermissionSuccess();
1430 mFs->hasFiles();
1431
1432 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1433 // First call.
1434 .WillOnce(Invoke(&checkPerUidTimeouts))
1435 // Fully loaded and no readlogs.
1436 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1437 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1438
1439 // Empty storage.
1440 mIncFs->countFilledBlocksEmpty();
1441
1442 TemporaryDir tempDir;
1443 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001444 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1445 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001446 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001447 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1448 createPerUidTimeouts(
1449 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001450
1451 {
1452 // Timed callback present -> 0 progress.
1453 ASSERT_EQ(storageId, mTimedQueue->mId);
1454 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1455 const auto timedCallback = mTimedQueue->mWhat;
1456 mTimedQueue->clearJob(storageId);
1457
1458 // Still loading.
1459 mIncFs->countFilledBlocksSuccess();
1460
1461 // Call it again.
1462 timedCallback();
1463 }
1464
1465 {
1466 // Still present -> 0.5 progress.
1467 ASSERT_EQ(storageId, mTimedQueue->mId);
1468 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1469 const auto timedCallback = mTimedQueue->mWhat;
1470 mTimedQueue->clearJob(storageId);
1471
1472 // Fully loaded but readlogs collection enabled.
1473 mIncFs->countFilledBlocksFullyLoaded();
1474 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1475
1476 // Call it again.
1477 timedCallback();
1478 }
1479
1480 {
1481 // Still present -> fully loaded + readlogs.
1482 ASSERT_EQ(storageId, mTimedQueue->mId);
1483 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1484 const auto timedCallback = mTimedQueue->mWhat;
1485 mTimedQueue->clearJob(storageId);
1486
1487 // Now disable readlogs.
1488 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1489
1490 // Call it again.
1491 timedCallback();
1492 }
1493
1494 // No callbacks anymore -> fully loaded and no readlogs.
1495 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1496}
1497
Songchun Fan3c82a302019-11-29 14:23:45 -08001498} // namespace android::os::incremental