blob: 154a55fd8bd1346e4db1fd07133b89d6133cb22b [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 Buynytskyyb19ee3e2021-02-06 20:31:43 -0800211 MOCK_CONST_METHOD5(bindToDataLoader,
Songchun Fan68645c42020-02-27 15:57:35 -0800212 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800213 int bindDelayMs,
Songchun Fan3c82a302019-11-29 14:23:45 -0800214 const sp<IDataLoaderStatusListener>& listener,
215 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800216 MOCK_CONST_METHOD2(getDataLoader,
217 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700218 MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800219
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700220 void bindToDataLoaderSuccess() {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800221 ON_CALL(*this, bindToDataLoader(_, _, _, _, _))
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700222 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700223 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700224 void bindToDataLoaderFails() {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800225 ON_CALL(*this, bindToDataLoader(_, _, _, _, _))
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700226 .WillByDefault(Return(
227 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
228 }
229 void getDataLoaderSuccess() {
230 ON_CALL(*this, getDataLoader(_, _))
231 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
232 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700233 void unbindFromDataLoaderSuccess() {
234 ON_CALL(*this, unbindFromDataLoader(_))
235 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700236 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700237 binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800238 int bindDelayMs,
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700239 const sp<IDataLoaderStatusListener>& listener,
240 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800241 mId = mountId;
242 mListener = listener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700243 mDataLoader = mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800244 *_aidl_return = true;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700245 if (mListener) {
246 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
247 }
248 return binder::Status::ok();
Songchun Fan3c82a302019-11-29 14:23:45 -0800249 }
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800250 binder::Status bindToDataLoaderOkWith10sDelay(int32_t mountId,
251 const DataLoaderParamsParcel& params,
252 int bindDelayMs,
253 const sp<IDataLoaderStatusListener>& listener,
254 bool* _aidl_return) {
255 CHECK(1000 * 9 <= bindDelayMs && bindDelayMs <= 1000 * 11) << bindDelayMs;
256 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
257 }
258 binder::Status bindToDataLoaderOkWith100sDelay(int32_t mountId,
259 const DataLoaderParamsParcel& params,
260 int bindDelayMs,
261 const sp<IDataLoaderStatusListener>& listener,
262 bool* _aidl_return) {
263 CHECK(1000 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11) << bindDelayMs;
264 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
265 }
266 binder::Status bindToDataLoaderOkWith1000sDelay(int32_t mountId,
267 const DataLoaderParamsParcel& params,
268 int bindDelayMs,
269 const sp<IDataLoaderStatusListener>& listener,
270 bool* _aidl_return) {
271 CHECK(1000 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11) << bindDelayMs;
272 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
273 }
274 binder::Status bindToDataLoaderOkWith10000sDelay(int32_t mountId,
275 const DataLoaderParamsParcel& params,
276 int bindDelayMs,
277 const sp<IDataLoaderStatusListener>& listener,
278 bool* _aidl_return) {
279 CHECK(1000 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11 * 11)
280 << bindDelayMs;
281 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
282 }
283
Songchun Fan68645c42020-02-27 15:57:35 -0800284 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
285 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800286 return binder::Status::ok();
287 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700288 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800289 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800290 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700291 void setDataLoaderStatusStarted() {
292 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
293 }
294 void setDataLoaderStatusDestroyed() {
295 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
296 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700297 void setDataLoaderStatusUnavailable() {
298 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
299 }
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800300 void setDataLoaderStatusUnrecoverable() {
301 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE);
302 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700303 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700304 if (mDataLoader) {
305 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
306 return status;
307 }
308 mDataLoader = nullptr;
309 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700310 if (mListener) {
311 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
312 }
313 return binder::Status::ok();
314 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700315
Songchun Fan3c82a302019-11-29 14:23:45 -0800316private:
317 int mId;
318 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700319 sp<IDataLoader> mDataLoader;
320 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800321};
322
323class MockIncFs : public IncFsWrapper {
324public:
Yurii Zubrytskyia5946f72021-02-17 14:24:14 -0800325 MOCK_CONST_METHOD0(features, Features());
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700326 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
327 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800328 MOCK_CONST_METHOD4(createControl,
329 Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
330 IncFsFd blocksWritten));
Songchun Fan3c82a302019-11-29 14:23:45 -0800331 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800332 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800333 NewFileParams params));
Yurii Zubrytskyia5946f72021-02-17 14:24:14 -0800334 MOCK_CONST_METHOD4(makeMappedFile,
335 ErrorCode(const Control& control, std::string_view path, int mode,
336 NewMappedFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800337 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700338 MOCK_CONST_METHOD3(makeDirs,
339 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800340 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
341 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
342 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan6944f1e2020-11-06 15:24:24 -0800343 MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
Songchun Fan374f7652020-08-20 08:40:29 -0700344 MOCK_CONST_METHOD2(countFilledBlocks,
345 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
346 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800347 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700348 ErrorCode(const Control& control, std::string_view from,
349 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800350 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700351 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700352 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700353 MOCK_CONST_METHOD3(waitForPendingReads,
354 WaitResult(const Control& control, std::chrono::milliseconds timeout,
355 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800356 MOCK_CONST_METHOD2(setUidReadTimeouts,
357 ErrorCode(const Control& control,
358 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700359
360 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800361
362 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
363 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700364
365 void countFilledBlocksSuccess() {
366 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
367 }
368
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700369 void countFilledBlocksFullyLoaded() {
370 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
371 }
372
Songchun Fan374f7652020-08-20 08:40:29 -0700373 void countFilledBlocksFails() {
374 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
375 }
376
377 void countFilledBlocksEmpty() {
378 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
379 }
380
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700381 void openMountSuccess() {
382 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
383 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700384
385 // 1000ms
386 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700387 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700388 .WillByDefault(
389 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
390 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
391 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
392 return android::incfs::WaitResult::HaveData;
393 }));
394 }
395
396 void waitForPendingReadsTimeout() {
397 ON_CALL(*this, waitForPendingReads(_, _, _))
398 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700399 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700400
401 static constexpr auto kPendingReadsFd = 42;
402 Control openMountForHealth(std::string_view) {
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800403 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700404 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700405
Songchun Fan20d6ef22020-03-03 09:47:15 -0800406 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800407 metadata::Mount m;
408 m.mutable_storage()->set_id(100);
409 m.mutable_loader()->set_package_name("com.test");
410 m.mutable_loader()->set_arguments("com.uri");
411 const auto metadata = m.SerializeAsString();
412 m.mutable_loader()->release_arguments();
413 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800414 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800415 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800416 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800417 metadata::Storage st;
418 st.set_id(100);
419 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800420 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800421 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800422 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800423 metadata::BindPoint bp;
424 std::string destPath = "dest";
425 std::string srcPath = "src";
426 bp.set_storage_id(100);
427 bp.set_allocated_dest_path(&destPath);
428 bp.set_allocated_source_subdir(&srcPath);
429 const auto metadata = bp.SerializeAsString();
430 bp.release_source_subdir();
431 bp.release_dest_path();
432 return std::vector<char>(metadata.begin(), metadata.end());
433 }
434};
435
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700436class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700437public:
438 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700439 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700440 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
441
442 void checkPermissionSuccess() {
443 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
444 }
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -0800445 void checkPermissionNoCrossUsers() {
446 ON_CALL(*this,
447 checkPermission("android.permission.LOADER_USAGE_STATS",
448 "android:loader_usage_stats", _))
449 .WillByDefault(Return(android::incremental::Ok()));
450 ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
451 .WillByDefault(
452 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
453 }
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700454 void checkPermissionFails() {
455 ON_CALL(*this, checkPermission(_, _, _))
456 .WillByDefault(
457 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
458 }
459 void initializeStartWatchingMode() {
460 ON_CALL(*this, startWatchingMode(_, _, _))
461 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
462 }
463 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
464 mStoredCallback = cb;
465 }
466
467 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700468};
469
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700470class MockJniWrapper : public JniWrapper {
471public:
472 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
473
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700474 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700475};
476
477class MockLooperWrapper : public LooperWrapper {
478public:
479 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
480 MOCK_METHOD1(removeFd, int(int));
481 MOCK_METHOD0(wake, void());
482 MOCK_METHOD1(pollAll, int(int));
483
484 MockLooperWrapper() {
485 ON_CALL(*this, addFd(_, _, _, _, _))
486 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
487 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700488 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700489 }
490
491 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
492 mCallback = callback;
493 mCallbackData = data;
494 return 0;
495 }
496
497 int clearCallback(int) {
498 mCallback = nullptr;
499 mCallbackData = nullptr;
500 return 0;
501 }
502
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700503 int wait10Ms(int) {
504 // This is called from a loop in runCmdLooper.
505 // Sleeping for 10ms only to avoid busy looping.
506 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700507 return 0;
508 }
509
510 android::Looper_callbackFunc mCallback = nullptr;
511 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700512};
513
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700514class MockTimedQueueWrapper : public TimedQueueWrapper {
515public:
516 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
517 MOCK_METHOD1(removeJobs, void(MountId));
518 MOCK_METHOD0(stop, void());
519
520 MockTimedQueueWrapper() {
521 ON_CALL(*this, addJob(_, _, _))
522 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
523 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
524 }
525
526 void storeJob(MountId id, Milliseconds after, Job what) {
527 mId = id;
528 mAfter = after;
529 mWhat = std::move(what);
530 }
531
532 void clearJob(MountId id) {
533 if (mId == id) {
534 mAfter = {};
535 mWhat = {};
536 }
537 }
538
539 MountId mId = -1;
540 Milliseconds mAfter;
541 Job mWhat;
542};
543
Songchun Fan374f7652020-08-20 08:40:29 -0700544class MockFsWrapper : public FsWrapper {
545public:
546 MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
547 void hasNoFile() {
548 ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
549 }
550 void hasFiles() {
551 ON_CALL(*this, listFilesRecursive(_))
552 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
553 }
554 std::vector<std::string> fakeFiles(std::string_view directoryPath) {
555 return {"base.apk", "split.apk", "lib/a.so"};
556 }
557};
558
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700559class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
560public:
561 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
562
563 MockStorageHealthListener() {
564 ON_CALL(*this, onHealthStatus(_, _))
565 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
566 }
567
568 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
569 mStorageId = storageId;
570 mStatus = status;
571 return binder::Status::ok();
572 }
573
574 int32_t mStorageId = -1;
575 int32_t mStatus = -1;
576};
577
Songchun Fana7098592020-09-03 11:45:53 -0700578class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
579public:
580 MockStorageLoadingProgressListener() = default;
581 MOCK_METHOD2(onStorageLoadingProgressChanged,
582 binder::Status(int32_t storageId, float progress));
583 MOCK_METHOD0(onAsBinder, IBinder*());
584};
585
Songchun Fan3c82a302019-11-29 14:23:45 -0800586class MockServiceManager : public ServiceManagerWrapper {
587public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800588 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700589 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700590 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700591 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700592 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700593 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700594 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700595 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Songchun Fan374f7652020-08-20 08:40:29 -0700596 std::unique_ptr<MockFsWrapper> fs)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800597 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700598 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700599 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700600 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700601 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700602 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700603 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700604 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Songchun Fan374f7652020-08-20 08:40:29 -0700605 mFs(std::move(fs)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800606 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800607 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
608 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800609 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800610 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700611 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
612 return std::move(mAppOpsManager);
613 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700614 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700615 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700616 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700617 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
618 return std::move(mProgressUpdateJobQueue);
619 }
Songchun Fan374f7652020-08-20 08:40:29 -0700620 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800621
622private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800623 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800624 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800625 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700626 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700627 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700628 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700629 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700630 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700631 std::unique_ptr<MockFsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800632};
633
634// --- IncrementalServiceTest ---
635
Songchun Fan3c82a302019-11-29 14:23:45 -0800636class IncrementalServiceTest : public testing::Test {
637public:
638 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800639 auto vold = std::make_unique<NiceMock<MockVoldService>>();
640 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700641 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
642 mDataLoader = dataLoader.get();
643 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800644 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800645 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
646 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700647 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
648 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700649 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
650 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700651 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
652 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700653 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
654 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700655 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
656 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700657 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
658 mFs = fs.get();
Songchun Fana7098592020-09-03 11:45:53 -0700659 mIncrementalService = std::make_unique<
660 IncrementalService>(MockServiceManager(std::move(vold),
661 std::move(dataloaderManager),
662 std::move(incFs), std::move(appOps),
663 std::move(jni), std::move(looper),
664 std::move(timedQueue),
665 std::move(progressUpdateJobQueue),
666 std::move(fs)),
667 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800668 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800669 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700670 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800671 mIncrementalService->onSystemReady();
Songchun Fan374f7652020-08-20 08:40:29 -0700672 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800673 }
674
675 void setUpExistingMountDir(const std::string& rootDir) {
676 const auto dir = rootDir + "/dir1";
677 const auto mountDir = dir + "/mount";
678 const auto backingDir = dir + "/backing_store";
679 const auto storageDir = mountDir + "/st0";
680 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
681 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
682 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
683 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
684 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
685 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
686 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
687 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800688 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
689 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
690 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
691 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
692 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
693 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800694 }
695
Songchun Fan374f7652020-08-20 08:40:29 -0700696 void setupSuccess() {
697 mVold->mountIncFsSuccess();
698 mIncFs->makeFileSuccess();
699 mVold->bindMountSuccess();
700 mDataLoaderManager->bindToDataLoaderSuccess();
701 mDataLoaderManager->getDataLoaderSuccess();
702 }
703
Songchun Fan3c82a302019-11-29 14:23:45 -0800704protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700705 NiceMock<MockVoldService>* mVold = nullptr;
706 NiceMock<MockIncFs>* mIncFs = nullptr;
707 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
708 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
709 NiceMock<MockJniWrapper>* mJni = nullptr;
710 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700711 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700712 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700713 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700714 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800715 std::unique_ptr<IncrementalService> mIncrementalService;
716 TemporaryDir mRootDir;
717 DataLoaderParamsParcel mDataLoaderParcel;
718};
719
Songchun Fan3c82a302019-11-29 14:23:45 -0800720TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
721 mVold->mountIncFsFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800722 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800723 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800724 int storageId =
725 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
726 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800727 ASSERT_LT(storageId, 0);
728}
729
730TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
731 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800732 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700733 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800734 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800735 int storageId =
736 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
737 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800738 ASSERT_LT(storageId, 0);
739}
740
741TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
742 mVold->mountIncFsSuccess();
743 mIncFs->makeFileFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800744 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700745 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800746 EXPECT_CALL(*mVold, unmountIncFs(_));
747 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800748 int storageId =
749 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
750 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800751 ASSERT_LT(storageId, 0);
752}
753
754TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
755 mVold->mountIncFsSuccess();
756 mIncFs->makeFileSuccess();
757 mVold->bindMountFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800758 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700759 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800760 EXPECT_CALL(*mVold, unmountIncFs(_));
761 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800762 int storageId =
763 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
764 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800765 ASSERT_LT(storageId, 0);
766}
767
768TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
769 mVold->mountIncFsSuccess();
770 mIncFs->makeFileSuccess();
771 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700772 mDataLoaderManager->bindToDataLoaderFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800773 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700774 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700775 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
776 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
777 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800778 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
779 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800780 int storageId =
781 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
782 IncrementalService::CreateOptions::CreateNew);
783 ASSERT_GE(storageId, 0);
784 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800785}
786
787TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700788 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800789 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700790 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800791 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
792 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800793 int storageId =
794 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
795 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800796 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800797 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800798 mIncrementalService->deleteStorage(storageId);
799}
800
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800801TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
802 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(6);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700803 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800804 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
805 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700806 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800807 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
808 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800809 int storageId =
810 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
811 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800812 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800813 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800814
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700815 // Simulated crash/other connection breakage.
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800816
817 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
818 .WillByDefault(Invoke(mDataLoaderManager,
819 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
820 mDataLoaderManager->setDataLoaderStatusDestroyed();
821
822 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
823 .WillByDefault(Invoke(mDataLoaderManager,
824 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
825 mDataLoaderManager->setDataLoaderStatusDestroyed();
826
827 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
828 .WillByDefault(Invoke(mDataLoaderManager,
829 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
830 mDataLoaderManager->setDataLoaderStatusDestroyed();
831
832 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
833 .WillByDefault(Invoke(mDataLoaderManager,
834 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
835 mDataLoaderManager->setDataLoaderStatusDestroyed();
836
837 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
838 .WillByDefault(Invoke(mDataLoaderManager,
839 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700840 mDataLoaderManager->setDataLoaderStatusDestroyed();
841}
842
843TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700844 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800845 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700846 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700847 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
848 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
849 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
850 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
851 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800852 int storageId =
853 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
854 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700855 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800856 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
857 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700858 mDataLoaderManager->setDataLoaderStatusCreated();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700859 mDataLoaderManager->setDataLoaderStatusStarted();
860}
861
862TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700863 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800864 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700865 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800866 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700867 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
868 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
869 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
870 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800871 int storageId =
872 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
873 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700874 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800875 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
876 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700877 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800878}
879
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700880TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700881 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800882 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700883 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
884 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
885 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
886 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
887 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
888 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800889 int storageId =
890 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
891 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700892 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800893 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
894 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700895 mDataLoaderManager->setDataLoaderStatusUnavailable();
896}
897
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800898TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnrecoverable) {
899 mDataLoader->initializeCreateOkNoStatus();
900 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
901 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
902 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
903 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
904 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
905 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
906 TemporaryDir tempDir;
907 int storageId =
908 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
909 IncrementalService::CreateOptions::CreateNew);
910 ASSERT_GE(storageId, 0);
911 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
912 {}, {}));
913 mDataLoaderManager->setDataLoaderStatusUnrecoverable();
914}
915
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700916TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700917 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700918 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700919 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -0700920
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800921 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700922 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700923 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
924 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700925 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700926 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
927 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
928 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
929 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800930 int storageId =
931 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
932 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700933 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800934 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
935 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700936 mDataLoaderManager->setDataLoaderStatusUnavailable();
937 ASSERT_NE(nullptr, mLooper->mCallback);
938 ASSERT_NE(nullptr, mLooper->mCallbackData);
939 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
940}
941
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700942TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700943 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700944
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800945 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700946 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
947 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
948 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
949 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
950 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
951 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
952 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
953 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
954
955 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
956 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
957 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
958 .Times(2);
959 EXPECT_CALL(*listenerMock,
960 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
961 .Times(1);
962 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
963 .Times(1);
964 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
965 .Times(2);
966
967 StorageHealthCheckParams params;
968 params.blockedTimeoutMs = 10000;
969 params.unhealthyTimeoutMs = 20000;
970 params.unhealthyMonitoringMs = 30000;
971
972 using MS = std::chrono::milliseconds;
973 using MCS = std::chrono::microseconds;
974
975 const auto blockedTimeout = MS(params.blockedTimeoutMs);
976 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
977 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
978
979 const uint64_t kFirstTimestampUs = 1000000000ll;
980 const uint64_t kBlockedTimestampUs =
981 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
982 const uint64_t kUnhealthyTimestampUs =
983 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
984
985 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800986 int storageId =
987 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
988 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700989 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800990 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
991 std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700992
993 // Healthy state, registered for pending reads.
994 ASSERT_NE(nullptr, mLooper->mCallback);
995 ASSERT_NE(nullptr, mLooper->mCallbackData);
996 ASSERT_EQ(storageId, listener->mStorageId);
997 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
998
999 // Looper/epoll callback.
1000 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1001 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1002
1003 // Unregister from pending reads and wait.
1004 ASSERT_EQ(nullptr, mLooper->mCallback);
1005 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1006 ASSERT_EQ(storageId, listener->mStorageId);
1007 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
1008 // Timed callback present.
1009 ASSERT_EQ(storageId, mTimedQueue->mId);
1010 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
1011 auto timedCallback = mTimedQueue->mWhat;
1012 mTimedQueue->clearJob(storageId);
1013
1014 // Timed job callback for blocked.
1015 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1016 timedCallback();
1017
1018 // Still not registered, and blocked.
1019 ASSERT_EQ(nullptr, mLooper->mCallback);
1020 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1021 ASSERT_EQ(storageId, listener->mStorageId);
1022 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
1023 // Timed callback present.
1024 ASSERT_EQ(storageId, mTimedQueue->mId);
1025 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
1026 timedCallback = mTimedQueue->mWhat;
1027 mTimedQueue->clearJob(storageId);
1028
1029 // Timed job callback for unhealthy.
1030 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1031 timedCallback();
1032
1033 // Still not registered, and blocked.
1034 ASSERT_EQ(nullptr, mLooper->mCallback);
1035 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1036 ASSERT_EQ(storageId, listener->mStorageId);
1037 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
1038 // Timed callback present.
1039 ASSERT_EQ(storageId, mTimedQueue->mId);
1040 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1041 timedCallback = mTimedQueue->mWhat;
1042 mTimedQueue->clearJob(storageId);
1043
1044 // One more unhealthy.
1045 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1046 timedCallback();
1047
1048 // Still not registered, and blocked.
1049 ASSERT_EQ(nullptr, mLooper->mCallback);
1050 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1051 ASSERT_EQ(storageId, listener->mStorageId);
1052 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
1053 // Timed callback present.
1054 ASSERT_EQ(storageId, mTimedQueue->mId);
1055 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1056 timedCallback = mTimedQueue->mWhat;
1057 mTimedQueue->clearJob(storageId);
1058
1059 // And now healthy.
1060 mIncFs->waitForPendingReadsTimeout();
1061 timedCallback();
1062
1063 // Healthy state, registered for pending reads.
1064 ASSERT_NE(nullptr, mLooper->mCallback);
1065 ASSERT_NE(nullptr, mLooper->mCallbackData);
1066 ASSERT_EQ(storageId, listener->mStorageId);
1067 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
1068}
1069
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001070TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001071 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001072 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001073
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001074 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001075 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001076 // We are calling setIncFsMountOptions(true).
1077 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1078 // After setIncFsMountOptions succeeded expecting to start watching.
1079 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1080 // Not expecting callback removal.
1081 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001082 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001083 int storageId =
1084 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1085 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001086 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001087 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1088 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001089 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001090}
1091
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001092TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001093 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001094 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001095
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001096 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1097 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1098 // Enabling and then disabling readlogs.
1099 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1100 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1101 // After setIncFsMountOptions succeeded expecting to start watching.
1102 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1103 // Not expecting callback removal.
1104 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1105 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001106 int storageId =
1107 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1108 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001109 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001110 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1111 {}, {}));
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001112 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1113 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001114 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001115 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1116}
1117
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001118TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001119 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001120 mAppOpsManager->checkPermissionSuccess();
1121 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001122
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001123 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001124 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1125 // We are calling setIncFsMountOptions(true).
1126 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1127 // setIncFsMountOptions(false) is called on the callback.
1128 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1129 // After setIncFsMountOptions succeeded expecting to start watching.
1130 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1131 // After callback is called, disable read logs and remove callback.
1132 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1133 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001134 int storageId =
1135 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1136 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001137 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001138 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1139 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001140 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001141 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1142 mAppOpsManager->mStoredCallback->opChanged(0, {});
1143}
1144
1145TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001146 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001147
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001148 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001149 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1150 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1151 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1152 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1153 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1154 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001155 int storageId =
1156 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1157 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001158 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001159 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1160 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001161 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001162}
1163
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001164TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
1165 mAppOpsManager->checkPermissionNoCrossUsers();
1166
1167 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1168 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1169 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1170 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1171 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1172 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1173 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001174 int storageId =
1175 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1176 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001177 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001178 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1179 {}, {}));
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001180 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1181}
1182
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001183TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001184 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001185 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001186
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001187 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001188 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001189 // We are calling setIncFsMountOptions.
1190 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1191 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1192 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1193 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001194 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001195 int storageId =
1196 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1197 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001198 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001199 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1200 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001201 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001202}
1203
Songchun Fan3c82a302019-11-29 14:23:45 -08001204TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001205 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001206 int storageId =
1207 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1208 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001209 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001210
Songchun Fan103ba1d2020-02-03 17:32:32 -08001211 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001212 // <root>/*/mount/<storage>/test
1213 EXPECT_CALL(*mIncFs,
1214 makeDir(_, Truly([&](std::string_view arg) {
1215 return arg.starts_with(mRootDir.path) &&
1216 arg.ends_with("/mount/st_1_0/" + dir_path);
1217 }),
1218 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001219 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1220 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001221}
1222
1223TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001224 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001225 int storageId =
1226 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1227 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001228 auto first = "first"sv;
1229 auto second = "second"sv;
1230 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001231 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001232
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001233 EXPECT_CALL(*mIncFs,
1234 makeDirs(_, Truly([&](std::string_view arg) {
1235 return arg.starts_with(mRootDir.path) &&
1236 arg.ends_with("/mount/st_1_0/" + dir_path);
1237 }),
1238 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001239 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001240 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001241}
Songchun Fan374f7652020-08-20 08:40:29 -07001242
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001243TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1244 mIncFs->countFilledBlocksFails();
1245 mFs->hasNoFile();
1246
1247 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001248 int storageId =
1249 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1250 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001251 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1252}
1253
1254TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1255 mIncFs->countFilledBlocksFails();
1256 mFs->hasFiles();
1257
1258 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001259 int storageId =
1260 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1261 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001262 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1263 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1264}
1265
1266TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1267 mIncFs->countFilledBlocksEmpty();
1268 mFs->hasFiles();
1269
1270 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001271 int storageId =
1272 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1273 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001274 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1275 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1276}
1277
1278TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1279 mIncFs->countFilledBlocksFullyLoaded();
1280 mFs->hasFiles();
1281
1282 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001283 int storageId =
1284 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1285 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001286 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1287 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1288}
1289
Songchun Fan425862f2020-08-25 13:12:16 -07001290TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001291 mIncFs->countFilledBlocksSuccess();
1292 mFs->hasNoFile();
1293
1294 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001295 int storageId =
1296 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1297 IncrementalService::CreateOptions::CreateNew);
1298 ASSERT_EQ(1,
1299 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1300 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001301}
1302
1303TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1304 mIncFs->countFilledBlocksFails();
1305 mFs->hasFiles();
1306
1307 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001308 int storageId =
1309 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1310 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001311 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001312 ASSERT_EQ(-1,
1313 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1314 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001315}
1316
Songchun Fan425862f2020-08-25 13:12:16 -07001317TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001318 mIncFs->countFilledBlocksEmpty();
1319 mFs->hasFiles();
1320
1321 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001322 int storageId =
1323 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1324 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001325 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001326 ASSERT_EQ(1,
1327 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1328 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001329}
1330
1331TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1332 mIncFs->countFilledBlocksSuccess();
1333 mFs->hasFiles();
1334
1335 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001336 int storageId =
1337 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1338 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001339 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001340 ASSERT_EQ(0.5,
1341 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1342 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001343}
Songchun Fana7098592020-09-03 11:45:53 -07001344
1345TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1346 mIncFs->countFilledBlocksSuccess();
1347 mFs->hasFiles();
1348
1349 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001350 int storageId =
1351 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1352 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001353 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1354 new NiceMock<MockStorageLoadingProgressListener>};
1355 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1356 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1357 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1358 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1359 // Timed callback present.
1360 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1361 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1362 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1363 timedCallback();
1364 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1365 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1366 mIncrementalService->unregisterLoadingProgressListener(storageId);
1367 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1368}
1369
1370TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1371 mIncFs->countFilledBlocksFails();
1372 mFs->hasFiles();
1373
1374 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001375 int storageId =
1376 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1377 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001378 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1379 new NiceMock<MockStorageLoadingProgressListener>};
1380 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1381 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1382 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1383}
Songchun Fan2570ec02020-10-08 17:22:33 -07001384
1385TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1386 mIncFs->openMountSuccess();
1387 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1388 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1389 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1390
1391 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001392 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001393 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1394 IncrementalService::CreateOptions::CreateNew);
Songchun Fan2570ec02020-10-08 17:22:33 -07001395 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001396 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener,
1397 {});
1398
Songchun Fan2570ec02020-10-08 17:22:33 -07001399 StorageHealthCheckParams newParams;
1400 newParams.blockedTimeoutMs = 10000;
1401 newParams.unhealthyTimeoutMs = 20000;
1402 newParams.unhealthyMonitoringMs = 30000;
1403 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1404 newListener));
1405
1406 using MS = std::chrono::milliseconds;
1407 using MCS = std::chrono::microseconds;
1408
1409 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1410 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1411
1412 const uint64_t kFirstTimestampUs = 1000000000ll;
1413 const uint64_t kBlockedTimestampUs =
1414 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1415 const uint64_t kUnhealthyTimestampUs =
1416 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1417
1418 // test that old listener was not called
1419 EXPECT_CALL(*listener.get(),
1420 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1421 .Times(0);
1422 EXPECT_CALL(*newListenerMock,
1423 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1424 .Times(1);
1425 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1426 .Times(1);
1427 EXPECT_CALL(*newListenerMock,
1428 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1429 .Times(1);
1430 EXPECT_CALL(*newListenerMock,
1431 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1432 .Times(1);
1433 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1434 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1435
1436 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1437 ASSERT_EQ(storageId, newListener->mStorageId);
1438
1439 auto timedCallback = mTimedQueue->mWhat;
1440 mTimedQueue->clearJob(storageId);
1441
1442 // test when health status is blocked with transport error
1443 mDataLoader->transportError(storageId);
1444 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1445 timedCallback();
1446 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1447 timedCallback = mTimedQueue->mWhat;
1448 mTimedQueue->clearJob(storageId);
1449
1450 // test when health status is blocked with storage error
1451 mDataLoader->storageError(storageId);
1452 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1453 timedCallback();
1454 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1455 timedCallback = mTimedQueue->mWhat;
1456 mTimedQueue->clearJob(storageId);
1457
1458 // test when health status is unhealthy with transport error
1459 mDataLoader->transportError(storageId);
1460 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1461 timedCallback();
1462 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1463 mTimedQueue->clearJob(storageId);
1464}
1465
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001466static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1467 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1468 std::vector<PerUidReadTimeouts> result;
1469 for (auto&& tuple : tuples) {
1470 result.emplace_back();
1471 auto& timeouts = result.back();
1472 timeouts.uid = std::get<0>(tuple);
1473 timeouts.minTimeUs = std::get<1>(tuple);
1474 timeouts.minPendingTimeUs = std::get<2>(tuple);
1475 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1476 }
1477 return result;
1478}
1479
1480static ErrorCode checkPerUidTimeouts(const Control& control,
1481 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1482 std::vector<PerUidReadTimeouts> expected =
1483 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1484 EXPECT_EQ(expected, perUidReadTimeouts);
1485 return 0;
1486}
1487
1488static ErrorCode checkPerUidTimeoutsEmpty(
1489 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1490 EXPECT_EQ(0u, perUidReadTimeouts.size());
1491 return 0;
1492}
1493
1494TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001495 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001496 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1497 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001498 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001499 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1500 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
1501 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1502 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1503 TemporaryDir tempDir;
1504 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001505 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1506 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001507 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001508 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1509 createPerUidTimeouts(
1510 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001511}
1512
1513TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1514 mVold->setIncFsMountOptionsSuccess();
1515 mAppOpsManager->checkPermissionSuccess();
1516 mFs->hasFiles();
1517
1518 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1519 // First call.
1520 .WillOnce(Invoke(&checkPerUidTimeouts))
1521 // Fully loaded and no readlogs.
1522 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1523 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1524
1525 // Empty storage.
1526 mIncFs->countFilledBlocksEmpty();
1527
1528 TemporaryDir tempDir;
1529 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001530 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1531 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001532 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001533 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1534 createPerUidTimeouts(
1535 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001536
1537 {
1538 // Timed callback present -> 0 progress.
1539 ASSERT_EQ(storageId, mTimedQueue->mId);
1540 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1541 const auto timedCallback = mTimedQueue->mWhat;
1542 mTimedQueue->clearJob(storageId);
1543
1544 // Still loading.
1545 mIncFs->countFilledBlocksSuccess();
1546
1547 // Call it again.
1548 timedCallback();
1549 }
1550
1551 {
1552 // Still present -> 0.5 progress.
1553 ASSERT_EQ(storageId, mTimedQueue->mId);
1554 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1555 const auto timedCallback = mTimedQueue->mWhat;
1556 mTimedQueue->clearJob(storageId);
1557
1558 // Fully loaded but readlogs collection enabled.
1559 mIncFs->countFilledBlocksFullyLoaded();
1560 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1561
1562 // Call it again.
1563 timedCallback();
1564 }
1565
1566 {
1567 // Still present -> fully loaded + readlogs.
1568 ASSERT_EQ(storageId, mTimedQueue->mId);
1569 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1570 const auto timedCallback = mTimedQueue->mWhat;
1571 mTimedQueue->clearJob(storageId);
1572
1573 // Now disable readlogs.
1574 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1575
1576 // Call it again.
1577 timedCallback();
1578 }
1579
1580 // No callbacks anymore -> fully loaded and no readlogs.
1581 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1582}
1583
Songchun Fan3c82a302019-11-29 14:23:45 -08001584} // namespace android::os::incremental