blob: 5236983c83fff484563696944c1943d1e45c48ac [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>
Songchun Fan1b76ccf2021-02-24 22:25:59 +000024#include <utils/String16.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080025
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -070026#include <chrono>
Songchun Fan3c82a302019-11-29 14:23:45 -080027#include <future>
28
29#include "IncrementalService.h"
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070030#include "IncrementalServiceValidation.h"
Songchun Fan3c82a302019-11-29 14:23:45 -080031#include "Metadata.pb.h"
32#include "ServiceWrappers.h"
33
34using namespace testing;
35using namespace android::incremental;
36using namespace std::literals;
37using testing::_;
38using testing::Invoke;
39using testing::NiceMock;
40
41#undef LOG_TAG
42#define LOG_TAG "IncrementalServiceTest"
43
44using namespace android::incfs;
45using namespace android::content::pm;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080046using PerUidReadTimeouts = android::os::incremental::PerUidReadTimeouts;
Songchun Fan3c82a302019-11-29 14:23:45 -080047
48namespace android::os::incremental {
49
50class MockVoldService : public VoldServiceWrapper {
51public:
52 MOCK_CONST_METHOD4(mountIncFs,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080053 binder::Status(const std::string& backingPath, const std::string& targetDir,
Songchun Fan3c82a302019-11-29 14:23:45 -080054 int32_t flags,
55 IncrementalFileSystemControlParcel* _aidl_return));
56 MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
57 MOCK_CONST_METHOD2(bindMount,
58 binder::Status(const std::string& sourceDir, const std::string& argetDir));
Songchun Fan374f7652020-08-20 08:40:29 -070059 MOCK_CONST_METHOD2(
60 setIncFsMountOptions,
61 binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
62 bool));
Songchun Fan3c82a302019-11-29 14:23:45 -080063
64 void mountIncFsFails() {
65 ON_CALL(*this, mountIncFs(_, _, _, _))
66 .WillByDefault(
67 Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
68 }
69 void mountIncFsInvalidControlParcel() {
70 ON_CALL(*this, mountIncFs(_, _, _, _))
71 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
72 }
73 void mountIncFsSuccess() {
74 ON_CALL(*this, mountIncFs(_, _, _, _))
75 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
76 }
77 void bindMountFails() {
78 ON_CALL(*this, bindMount(_, _))
79 .WillByDefault(Return(
80 binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
81 }
82 void bindMountSuccess() {
83 ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
84 }
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070085 void setIncFsMountOptionsFails() const {
86 ON_CALL(*this, setIncFsMountOptions(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -070087 .WillByDefault(Return(
88 binder::Status::fromExceptionCode(1, String8("failed to set options"))));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070089 }
90 void setIncFsMountOptionsSuccess() {
91 ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
92 }
Songchun Fan3c82a302019-11-29 14:23:45 -080093 binder::Status getInvalidControlParcel(const std::string& imagePath,
94 const std::string& targetDir, int32_t flags,
95 IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080096 _aidl_return = {};
Songchun Fan3c82a302019-11-29 14:23:45 -080097 return binder::Status::ok();
98 }
99 binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
100 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800101 _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
102 _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
103 _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
Songchun Fan3c82a302019-11-29 14:23:45 -0800104 return binder::Status::ok();
105 }
106
107private:
108 TemporaryFile cmdFile;
109 TemporaryFile logFile;
Songchun Fan3c82a302019-11-29 14:23:45 -0800110};
111
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700112class MockDataLoader : public IDataLoader {
Songchun Fan3c82a302019-11-29 14:23:45 -0800113public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700114 MockDataLoader() {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700115 ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk));
116 ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk));
117 ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk));
118 ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk));
119 ON_CALL(*this, prepareImage(_, _, _))
120 .WillByDefault(Invoke(this, &MockDataLoader::prepareImageOk));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700121 }
Songchun Fan68645c42020-02-27 15:57:35 -0800122 IBinder* onAsBinder() override { return nullptr; }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700123 MOCK_METHOD4(create,
124 binder::Status(int32_t id, const DataLoaderParamsParcel& params,
125 const FileSystemControlParcel& control,
126 const sp<IDataLoaderStatusListener>& listener));
127 MOCK_METHOD1(start, binder::Status(int32_t id));
128 MOCK_METHOD1(stop, binder::Status(int32_t id));
129 MOCK_METHOD1(destroy, binder::Status(int32_t id));
130 MOCK_METHOD3(prepareImage,
131 binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles,
132 const std::vector<std::string>& removedFiles));
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700133
134 void initializeCreateOkNoStatus() {
135 ON_CALL(*this, create(_, _, _, _))
136 .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus));
137 }
138
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700139 binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params,
140 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700141 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700142 createOkNoStatus(id, params, control, listener);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700143 if (mListener) {
144 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED);
145 }
146 return binder::Status::ok();
147 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700148 binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
149 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700150 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700151 mServiceConnector = control.service;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700152 mListener = listener;
153 return binder::Status::ok();
154 }
155 binder::Status startOk(int32_t id) {
156 if (mListener) {
157 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
158 }
159 return binder::Status::ok();
160 }
161 binder::Status stopOk(int32_t id) {
162 if (mListener) {
163 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
164 }
165 return binder::Status::ok();
166 }
167 binder::Status destroyOk(int32_t id) {
168 if (mListener) {
169 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
170 }
171 mListener = nullptr;
172 return binder::Status::ok();
173 }
174 binder::Status prepareImageOk(int32_t id,
175 const ::std::vector<content::pm::InstallationFileParcel>&,
176 const ::std::vector<::std::string>&) {
177 if (mListener) {
178 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
179 }
180 return binder::Status::ok();
181 }
Songchun Fan2570ec02020-10-08 17:22:33 -0700182 binder::Status storageError(int32_t id) {
183 if (mListener) {
184 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_STORAGE_ERROR);
185 }
186 return binder::Status::ok();
187 }
188 binder::Status transportError(int32_t id) {
189 if (mListener) {
190 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_INTEGRITY_ERROR);
191 }
192 return binder::Status::ok();
193 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700194 int32_t setStorageParams(bool enableReadLogs) {
195 int32_t result = -1;
196 EXPECT_NE(mServiceConnector.get(), nullptr);
197 EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
198 return result;
199 }
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700200
201private:
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700202 sp<IIncrementalServiceConnector> mServiceConnector;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700203 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800204};
205
206class MockDataLoaderManager : public DataLoaderManagerWrapper {
207public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700208 MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
209 EXPECT_TRUE(mDataLoaderHolder != nullptr);
210 }
211
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800212 MOCK_CONST_METHOD5(bindToDataLoader,
Songchun Fan68645c42020-02-27 15:57:35 -0800213 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800214 int bindDelayMs,
Songchun Fan3c82a302019-11-29 14:23:45 -0800215 const sp<IDataLoaderStatusListener>& listener,
216 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800217 MOCK_CONST_METHOD2(getDataLoader,
218 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700219 MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800220
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700221 void bindToDataLoaderSuccess() {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800222 ON_CALL(*this, bindToDataLoader(_, _, _, _, _))
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700223 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700224 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700225 void bindToDataLoaderFails() {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800226 ON_CALL(*this, bindToDataLoader(_, _, _, _, _))
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700227 .WillByDefault(Return(
228 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
229 }
230 void getDataLoaderSuccess() {
231 ON_CALL(*this, getDataLoader(_, _))
232 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
233 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700234 void unbindFromDataLoaderSuccess() {
235 ON_CALL(*this, unbindFromDataLoader(_))
236 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700237 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700238 binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800239 int bindDelayMs,
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700240 const sp<IDataLoaderStatusListener>& listener,
241 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800242 mId = mountId;
243 mListener = listener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700244 mDataLoader = mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800245 *_aidl_return = true;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700246 if (mListener) {
247 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
248 }
249 return binder::Status::ok();
Songchun Fan3c82a302019-11-29 14:23:45 -0800250 }
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800251 binder::Status bindToDataLoaderOkWith10sDelay(int32_t mountId,
252 const DataLoaderParamsParcel& params,
253 int bindDelayMs,
254 const sp<IDataLoaderStatusListener>& listener,
255 bool* _aidl_return) {
256 CHECK(1000 * 9 <= bindDelayMs && bindDelayMs <= 1000 * 11) << bindDelayMs;
257 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
258 }
259 binder::Status bindToDataLoaderOkWith100sDelay(int32_t mountId,
260 const DataLoaderParamsParcel& params,
261 int bindDelayMs,
262 const sp<IDataLoaderStatusListener>& listener,
263 bool* _aidl_return) {
264 CHECK(1000 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11) << bindDelayMs;
265 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
266 }
267 binder::Status bindToDataLoaderOkWith1000sDelay(int32_t mountId,
268 const DataLoaderParamsParcel& params,
269 int bindDelayMs,
270 const sp<IDataLoaderStatusListener>& listener,
271 bool* _aidl_return) {
272 CHECK(1000 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11) << bindDelayMs;
273 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
274 }
275 binder::Status bindToDataLoaderOkWith10000sDelay(int32_t mountId,
276 const DataLoaderParamsParcel& params,
277 int bindDelayMs,
278 const sp<IDataLoaderStatusListener>& listener,
279 bool* _aidl_return) {
280 CHECK(1000 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11 * 11)
281 << bindDelayMs;
282 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
283 }
284
Songchun Fan68645c42020-02-27 15:57:35 -0800285 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
286 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800287 return binder::Status::ok();
288 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700289 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800290 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800291 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700292 void setDataLoaderStatusStarted() {
293 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
294 }
295 void setDataLoaderStatusDestroyed() {
296 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
297 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700298 void setDataLoaderStatusUnavailable() {
299 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
300 }
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800301 void setDataLoaderStatusUnrecoverable() {
302 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE);
303 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700304 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700305 if (mDataLoader) {
306 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
307 return status;
308 }
309 mDataLoader = nullptr;
310 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700311 if (mListener) {
312 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
313 }
314 return binder::Status::ok();
315 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700316
Songchun Fan3c82a302019-11-29 14:23:45 -0800317private:
318 int mId;
319 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700320 sp<IDataLoader> mDataLoader;
321 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800322};
323
324class MockIncFs : public IncFsWrapper {
325public:
Yurii Zubrytskyia5946f72021-02-17 14:24:14 -0800326 MOCK_CONST_METHOD0(features, Features());
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700327 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
328 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800329 MOCK_CONST_METHOD4(createControl,
330 Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
331 IncFsFd blocksWritten));
Songchun Fan3c82a302019-11-29 14:23:45 -0800332 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800333 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800334 NewFileParams params));
Yurii Zubrytskyia5946f72021-02-17 14:24:14 -0800335 MOCK_CONST_METHOD4(makeMappedFile,
336 ErrorCode(const Control& control, std::string_view path, int mode,
337 NewMappedFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800338 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700339 MOCK_CONST_METHOD3(makeDirs,
340 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800341 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
342 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
343 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan6944f1e2020-11-06 15:24:24 -0800344 MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
Songchun Fan374f7652020-08-20 08:40:29 -0700345 MOCK_CONST_METHOD2(countFilledBlocks,
346 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
347 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800348 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700349 ErrorCode(const Control& control, std::string_view from,
350 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800351 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700352 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700353 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700354 MOCK_CONST_METHOD3(waitForPendingReads,
355 WaitResult(const Control& control, std::chrono::milliseconds timeout,
356 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800357 MOCK_CONST_METHOD2(setUidReadTimeouts,
358 ErrorCode(const Control& control,
359 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700360
361 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800362
363 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
364 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700365
366 void countFilledBlocksSuccess() {
367 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
368 }
369
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700370 void countFilledBlocksFullyLoaded() {
371 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
372 }
373
Songchun Fan374f7652020-08-20 08:40:29 -0700374 void countFilledBlocksFails() {
375 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
376 }
377
378 void countFilledBlocksEmpty() {
379 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
380 }
381
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700382 void openMountSuccess() {
383 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
384 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700385
386 // 1000ms
387 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700388 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700389 .WillByDefault(
390 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
391 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
392 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
393 return android::incfs::WaitResult::HaveData;
394 }));
395 }
396
397 void waitForPendingReadsTimeout() {
398 ON_CALL(*this, waitForPendingReads(_, _, _))
399 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700400 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700401
402 static constexpr auto kPendingReadsFd = 42;
403 Control openMountForHealth(std::string_view) {
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800404 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700405 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700406
Songchun Fan20d6ef22020-03-03 09:47:15 -0800407 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800408 metadata::Mount m;
409 m.mutable_storage()->set_id(100);
410 m.mutable_loader()->set_package_name("com.test");
411 m.mutable_loader()->set_arguments("com.uri");
412 const auto metadata = m.SerializeAsString();
413 m.mutable_loader()->release_arguments();
414 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800415 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800416 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800417 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800418 metadata::Storage st;
419 st.set_id(100);
420 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800421 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800422 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800423 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800424 metadata::BindPoint bp;
425 std::string destPath = "dest";
426 std::string srcPath = "src";
427 bp.set_storage_id(100);
428 bp.set_allocated_dest_path(&destPath);
429 bp.set_allocated_source_subdir(&srcPath);
430 const auto metadata = bp.SerializeAsString();
431 bp.release_source_subdir();
432 bp.release_dest_path();
433 return std::vector<char>(metadata.begin(), metadata.end());
434 }
435};
436
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700437class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700438public:
439 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700440 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700441 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
442
443 void checkPermissionSuccess() {
444 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
445 }
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -0800446 void checkPermissionNoCrossUsers() {
447 ON_CALL(*this,
448 checkPermission("android.permission.LOADER_USAGE_STATS",
449 "android:loader_usage_stats", _))
450 .WillByDefault(Return(android::incremental::Ok()));
451 ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
452 .WillByDefault(
453 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
454 }
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700455 void checkPermissionFails() {
456 ON_CALL(*this, checkPermission(_, _, _))
457 .WillByDefault(
458 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
459 }
460 void initializeStartWatchingMode() {
461 ON_CALL(*this, startWatchingMode(_, _, _))
462 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
463 }
464 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
465 mStoredCallback = cb;
466 }
467
468 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700469};
470
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700471class MockJniWrapper : public JniWrapper {
472public:
473 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
474
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700475 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700476};
477
478class MockLooperWrapper : public LooperWrapper {
479public:
480 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
481 MOCK_METHOD1(removeFd, int(int));
482 MOCK_METHOD0(wake, void());
483 MOCK_METHOD1(pollAll, int(int));
484
485 MockLooperWrapper() {
486 ON_CALL(*this, addFd(_, _, _, _, _))
487 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
488 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700489 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700490 }
491
492 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
493 mCallback = callback;
494 mCallbackData = data;
495 return 0;
496 }
497
498 int clearCallback(int) {
499 mCallback = nullptr;
500 mCallbackData = nullptr;
501 return 0;
502 }
503
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700504 int wait10Ms(int) {
505 // This is called from a loop in runCmdLooper.
506 // Sleeping for 10ms only to avoid busy looping.
507 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700508 return 0;
509 }
510
511 android::Looper_callbackFunc mCallback = nullptr;
512 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700513};
514
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700515class MockTimedQueueWrapper : public TimedQueueWrapper {
516public:
517 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
518 MOCK_METHOD1(removeJobs, void(MountId));
519 MOCK_METHOD0(stop, void());
520
521 MockTimedQueueWrapper() {
522 ON_CALL(*this, addJob(_, _, _))
523 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
524 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
525 }
526
527 void storeJob(MountId id, Milliseconds after, Job what) {
528 mId = id;
529 mAfter = after;
530 mWhat = std::move(what);
531 }
532
533 void clearJob(MountId id) {
534 if (mId == id) {
535 mAfter = {};
536 mWhat = {};
537 }
538 }
539
540 MountId mId = -1;
541 Milliseconds mAfter;
542 Job mWhat;
543};
544
Songchun Fan374f7652020-08-20 08:40:29 -0700545class MockFsWrapper : public FsWrapper {
546public:
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800547 MOCK_CONST_METHOD2(listFilesRecursive, void(std::string_view, FileCallback));
548 void hasNoFile() { ON_CALL(*this, listFilesRecursive(_, _)).WillByDefault(Return()); }
Songchun Fan374f7652020-08-20 08:40:29 -0700549 void hasFiles() {
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800550 ON_CALL(*this, listFilesRecursive(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -0700551 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
552 }
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800553 void fakeFiles(std::string_view directoryPath, FileCallback onFile) {
554 for (auto file : {"base.apk", "split.apk", "lib/a.so"}) {
555 if (!onFile(file)) break;
556 }
Songchun Fan374f7652020-08-20 08:40:29 -0700557 }
558};
559
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700560class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
561public:
562 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
563
564 MockStorageHealthListener() {
565 ON_CALL(*this, onHealthStatus(_, _))
566 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
567 }
568
569 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
570 mStorageId = storageId;
571 mStatus = status;
572 return binder::Status::ok();
573 }
574
575 int32_t mStorageId = -1;
576 int32_t mStatus = -1;
577};
578
Songchun Fana7098592020-09-03 11:45:53 -0700579class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
580public:
581 MockStorageLoadingProgressListener() = default;
582 MOCK_METHOD2(onStorageLoadingProgressChanged,
583 binder::Status(int32_t storageId, float progress));
584 MOCK_METHOD0(onAsBinder, IBinder*());
585};
586
Songchun Fan3c82a302019-11-29 14:23:45 -0800587class MockServiceManager : public ServiceManagerWrapper {
588public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800589 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700590 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700591 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700592 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700593 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700594 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700595 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700596 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Songchun Fan374f7652020-08-20 08:40:29 -0700597 std::unique_ptr<MockFsWrapper> fs)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800598 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700599 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700600 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700601 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700602 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700603 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700604 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700605 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Songchun Fan374f7652020-08-20 08:40:29 -0700606 mFs(std::move(fs)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800607 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800608 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
609 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800610 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800611 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700612 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
613 return std::move(mAppOpsManager);
614 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700615 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700616 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700617 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700618 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
619 return std::move(mProgressUpdateJobQueue);
620 }
Songchun Fan374f7652020-08-20 08:40:29 -0700621 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800622
623private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800624 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800625 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800626 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700627 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700628 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700629 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700630 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700631 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700632 std::unique_ptr<MockFsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800633};
634
635// --- IncrementalServiceTest ---
636
Songchun Fan3c82a302019-11-29 14:23:45 -0800637class IncrementalServiceTest : public testing::Test {
638public:
639 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800640 auto vold = std::make_unique<NiceMock<MockVoldService>>();
641 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700642 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
643 mDataLoader = dataLoader.get();
644 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800645 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800646 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
647 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700648 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
649 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700650 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
651 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700652 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
653 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700654 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
655 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700656 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
657 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700658 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
659 mFs = fs.get();
Songchun Fana7098592020-09-03 11:45:53 -0700660 mIncrementalService = std::make_unique<
661 IncrementalService>(MockServiceManager(std::move(vold),
662 std::move(dataloaderManager),
663 std::move(incFs), std::move(appOps),
664 std::move(jni), std::move(looper),
665 std::move(timedQueue),
666 std::move(progressUpdateJobQueue),
667 std::move(fs)),
668 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800669 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800670 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700671 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800672 mIncrementalService->onSystemReady();
Songchun Fan374f7652020-08-20 08:40:29 -0700673 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800674 }
675
676 void setUpExistingMountDir(const std::string& rootDir) {
677 const auto dir = rootDir + "/dir1";
678 const auto mountDir = dir + "/mount";
679 const auto backingDir = dir + "/backing_store";
680 const auto storageDir = mountDir + "/st0";
681 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
682 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
683 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
684 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
685 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
686 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
687 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
688 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800689 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
690 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
691 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
692 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
693 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
694 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800695 }
696
Songchun Fan374f7652020-08-20 08:40:29 -0700697 void setupSuccess() {
698 mVold->mountIncFsSuccess();
699 mIncFs->makeFileSuccess();
700 mVold->bindMountSuccess();
701 mDataLoaderManager->bindToDataLoaderSuccess();
702 mDataLoaderManager->getDataLoaderSuccess();
703 }
704
Songchun Fan1b76ccf2021-02-24 22:25:59 +0000705 void checkMillisSinceOldestPendingRead(int storageId, long expected) {
706 android::os::PersistableBundle result{};
707 mIncrementalService->getMetrics(storageId, &result);
708 int64_t value = -1;
709 ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
710 METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
711 .c_str()),
712 &value));
713 ASSERT_EQ(expected, value);
714 ASSERT_EQ(1, (int)result.size());
715 }
716
Songchun Fan3c82a302019-11-29 14:23:45 -0800717protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700718 NiceMock<MockVoldService>* mVold = nullptr;
719 NiceMock<MockIncFs>* mIncFs = nullptr;
720 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
721 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
722 NiceMock<MockJniWrapper>* mJni = nullptr;
723 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700724 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700725 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700726 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700727 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800728 std::unique_ptr<IncrementalService> mIncrementalService;
729 TemporaryDir mRootDir;
730 DataLoaderParamsParcel mDataLoaderParcel;
731};
732
Songchun Fan3c82a302019-11-29 14:23:45 -0800733TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
734 mVold->mountIncFsFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800735 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800736 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800737 int storageId =
738 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
739 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800740 ASSERT_LT(storageId, 0);
741}
742
743TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
744 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800745 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700746 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800747 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, testCreateStorageMakeFileFails) {
755 mVold->mountIncFsSuccess();
756 mIncFs->makeFileFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800757 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700758 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800759 EXPECT_CALL(*mVold, unmountIncFs(_));
760 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800761 int storageId =
762 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
763 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800764 ASSERT_LT(storageId, 0);
765}
766
767TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
768 mVold->mountIncFsSuccess();
769 mIncFs->makeFileSuccess();
770 mVold->bindMountFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800771 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700772 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800773 EXPECT_CALL(*mVold, unmountIncFs(_));
774 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800775 int storageId =
776 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
777 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800778 ASSERT_LT(storageId, 0);
779}
780
781TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
782 mVold->mountIncFsSuccess();
783 mIncFs->makeFileSuccess();
784 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700785 mDataLoaderManager->bindToDataLoaderFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800786 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700787 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700788 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
789 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
790 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
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);
796 ASSERT_GE(storageId, 0);
797 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800798}
799
800TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700801 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800802 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700803 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800804 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
805 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800806 int storageId =
807 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
808 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800809 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800810 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800811 mIncrementalService->deleteStorage(storageId);
812}
813
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800814TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
815 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(6);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700816 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800817 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
818 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700819 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800820 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
821 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800822 int storageId =
823 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
824 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800825 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800826 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800827
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700828 // Simulated crash/other connection breakage.
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800829
830 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
831 .WillByDefault(Invoke(mDataLoaderManager,
832 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
833 mDataLoaderManager->setDataLoaderStatusDestroyed();
834
835 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
836 .WillByDefault(Invoke(mDataLoaderManager,
837 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
838 mDataLoaderManager->setDataLoaderStatusDestroyed();
839
840 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
841 .WillByDefault(Invoke(mDataLoaderManager,
842 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
843 mDataLoaderManager->setDataLoaderStatusDestroyed();
844
845 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
846 .WillByDefault(Invoke(mDataLoaderManager,
847 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
848 mDataLoaderManager->setDataLoaderStatusDestroyed();
849
850 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
851 .WillByDefault(Invoke(mDataLoaderManager,
852 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700853 mDataLoaderManager->setDataLoaderStatusDestroyed();
854}
855
856TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700857 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800858 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700859 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700860 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
861 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
862 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
863 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
864 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800865 int storageId =
866 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
867 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700868 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800869 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
870 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700871 mDataLoaderManager->setDataLoaderStatusCreated();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700872 mDataLoaderManager->setDataLoaderStatusStarted();
873}
874
875TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700876 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800877 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700878 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800879 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700880 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
881 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
882 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
883 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800884 int storageId =
885 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
886 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700887 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800888 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
889 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700890 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800891}
892
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700893TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700894 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800895 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700896 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
897 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
898 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
899 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
900 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
901 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800902 int storageId =
903 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
904 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700905 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800906 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
907 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700908 mDataLoaderManager->setDataLoaderStatusUnavailable();
909}
910
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800911TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnrecoverable) {
912 mDataLoader->initializeCreateOkNoStatus();
913 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
914 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
915 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
916 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
917 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
918 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
919 TemporaryDir tempDir;
920 int storageId =
921 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
922 IncrementalService::CreateOptions::CreateNew);
923 ASSERT_GE(storageId, 0);
924 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
925 {}, {}));
926 mDataLoaderManager->setDataLoaderStatusUnrecoverable();
927}
928
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700929TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700930 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700931 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700932 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -0700933
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800934 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700935 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700936 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
937 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700938 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700939 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
940 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
941 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
942 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800943 int storageId =
944 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
945 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700946 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800947 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
948 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700949 mDataLoaderManager->setDataLoaderStatusUnavailable();
950 ASSERT_NE(nullptr, mLooper->mCallback);
951 ASSERT_NE(nullptr, mLooper->mCallbackData);
952 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
953}
954
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700955TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700956 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700957
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800958 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700959 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
960 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
961 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
962 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
963 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
964 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
965 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
966 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
967
968 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
969 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
970 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
971 .Times(2);
972 EXPECT_CALL(*listenerMock,
973 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
974 .Times(1);
975 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
976 .Times(1);
977 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
978 .Times(2);
979
980 StorageHealthCheckParams params;
981 params.blockedTimeoutMs = 10000;
982 params.unhealthyTimeoutMs = 20000;
983 params.unhealthyMonitoringMs = 30000;
984
985 using MS = std::chrono::milliseconds;
986 using MCS = std::chrono::microseconds;
987
988 const auto blockedTimeout = MS(params.blockedTimeoutMs);
989 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
990 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
991
992 const uint64_t kFirstTimestampUs = 1000000000ll;
993 const uint64_t kBlockedTimestampUs =
994 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
995 const uint64_t kUnhealthyTimestampUs =
996 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
997
998 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800999 int storageId =
1000 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1001 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001002 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001003 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
1004 std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001005
1006 // Healthy state, registered for pending reads.
1007 ASSERT_NE(nullptr, mLooper->mCallback);
1008 ASSERT_NE(nullptr, mLooper->mCallbackData);
1009 ASSERT_EQ(storageId, listener->mStorageId);
1010 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001011 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001012
1013 // Looper/epoll callback.
1014 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1015 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1016
1017 // Unregister from pending reads and wait.
1018 ASSERT_EQ(nullptr, mLooper->mCallback);
1019 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1020 ASSERT_EQ(storageId, listener->mStorageId);
1021 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
1022 // Timed callback present.
1023 ASSERT_EQ(storageId, mTimedQueue->mId);
1024 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
1025 auto timedCallback = mTimedQueue->mWhat;
1026 mTimedQueue->clearJob(storageId);
1027
1028 // Timed job callback for blocked.
1029 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1030 timedCallback();
1031
1032 // Still not registered, and blocked.
1033 ASSERT_EQ(nullptr, mLooper->mCallback);
1034 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1035 ASSERT_EQ(storageId, listener->mStorageId);
1036 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001037 checkMillisSinceOldestPendingRead(storageId, params.blockedTimeoutMs);
1038
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001039 // Timed callback present.
1040 ASSERT_EQ(storageId, mTimedQueue->mId);
1041 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
1042 timedCallback = mTimedQueue->mWhat;
1043 mTimedQueue->clearJob(storageId);
1044
1045 // Timed job callback for unhealthy.
1046 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1047 timedCallback();
1048
1049 // Still not registered, and blocked.
1050 ASSERT_EQ(nullptr, mLooper->mCallback);
1051 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1052 ASSERT_EQ(storageId, listener->mStorageId);
1053 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001054 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1055
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001056 // Timed callback present.
1057 ASSERT_EQ(storageId, mTimedQueue->mId);
1058 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1059 timedCallback = mTimedQueue->mWhat;
1060 mTimedQueue->clearJob(storageId);
1061
1062 // One more unhealthy.
1063 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1064 timedCallback();
1065
1066 // Still not registered, and blocked.
1067 ASSERT_EQ(nullptr, mLooper->mCallback);
1068 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1069 ASSERT_EQ(storageId, listener->mStorageId);
1070 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001071 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1072
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001073 // Timed callback present.
1074 ASSERT_EQ(storageId, mTimedQueue->mId);
1075 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1076 timedCallback = mTimedQueue->mWhat;
1077 mTimedQueue->clearJob(storageId);
1078
1079 // And now healthy.
1080 mIncFs->waitForPendingReadsTimeout();
1081 timedCallback();
1082
1083 // Healthy state, registered for pending reads.
1084 ASSERT_NE(nullptr, mLooper->mCallback);
1085 ASSERT_NE(nullptr, mLooper->mCallbackData);
1086 ASSERT_EQ(storageId, listener->mStorageId);
1087 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001088 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001089}
1090
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001091TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001092 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001093 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001094
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001095 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001096 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001097 // We are calling setIncFsMountOptions(true).
1098 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1099 // After setIncFsMountOptions succeeded expecting to start watching.
1100 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1101 // Not expecting callback removal.
1102 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001103 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001104 int storageId =
1105 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1106 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001107 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001108 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1109 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001110 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001111}
1112
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001113TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001114 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001115 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001116
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001117 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1118 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1119 // Enabling and then disabling readlogs.
1120 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1121 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1122 // After setIncFsMountOptions succeeded expecting to start watching.
1123 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1124 // Not expecting callback removal.
1125 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1126 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001127 int storageId =
1128 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1129 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001130 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001131 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1132 {}, {}));
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001133 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1134 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001135 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001136 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1137}
1138
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001139TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001140 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001141 mAppOpsManager->checkPermissionSuccess();
1142 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001143
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001144 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001145 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1146 // We are calling setIncFsMountOptions(true).
1147 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1148 // setIncFsMountOptions(false) is called on the callback.
1149 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1150 // After setIncFsMountOptions succeeded expecting to start watching.
1151 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1152 // After callback is called, disable read logs and remove callback.
1153 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
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_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001162 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1163 mAppOpsManager->mStoredCallback->opChanged(0, {});
1164}
1165
1166TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001167 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001168
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001169 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001170 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1171 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1172 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1173 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1174 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1175 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001176 int storageId =
1177 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1178 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001179 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001180 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1181 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001182 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001183}
1184
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001185TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
1186 mAppOpsManager->checkPermissionNoCrossUsers();
1187
1188 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1189 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1190 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1191 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1192 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1193 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1194 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001195 int storageId =
1196 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1197 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001198 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001199 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1200 {}, {}));
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001201 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1202}
1203
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001204TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001205 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001206 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001207
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001208 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001209 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001210 // We are calling setIncFsMountOptions.
1211 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1212 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1213 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1214 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001215 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001216 int storageId =
1217 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1218 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001219 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001220 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1221 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001222 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001223}
1224
Songchun Fan3c82a302019-11-29 14:23:45 -08001225TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001226 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001227 int storageId =
1228 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1229 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001230 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001231
Songchun Fan103ba1d2020-02-03 17:32:32 -08001232 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001233 // <root>/*/mount/<storage>/test
1234 EXPECT_CALL(*mIncFs,
1235 makeDir(_, Truly([&](std::string_view arg) {
1236 return arg.starts_with(mRootDir.path) &&
1237 arg.ends_with("/mount/st_1_0/" + dir_path);
1238 }),
1239 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001240 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1241 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001242}
1243
1244TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001245 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001246 int storageId =
1247 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1248 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001249 auto first = "first"sv;
1250 auto second = "second"sv;
1251 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001252 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001253
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001254 EXPECT_CALL(*mIncFs,
1255 makeDirs(_, Truly([&](std::string_view arg) {
1256 return arg.starts_with(mRootDir.path) &&
1257 arg.ends_with("/mount/st_1_0/" + dir_path);
1258 }),
1259 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001260 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001261 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001262}
Songchun Fan374f7652020-08-20 08:40:29 -07001263
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001264TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1265 mIncFs->countFilledBlocksFails();
1266 mFs->hasNoFile();
1267
1268 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001269 int storageId =
1270 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1271 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001272 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1273}
1274
1275TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1276 mIncFs->countFilledBlocksFails();
1277 mFs->hasFiles();
1278
1279 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001280 int storageId =
1281 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1282 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001283 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1284 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1285}
1286
1287TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1288 mIncFs->countFilledBlocksEmpty();
1289 mFs->hasFiles();
1290
1291 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001292 int storageId =
1293 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1294 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001295 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1296 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1297}
1298
1299TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1300 mIncFs->countFilledBlocksFullyLoaded();
1301 mFs->hasFiles();
1302
1303 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001304 int storageId =
1305 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1306 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001307 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1308 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1309}
1310
Songchun Fan425862f2020-08-25 13:12:16 -07001311TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001312 mIncFs->countFilledBlocksSuccess();
1313 mFs->hasNoFile();
1314
1315 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001316 int storageId =
1317 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1318 IncrementalService::CreateOptions::CreateNew);
1319 ASSERT_EQ(1,
1320 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1321 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001322}
1323
1324TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1325 mIncFs->countFilledBlocksFails();
1326 mFs->hasFiles();
1327
1328 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001329 int storageId =
1330 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1331 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001332 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001333 ASSERT_EQ(-1,
1334 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1335 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001336}
1337
Songchun Fan425862f2020-08-25 13:12:16 -07001338TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001339 mIncFs->countFilledBlocksEmpty();
1340 mFs->hasFiles();
1341
1342 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001343 int storageId =
1344 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1345 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001346 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001347 ASSERT_EQ(1,
1348 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1349 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001350}
1351
1352TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1353 mIncFs->countFilledBlocksSuccess();
1354 mFs->hasFiles();
1355
1356 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001357 int storageId =
1358 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1359 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001360 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001361 ASSERT_EQ(0.5,
1362 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1363 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001364}
Songchun Fana7098592020-09-03 11:45:53 -07001365
1366TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1367 mIncFs->countFilledBlocksSuccess();
1368 mFs->hasFiles();
1369
1370 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001371 int storageId =
1372 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1373 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001374 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1375 new NiceMock<MockStorageLoadingProgressListener>};
1376 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1377 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1378 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1379 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1380 // Timed callback present.
1381 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1382 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1383 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1384 timedCallback();
1385 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1386 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1387 mIncrementalService->unregisterLoadingProgressListener(storageId);
1388 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1389}
1390
1391TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1392 mIncFs->countFilledBlocksFails();
1393 mFs->hasFiles();
1394
1395 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001396 int storageId =
1397 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1398 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001399 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1400 new NiceMock<MockStorageLoadingProgressListener>};
1401 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1402 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1403 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1404}
Songchun Fan2570ec02020-10-08 17:22:33 -07001405
1406TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1407 mIncFs->openMountSuccess();
1408 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1409 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1410 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1411
1412 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001413 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001414 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1415 IncrementalService::CreateOptions::CreateNew);
Songchun Fan2570ec02020-10-08 17:22:33 -07001416 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001417 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener,
1418 {});
1419
Songchun Fan2570ec02020-10-08 17:22:33 -07001420 StorageHealthCheckParams newParams;
1421 newParams.blockedTimeoutMs = 10000;
1422 newParams.unhealthyTimeoutMs = 20000;
1423 newParams.unhealthyMonitoringMs = 30000;
1424 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1425 newListener));
1426
1427 using MS = std::chrono::milliseconds;
1428 using MCS = std::chrono::microseconds;
1429
1430 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1431 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1432
1433 const uint64_t kFirstTimestampUs = 1000000000ll;
1434 const uint64_t kBlockedTimestampUs =
1435 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1436 const uint64_t kUnhealthyTimestampUs =
1437 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1438
1439 // test that old listener was not called
1440 EXPECT_CALL(*listener.get(),
1441 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1442 .Times(0);
1443 EXPECT_CALL(*newListenerMock,
1444 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1445 .Times(1);
1446 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1447 .Times(1);
1448 EXPECT_CALL(*newListenerMock,
1449 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1450 .Times(1);
1451 EXPECT_CALL(*newListenerMock,
1452 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1453 .Times(1);
1454 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1455 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1456
1457 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1458 ASSERT_EQ(storageId, newListener->mStorageId);
1459
1460 auto timedCallback = mTimedQueue->mWhat;
1461 mTimedQueue->clearJob(storageId);
1462
1463 // test when health status is blocked with transport error
1464 mDataLoader->transportError(storageId);
1465 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1466 timedCallback();
1467 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1468 timedCallback = mTimedQueue->mWhat;
1469 mTimedQueue->clearJob(storageId);
1470
1471 // test when health status is blocked with storage error
1472 mDataLoader->storageError(storageId);
1473 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1474 timedCallback();
1475 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1476 timedCallback = mTimedQueue->mWhat;
1477 mTimedQueue->clearJob(storageId);
1478
1479 // test when health status is unhealthy with transport error
1480 mDataLoader->transportError(storageId);
1481 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1482 timedCallback();
1483 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1484 mTimedQueue->clearJob(storageId);
1485}
1486
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001487static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1488 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1489 std::vector<PerUidReadTimeouts> result;
1490 for (auto&& tuple : tuples) {
1491 result.emplace_back();
1492 auto& timeouts = result.back();
1493 timeouts.uid = std::get<0>(tuple);
1494 timeouts.minTimeUs = std::get<1>(tuple);
1495 timeouts.minPendingTimeUs = std::get<2>(tuple);
1496 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1497 }
1498 return result;
1499}
1500
1501static ErrorCode checkPerUidTimeouts(const Control& control,
1502 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1503 std::vector<PerUidReadTimeouts> expected =
1504 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1505 EXPECT_EQ(expected, perUidReadTimeouts);
1506 return 0;
1507}
1508
1509static ErrorCode checkPerUidTimeoutsEmpty(
1510 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1511 EXPECT_EQ(0u, perUidReadTimeouts.size());
1512 return 0;
1513}
1514
1515TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001516 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001517 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1518 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001519 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001520 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1521 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
1522 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1523 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1524 TemporaryDir tempDir;
1525 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001526 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1527 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001528 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001529 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1530 createPerUidTimeouts(
1531 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001532}
1533
1534TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1535 mVold->setIncFsMountOptionsSuccess();
1536 mAppOpsManager->checkPermissionSuccess();
1537 mFs->hasFiles();
1538
1539 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1540 // First call.
1541 .WillOnce(Invoke(&checkPerUidTimeouts))
1542 // Fully loaded and no readlogs.
1543 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1544 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1545
1546 // Empty storage.
1547 mIncFs->countFilledBlocksEmpty();
1548
1549 TemporaryDir tempDir;
1550 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001551 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1552 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001553 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001554 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1555 createPerUidTimeouts(
1556 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001557
1558 {
1559 // Timed callback present -> 0 progress.
1560 ASSERT_EQ(storageId, mTimedQueue->mId);
1561 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1562 const auto timedCallback = mTimedQueue->mWhat;
1563 mTimedQueue->clearJob(storageId);
1564
1565 // Still loading.
1566 mIncFs->countFilledBlocksSuccess();
1567
1568 // Call it again.
1569 timedCallback();
1570 }
1571
1572 {
1573 // Still present -> 0.5 progress.
1574 ASSERT_EQ(storageId, mTimedQueue->mId);
1575 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1576 const auto timedCallback = mTimedQueue->mWhat;
1577 mTimedQueue->clearJob(storageId);
1578
1579 // Fully loaded but readlogs collection enabled.
1580 mIncFs->countFilledBlocksFullyLoaded();
1581 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1582
1583 // Call it again.
1584 timedCallback();
1585 }
1586
1587 {
1588 // Still present -> fully loaded + readlogs.
1589 ASSERT_EQ(storageId, mTimedQueue->mId);
1590 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1591 const auto timedCallback = mTimedQueue->mWhat;
1592 mTimedQueue->clearJob(storageId);
1593
1594 // Now disable readlogs.
1595 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1596
1597 // Call it again.
1598 timedCallback();
1599 }
1600
1601 // No callbacks anymore -> fully loaded and no readlogs.
1602 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1603}
1604
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001605TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) {
1606 const auto invalidStorageId = 100;
1607 android::os::PersistableBundle result{};
1608 mIncrementalService->getMetrics(invalidStorageId, &result);
1609 int64_t expected = -1, value = -1;
1610 ASSERT_FALSE(
1611 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1612 .c_str()),
1613 &value));
1614 ASSERT_EQ(expected, value);
1615 ASSERT_TRUE(result.empty());
1616}
1617
1618TEST_F(IncrementalServiceTest, testNoMetrics) {
1619 mVold->setIncFsMountOptionsSuccess();
1620 TemporaryDir tempDir;
1621 int storageId =
1622 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1623 IncrementalService::CreateOptions::CreateNew);
1624 ASSERT_GE(storageId, 0);
1625 android::os::PersistableBundle result{};
1626 mIncrementalService->getMetrics(storageId, &result);
1627 int64_t expected = -1, value = -1;
1628 ASSERT_FALSE(
1629 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1630 .c_str()),
1631 &value));
1632 ASSERT_EQ(expected, value);
1633 ASSERT_EQ(0, (int)result.size());
1634}
1635
1636TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) {
1637 mVold->setIncFsMountOptionsSuccess();
1638 TemporaryDir tempDir;
1639 int storageId =
1640 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1641 IncrementalService::CreateOptions::CreateNew);
1642 ASSERT_GE(storageId, 0);
1643 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1644 {}, {}));
1645 android::os::PersistableBundle result{};
1646 mIncrementalService->getMetrics(storageId, &result);
1647 int64_t expected = -1, value = -1;
1648 ASSERT_FALSE(result.getLong(String16("invalid"), &value));
1649 ASSERT_EQ(expected, value);
1650 ASSERT_EQ(1, (int)result.size());
1651}
1652
Songchun Fan3c82a302019-11-29 14:23:45 -08001653} // namespace android::os::incremental