blob: bf798273a8a96f356db2ec71ff79713217f1fdc3 [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 Buynytskyy7e06d712021-03-09 19:24:23 -0800251 binder::Status bindToDataLoaderNotOkWithNoDelay(int32_t mountId,
252 const DataLoaderParamsParcel& params,
253 int bindDelayMs,
254 const sp<IDataLoaderStatusListener>& listener,
255 bool* _aidl_return) {
256 CHECK(bindDelayMs == 0) << bindDelayMs;
257 *_aidl_return = false;
258 return binder::Status::ok();
259 }
260 binder::Status bindToDataLoaderBindingWithNoDelay(int32_t mountId,
261 const DataLoaderParamsParcel& params,
262 int bindDelayMs,
263 const sp<IDataLoaderStatusListener>& listener,
264 bool* _aidl_return) {
265 CHECK(bindDelayMs == 0) << bindDelayMs;
266 *_aidl_return = true;
267 if (listener) {
268 listener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BINDING);
269 }
270 return binder::Status::ok();
271 }
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800272 binder::Status bindToDataLoaderOkWith10sDelay(int32_t mountId,
273 const DataLoaderParamsParcel& params,
274 int bindDelayMs,
275 const sp<IDataLoaderStatusListener>& listener,
276 bool* _aidl_return) {
277 CHECK(1000 * 9 <= bindDelayMs && bindDelayMs <= 1000 * 11) << bindDelayMs;
278 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
279 }
280 binder::Status bindToDataLoaderOkWith100sDelay(int32_t mountId,
281 const DataLoaderParamsParcel& params,
282 int bindDelayMs,
283 const sp<IDataLoaderStatusListener>& listener,
284 bool* _aidl_return) {
285 CHECK(1000 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11) << bindDelayMs;
286 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
287 }
288 binder::Status bindToDataLoaderOkWith1000sDelay(int32_t mountId,
289 const DataLoaderParamsParcel& params,
290 int bindDelayMs,
291 const sp<IDataLoaderStatusListener>& listener,
292 bool* _aidl_return) {
293 CHECK(1000 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11) << bindDelayMs;
294 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
295 }
296 binder::Status bindToDataLoaderOkWith10000sDelay(int32_t mountId,
297 const DataLoaderParamsParcel& params,
298 int bindDelayMs,
299 const sp<IDataLoaderStatusListener>& listener,
300 bool* _aidl_return) {
301 CHECK(1000 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 1000 * 11 * 11 * 11 * 11)
302 << bindDelayMs;
303 return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
304 }
305
Songchun Fan68645c42020-02-27 15:57:35 -0800306 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
307 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800308 return binder::Status::ok();
309 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700310 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800311 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800312 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700313 void setDataLoaderStatusStarted() {
314 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
315 }
316 void setDataLoaderStatusDestroyed() {
317 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
318 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700319 void setDataLoaderStatusUnavailable() {
320 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
321 }
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800322 void setDataLoaderStatusUnrecoverable() {
323 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE);
324 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700325 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700326 if (mDataLoader) {
327 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
328 return status;
329 }
330 mDataLoader = nullptr;
331 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700332 if (mListener) {
333 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
334 }
335 return binder::Status::ok();
336 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700337
Songchun Fan3c82a302019-11-29 14:23:45 -0800338private:
339 int mId;
340 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700341 sp<IDataLoader> mDataLoader;
342 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800343};
344
345class MockIncFs : public IncFsWrapper {
346public:
Yurii Zubrytskyia5946f72021-02-17 14:24:14 -0800347 MOCK_CONST_METHOD0(features, Features());
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700348 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
349 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800350 MOCK_CONST_METHOD4(createControl,
351 Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
352 IncFsFd blocksWritten));
Songchun Fan3c82a302019-11-29 14:23:45 -0800353 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800354 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800355 NewFileParams params));
Yurii Zubrytskyia5946f72021-02-17 14:24:14 -0800356 MOCK_CONST_METHOD4(makeMappedFile,
357 ErrorCode(const Control& control, std::string_view path, int mode,
358 NewMappedFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800359 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700360 MOCK_CONST_METHOD3(makeDirs,
361 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800362 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
363 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
364 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan6944f1e2020-11-06 15:24:24 -0800365 MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
Songchun Fan374f7652020-08-20 08:40:29 -0700366 MOCK_CONST_METHOD2(countFilledBlocks,
367 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
368 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800369 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700370 ErrorCode(const Control& control, std::string_view from,
371 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800372 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700373 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700374 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700375 MOCK_CONST_METHOD3(waitForPendingReads,
376 WaitResult(const Control& control, std::chrono::milliseconds timeout,
377 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800378 MOCK_CONST_METHOD2(setUidReadTimeouts,
379 ErrorCode(const Control& control,
380 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700381
382 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800383
384 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
385 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700386
387 void countFilledBlocksSuccess() {
388 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
389 }
390
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700391 void countFilledBlocksFullyLoaded() {
392 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
393 }
394
Songchun Fan374f7652020-08-20 08:40:29 -0700395 void countFilledBlocksFails() {
396 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
397 }
398
399 void countFilledBlocksEmpty() {
400 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
401 }
402
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700403 void openMountSuccess() {
404 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
405 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700406
407 // 1000ms
408 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700409 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700410 .WillByDefault(
411 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
412 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
413 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
414 return android::incfs::WaitResult::HaveData;
415 }));
416 }
417
418 void waitForPendingReadsTimeout() {
419 ON_CALL(*this, waitForPendingReads(_, _, _))
420 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700421 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700422
423 static constexpr auto kPendingReadsFd = 42;
424 Control openMountForHealth(std::string_view) {
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800425 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700426 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700427
Songchun Fan20d6ef22020-03-03 09:47:15 -0800428 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800429 metadata::Mount m;
430 m.mutable_storage()->set_id(100);
431 m.mutable_loader()->set_package_name("com.test");
432 m.mutable_loader()->set_arguments("com.uri");
433 const auto metadata = m.SerializeAsString();
434 m.mutable_loader()->release_arguments();
435 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800436 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800437 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800438 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800439 metadata::Storage st;
440 st.set_id(100);
441 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800442 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800443 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800444 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800445 metadata::BindPoint bp;
446 std::string destPath = "dest";
447 std::string srcPath = "src";
448 bp.set_storage_id(100);
449 bp.set_allocated_dest_path(&destPath);
450 bp.set_allocated_source_subdir(&srcPath);
451 const auto metadata = bp.SerializeAsString();
452 bp.release_source_subdir();
453 bp.release_dest_path();
454 return std::vector<char>(metadata.begin(), metadata.end());
455 }
456};
457
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700458class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700459public:
460 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700461 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700462 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
463
464 void checkPermissionSuccess() {
465 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
466 }
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -0800467 void checkPermissionNoCrossUsers() {
468 ON_CALL(*this,
469 checkPermission("android.permission.LOADER_USAGE_STATS",
470 "android:loader_usage_stats", _))
471 .WillByDefault(Return(android::incremental::Ok()));
472 ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
473 .WillByDefault(
474 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
475 }
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700476 void checkPermissionFails() {
477 ON_CALL(*this, checkPermission(_, _, _))
478 .WillByDefault(
479 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
480 }
481 void initializeStartWatchingMode() {
482 ON_CALL(*this, startWatchingMode(_, _, _))
483 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
484 }
485 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
486 mStoredCallback = cb;
487 }
488
489 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700490};
491
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700492class MockJniWrapper : public JniWrapper {
493public:
494 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
495
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700496 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700497};
498
499class MockLooperWrapper : public LooperWrapper {
500public:
501 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
502 MOCK_METHOD1(removeFd, int(int));
503 MOCK_METHOD0(wake, void());
504 MOCK_METHOD1(pollAll, int(int));
505
506 MockLooperWrapper() {
507 ON_CALL(*this, addFd(_, _, _, _, _))
508 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
509 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700510 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700511 }
512
513 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
514 mCallback = callback;
515 mCallbackData = data;
516 return 0;
517 }
518
519 int clearCallback(int) {
520 mCallback = nullptr;
521 mCallbackData = nullptr;
522 return 0;
523 }
524
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700525 int wait10Ms(int) {
526 // This is called from a loop in runCmdLooper.
527 // Sleeping for 10ms only to avoid busy looping.
528 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700529 return 0;
530 }
531
532 android::Looper_callbackFunc mCallback = nullptr;
533 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700534};
535
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700536class MockTimedQueueWrapper : public TimedQueueWrapper {
537public:
538 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
539 MOCK_METHOD1(removeJobs, void(MountId));
540 MOCK_METHOD0(stop, void());
541
542 MockTimedQueueWrapper() {
543 ON_CALL(*this, addJob(_, _, _))
544 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
545 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
546 }
547
548 void storeJob(MountId id, Milliseconds after, Job what) {
549 mId = id;
550 mAfter = after;
551 mWhat = std::move(what);
552 }
553
554 void clearJob(MountId id) {
555 if (mId == id) {
556 mAfter = {};
557 mWhat = {};
558 }
559 }
560
561 MountId mId = -1;
562 Milliseconds mAfter;
563 Job mWhat;
564};
565
Songchun Fan374f7652020-08-20 08:40:29 -0700566class MockFsWrapper : public FsWrapper {
567public:
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800568 MOCK_CONST_METHOD2(listFilesRecursive, void(std::string_view, FileCallback));
569 void hasNoFile() { ON_CALL(*this, listFilesRecursive(_, _)).WillByDefault(Return()); }
Songchun Fan374f7652020-08-20 08:40:29 -0700570 void hasFiles() {
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800571 ON_CALL(*this, listFilesRecursive(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -0700572 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
573 }
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800574 void fakeFiles(std::string_view directoryPath, FileCallback onFile) {
575 for (auto file : {"base.apk", "split.apk", "lib/a.so"}) {
576 if (!onFile(file)) break;
577 }
Songchun Fan374f7652020-08-20 08:40:29 -0700578 }
579};
580
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800581class MockClockWrapper : public ClockWrapper {
582public:
583 MOCK_CONST_METHOD0(now, TimePoint());
584
585 void start() { ON_CALL(*this, now()).WillByDefault(Invoke(this, &MockClockWrapper::getClock)); }
586 template <class Delta>
587 void advance(Delta delta) {
588 mClock += delta;
589 }
590
591 TimePoint getClock() const { return mClock; }
592
593 TimePoint mClock = Clock::now();
594};
595
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700596class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
597public:
598 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
599
600 MockStorageHealthListener() {
601 ON_CALL(*this, onHealthStatus(_, _))
602 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
603 }
604
605 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
606 mStorageId = storageId;
607 mStatus = status;
608 return binder::Status::ok();
609 }
610
611 int32_t mStorageId = -1;
612 int32_t mStatus = -1;
613};
614
Songchun Fana7098592020-09-03 11:45:53 -0700615class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
616public:
617 MockStorageLoadingProgressListener() = default;
618 MOCK_METHOD2(onStorageLoadingProgressChanged,
619 binder::Status(int32_t storageId, float progress));
620 MOCK_METHOD0(onAsBinder, IBinder*());
621};
622
Songchun Fan3c82a302019-11-29 14:23:45 -0800623class MockServiceManager : public ServiceManagerWrapper {
624public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800625 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700626 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700627 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700628 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700629 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700630 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700631 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700632 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800633 std::unique_ptr<MockFsWrapper> fs, std::unique_ptr<MockClockWrapper> clock)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800634 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700635 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700636 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700637 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700638 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700639 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700640 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700641 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800642 mFs(std::move(fs)),
643 mClock(std::move(clock)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800644 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800645 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
646 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800647 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800648 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700649 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
650 return std::move(mAppOpsManager);
651 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700652 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700653 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700654 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700655 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
656 return std::move(mProgressUpdateJobQueue);
657 }
Songchun Fan374f7652020-08-20 08:40:29 -0700658 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800659 std::unique_ptr<ClockWrapper> getClock() final { return std::move(mClock); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800660
661private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800662 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800663 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800664 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700665 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700666 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700667 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700668 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700669 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700670 std::unique_ptr<MockFsWrapper> mFs;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800671 std::unique_ptr<MockClockWrapper> mClock;
Songchun Fan3c82a302019-11-29 14:23:45 -0800672};
673
674// --- IncrementalServiceTest ---
675
Songchun Fan3c82a302019-11-29 14:23:45 -0800676class IncrementalServiceTest : public testing::Test {
677public:
678 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800679 auto vold = std::make_unique<NiceMock<MockVoldService>>();
680 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700681 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
682 mDataLoader = dataLoader.get();
683 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800684 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800685 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
686 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700687 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
688 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700689 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
690 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700691 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
692 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700693 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
694 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700695 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
696 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700697 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
698 mFs = fs.get();
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800699 auto clock = std::make_unique<NiceMock<MockClockWrapper>>();
700 mClock = clock.get();
Songchun Fana7098592020-09-03 11:45:53 -0700701 mIncrementalService = std::make_unique<
702 IncrementalService>(MockServiceManager(std::move(vold),
703 std::move(dataloaderManager),
704 std::move(incFs), std::move(appOps),
705 std::move(jni), std::move(looper),
706 std::move(timedQueue),
707 std::move(progressUpdateJobQueue),
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800708 std::move(fs), std::move(clock)),
Songchun Fana7098592020-09-03 11:45:53 -0700709 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800710 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800711 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700712 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800713 mIncrementalService->onSystemReady();
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800714 mClock->start();
Songchun Fan374f7652020-08-20 08:40:29 -0700715 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800716 }
717
718 void setUpExistingMountDir(const std::string& rootDir) {
719 const auto dir = rootDir + "/dir1";
720 const auto mountDir = dir + "/mount";
721 const auto backingDir = dir + "/backing_store";
722 const auto storageDir = mountDir + "/st0";
723 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
724 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
725 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
726 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
727 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
728 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
729 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
730 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800731 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
732 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
733 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
734 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
735 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
736 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800737 }
738
Songchun Fan374f7652020-08-20 08:40:29 -0700739 void setupSuccess() {
740 mVold->mountIncFsSuccess();
741 mIncFs->makeFileSuccess();
742 mVold->bindMountSuccess();
743 mDataLoaderManager->bindToDataLoaderSuccess();
744 mDataLoaderManager->getDataLoaderSuccess();
745 }
746
Songchun Fan1b76ccf2021-02-24 22:25:59 +0000747 void checkMillisSinceOldestPendingRead(int storageId, long expected) {
748 android::os::PersistableBundle result{};
749 mIncrementalService->getMetrics(storageId, &result);
750 int64_t value = -1;
751 ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
752 METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
753 .c_str()),
754 &value));
755 ASSERT_EQ(expected, value);
756 ASSERT_EQ(1, (int)result.size());
757 }
758
Songchun Fan3c82a302019-11-29 14:23:45 -0800759protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700760 NiceMock<MockVoldService>* mVold = nullptr;
761 NiceMock<MockIncFs>* mIncFs = nullptr;
762 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
763 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
764 NiceMock<MockJniWrapper>* mJni = nullptr;
765 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700766 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700767 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700768 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800769 NiceMock<MockClockWrapper>* mClock = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700770 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800771 std::unique_ptr<IncrementalService> mIncrementalService;
772 TemporaryDir mRootDir;
773 DataLoaderParamsParcel mDataLoaderParcel;
774};
775
Songchun Fan3c82a302019-11-29 14:23:45 -0800776TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
777 mVold->mountIncFsFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800778 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800779 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800780 int storageId =
781 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
782 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800783 ASSERT_LT(storageId, 0);
784}
785
786TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
787 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800788 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700789 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800790 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800791 int storageId =
792 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
793 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800794 ASSERT_LT(storageId, 0);
795}
796
797TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
798 mVold->mountIncFsSuccess();
799 mIncFs->makeFileFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800800 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700801 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800802 EXPECT_CALL(*mVold, unmountIncFs(_));
803 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800804 int storageId =
805 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
806 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800807 ASSERT_LT(storageId, 0);
808}
809
810TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
811 mVold->mountIncFsSuccess();
812 mIncFs->makeFileSuccess();
813 mVold->bindMountFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800814 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700815 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800816 EXPECT_CALL(*mVold, unmountIncFs(_));
817 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800818 int storageId =
819 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
820 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800821 ASSERT_LT(storageId, 0);
822}
823
824TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
825 mVold->mountIncFsSuccess();
826 mIncFs->makeFileSuccess();
827 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700828 mDataLoaderManager->bindToDataLoaderFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800829 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700830 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700831 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
832 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
833 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800834 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
835 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800836 int storageId =
837 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
838 IncrementalService::CreateOptions::CreateNew);
839 ASSERT_GE(storageId, 0);
840 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800841}
842
843TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700844 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800845 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700846 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800847 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
848 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800849 int storageId =
850 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
851 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800852 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800853 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800854 mIncrementalService->deleteStorage(storageId);
855}
856
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800857TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
858 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(6);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700859 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800860 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
861 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700862 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800863 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);
Songchun Fan3c82a302019-11-29 14:23:45 -0800868 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800869 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800870
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700871 // Simulated crash/other connection breakage.
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800872
873 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
874 .WillByDefault(Invoke(mDataLoaderManager,
875 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
876 mDataLoaderManager->setDataLoaderStatusDestroyed();
877
878 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
879 .WillByDefault(Invoke(mDataLoaderManager,
880 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
881 mDataLoaderManager->setDataLoaderStatusDestroyed();
882
883 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
884 .WillByDefault(Invoke(mDataLoaderManager,
885 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
886 mDataLoaderManager->setDataLoaderStatusDestroyed();
887
888 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
889 .WillByDefault(Invoke(mDataLoaderManager,
890 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
891 mDataLoaderManager->setDataLoaderStatusDestroyed();
892
893 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
894 .WillByDefault(Invoke(mDataLoaderManager,
895 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700896 mDataLoaderManager->setDataLoaderStatusDestroyed();
897}
898
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800899TEST_F(IncrementalServiceTest, testDataLoaderOnRestart) {
900 mIncFs->waitForPendingReadsSuccess();
901 mIncFs->openMountSuccess();
902
903 constexpr auto bindRetryInterval = 5s;
904
905 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(10);
906 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
907 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
908 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
909 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
910 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -0700911 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800912 TemporaryDir tempDir;
913 int storageId =
914 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
915 IncrementalService::CreateOptions::CreateNew);
916 ASSERT_GE(storageId, 0);
917
918 // First binds to DataLoader fails... because it's restart.
919 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
920 .WillByDefault(Invoke(mDataLoaderManager,
921 &MockDataLoaderManager::bindToDataLoaderNotOkWithNoDelay));
922
923 // Request DL start.
924 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
925
926 // Retry callback present.
927 ASSERT_EQ(storageId, mTimedQueue->mId);
928 ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
929 auto retryCallback = mTimedQueue->mWhat;
930 mTimedQueue->clearJob(storageId);
931
932 // Expecting the same bindToDataLoaderNotOkWithNoDelay call.
933 mClock->advance(5s);
934
935 retryCallback();
936 // Retry callback present.
937 ASSERT_EQ(storageId, mTimedQueue->mId);
938 ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
939 retryCallback = mTimedQueue->mWhat;
940 mTimedQueue->clearJob(storageId);
941
942 // Returning "binding" so that we can retry.
943 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
944 .WillByDefault(Invoke(mDataLoaderManager,
945 &MockDataLoaderManager::bindToDataLoaderBindingWithNoDelay));
946
947 // Expecting bindToDataLoaderBindingWithNoDelay call.
948 mClock->advance(5s);
949
950 retryCallback();
951 // No retry callback.
952 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
953 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
954
955 // Should not change the bindToDataLoader call count
956 ASSERT_NE(nullptr, mLooper->mCallback);
957 ASSERT_NE(nullptr, mLooper->mCallbackData);
958 auto looperCb = mLooper->mCallback;
959 auto looperCbData = mLooper->mCallbackData;
960 looperCb(-1, -1, looperCbData);
961
962 // Expecting the same bindToDataLoaderBindingWithNoDelay call.
963 mClock->advance(5s);
964
965 // Use pending reads callback to trigger binding.
966 looperCb(-1, -1, looperCbData);
967
968 // No retry callback.
969 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
970 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
971
972 // Now we are out of 10m "retry" budget, let's finally bind.
973 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
974 .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOk));
975 mClock->advance(11min);
976
977 // Use pending reads callback to trigger binding.
978 looperCb(-1, -1, looperCbData);
979
980 // No retry callback.
981 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
982 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
983
984 // And test the rest of the backoff.
985 // Simulated crash/other connection breakage.
986 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
987 .WillByDefault(Invoke(mDataLoaderManager,
988 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
989 mDataLoaderManager->setDataLoaderStatusDestroyed();
990
991 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
992 .WillByDefault(Invoke(mDataLoaderManager,
993 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
994 mDataLoaderManager->setDataLoaderStatusDestroyed();
995
996 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
997 .WillByDefault(Invoke(mDataLoaderManager,
998 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
999 mDataLoaderManager->setDataLoaderStatusDestroyed();
1000
1001 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1002 .WillByDefault(Invoke(mDataLoaderManager,
1003 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
1004 mDataLoaderManager->setDataLoaderStatusDestroyed();
1005
1006 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1007 .WillByDefault(Invoke(mDataLoaderManager,
1008 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
1009 mDataLoaderManager->setDataLoaderStatusDestroyed();
1010}
1011
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001012TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -07001013 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001014 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001015 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001016 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1017 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1018 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1019 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1020 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001021 int storageId =
1022 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1023 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001024 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001025 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1026 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001027 mDataLoaderManager->setDataLoaderStatusCreated();
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001028 mDataLoaderManager->setDataLoaderStatusStarted();
1029}
1030
1031TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -07001032 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001033 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001034 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001035 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001036 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1037 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1038 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1039 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001040 int storageId =
1041 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1042 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001043 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001044 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1045 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001046 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -08001047}
1048
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001049TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001050 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001051 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001052 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1053 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1054 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1055 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1056 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1057 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001058 int storageId =
1059 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1060 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001061 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001062 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1063 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001064 mDataLoaderManager->setDataLoaderStatusUnavailable();
1065}
1066
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001067TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnrecoverable) {
1068 mDataLoader->initializeCreateOkNoStatus();
1069 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
1070 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1071 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1072 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1073 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1074 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1075 TemporaryDir tempDir;
1076 int storageId =
1077 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1078 IncrementalService::CreateOptions::CreateNew);
1079 ASSERT_GE(storageId, 0);
1080 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1081 {}, {}));
1082 mDataLoaderManager->setDataLoaderStatusUnrecoverable();
1083}
1084
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001085TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001086 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001087 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001088 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -07001089
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001090 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -07001091 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001092 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
1093 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -07001094 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001095 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1096 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
1097 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
1098 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001099 int storageId =
1100 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1101 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001102 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001103 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1104 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001105 mDataLoaderManager->setDataLoaderStatusUnavailable();
1106 ASSERT_NE(nullptr, mLooper->mCallback);
1107 ASSERT_NE(nullptr, mLooper->mCallbackData);
1108 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1109}
1110
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001111TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001112 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001113
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001114 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001115 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1116 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1117 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1118 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1119 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1120 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
1121 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001122 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001123
1124 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1125 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
1126 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
1127 .Times(2);
1128 EXPECT_CALL(*listenerMock,
1129 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1130 .Times(1);
1131 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1132 .Times(1);
1133 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
1134 .Times(2);
1135
1136 StorageHealthCheckParams params;
1137 params.blockedTimeoutMs = 10000;
1138 params.unhealthyTimeoutMs = 20000;
1139 params.unhealthyMonitoringMs = 30000;
1140
1141 using MS = std::chrono::milliseconds;
1142 using MCS = std::chrono::microseconds;
1143
1144 const auto blockedTimeout = MS(params.blockedTimeoutMs);
1145 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
1146 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
1147
1148 const uint64_t kFirstTimestampUs = 1000000000ll;
1149 const uint64_t kBlockedTimestampUs =
1150 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1151 const uint64_t kUnhealthyTimestampUs =
1152 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1153
1154 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001155 int storageId =
1156 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1157 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001158 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001159 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
1160 std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001161
1162 // Healthy state, registered for pending reads.
1163 ASSERT_NE(nullptr, mLooper->mCallback);
1164 ASSERT_NE(nullptr, mLooper->mCallbackData);
1165 ASSERT_EQ(storageId, listener->mStorageId);
1166 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001167 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001168
1169 // Looper/epoll callback.
1170 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1171 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1172
1173 // Unregister from pending reads and wait.
1174 ASSERT_EQ(nullptr, mLooper->mCallback);
1175 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1176 ASSERT_EQ(storageId, listener->mStorageId);
1177 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
1178 // Timed callback present.
1179 ASSERT_EQ(storageId, mTimedQueue->mId);
1180 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
1181 auto timedCallback = mTimedQueue->mWhat;
1182 mTimedQueue->clearJob(storageId);
1183
1184 // Timed job callback for blocked.
1185 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1186 timedCallback();
1187
1188 // Still not registered, and blocked.
1189 ASSERT_EQ(nullptr, mLooper->mCallback);
1190 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1191 ASSERT_EQ(storageId, listener->mStorageId);
1192 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001193 checkMillisSinceOldestPendingRead(storageId, params.blockedTimeoutMs);
1194
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001195 // Timed callback present.
1196 ASSERT_EQ(storageId, mTimedQueue->mId);
1197 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
1198 timedCallback = mTimedQueue->mWhat;
1199 mTimedQueue->clearJob(storageId);
1200
1201 // Timed job callback for unhealthy.
1202 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1203 timedCallback();
1204
1205 // Still not registered, and blocked.
1206 ASSERT_EQ(nullptr, mLooper->mCallback);
1207 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1208 ASSERT_EQ(storageId, listener->mStorageId);
1209 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001210 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1211
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001212 // Timed callback present.
1213 ASSERT_EQ(storageId, mTimedQueue->mId);
1214 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1215 timedCallback = mTimedQueue->mWhat;
1216 mTimedQueue->clearJob(storageId);
1217
1218 // One more unhealthy.
1219 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1220 timedCallback();
1221
1222 // Still not registered, and blocked.
1223 ASSERT_EQ(nullptr, mLooper->mCallback);
1224 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1225 ASSERT_EQ(storageId, listener->mStorageId);
1226 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001227 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1228
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001229 // Timed callback present.
1230 ASSERT_EQ(storageId, mTimedQueue->mId);
1231 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1232 timedCallback = mTimedQueue->mWhat;
1233 mTimedQueue->clearJob(storageId);
1234
1235 // And now healthy.
1236 mIncFs->waitForPendingReadsTimeout();
1237 timedCallback();
1238
1239 // Healthy state, registered for pending reads.
1240 ASSERT_NE(nullptr, mLooper->mCallback);
1241 ASSERT_NE(nullptr, mLooper->mCallbackData);
1242 ASSERT_EQ(storageId, listener->mStorageId);
1243 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001244 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001245}
1246
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001247TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001248 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001249 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001250
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001251 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001252 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001253 // We are calling setIncFsMountOptions(true).
1254 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1255 // After setIncFsMountOptions succeeded expecting to start watching.
1256 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1257 // Not expecting callback removal.
1258 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001259 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001260 int storageId =
1261 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1262 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001263 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001264 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1265 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001266 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001267}
1268
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001269TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001270 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001271 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001272
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001273 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1274 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1275 // Enabling and then disabling readlogs.
1276 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1277 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1278 // After setIncFsMountOptions succeeded expecting to start watching.
1279 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1280 // Not expecting callback removal.
1281 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1282 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001283 int storageId =
1284 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1285 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001286 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001287 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1288 {}, {}));
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001289 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1290 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001291 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001292 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1293}
1294
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001295TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) {
1296 mVold->setIncFsMountOptionsSuccess();
1297 mAppOpsManager->checkPermissionSuccess();
1298
1299 const auto readLogsMaxInterval = 2h;
1300
1301 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1302 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1303 // Enabling and then disabling readlogs.
1304 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(2);
1305 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1306 // After setIncFsMountOptions succeeded expecting to start watching.
1307 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1308 // Not expecting callback removal.
1309 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1310 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
1311 TemporaryDir tempDir;
1312 int storageId =
1313 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1314 IncrementalService::CreateOptions::CreateNew);
1315 ASSERT_GE(storageId, 0);
1316 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1317 {}, {}));
1318
1319 // Disable readlogs callback present.
1320 ASSERT_EQ(storageId, mTimedQueue->mId);
1321 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1322 auto callback = mTimedQueue->mWhat;
1323 mTimedQueue->clearJob(storageId);
1324
1325 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1326 // Now advance clock for 1hr.
1327 mClock->advance(1h);
1328 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1329 // Now call the timed callback, it should turn off the readlogs.
1330 callback();
1331 // Now advance clock for 2hrs.
1332 mClock->advance(readLogsMaxInterval);
1333 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1334}
1335
1336TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) {
1337 mVold->setIncFsMountOptionsSuccess();
1338 mAppOpsManager->checkPermissionSuccess();
1339
1340 const auto readLogsMaxInterval = 2h;
1341
1342 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1343 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1344 // Enabling and then disabling readlogs.
1345 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
1346 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(0);
1347 // After setIncFsMountOptions succeeded expecting to start watching.
1348 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1349 // Not expecting callback removal.
1350 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1351 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1352 // System data loader.
1353 mDataLoaderParcel.packageName = "android";
1354 TemporaryDir tempDir;
1355 int storageId =
1356 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1357 IncrementalService::CreateOptions::CreateNew);
1358 ASSERT_GE(storageId, 0);
1359 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1360 {}, {}));
1361
1362 // No readlogs callback.
1363 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
1364 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
1365
1366 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1367 // Now advance clock for 1hr.
1368 mClock->advance(1h);
1369 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1370 // Now advance clock for 2hrs.
1371 mClock->advance(readLogsMaxInterval);
1372 ASSERT_EQ(mDataLoader->setStorageParams(true), 0);
1373}
1374
1375TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) {
1376 mVold->setIncFsMountOptionsSuccess();
1377 mAppOpsManager->checkPermissionSuccess();
1378
1379 const auto readLogsMaxInterval = 2h;
1380
1381 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
1382 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1383 // Enabling and then disabling readlogs.
1384 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
1385 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1386 // After setIncFsMountOptions succeeded expecting to start watching.
1387 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1388 // Not expecting callback removal.
1389 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1390 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
1391 TemporaryDir tempDir;
1392 int storageId =
1393 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1394 IncrementalService::CreateOptions::CreateNew);
1395 ASSERT_GE(storageId, 0);
1396
1397 auto dataLoaderParcel = mDataLoaderParcel;
1398 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {},
1399 {}, {}));
1400
1401 // Disable readlogs callback present.
1402 ASSERT_EQ(storageId, mTimedQueue->mId);
1403 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1404 auto callback = mTimedQueue->mWhat;
1405 mTimedQueue->clearJob(storageId);
1406
1407 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1408 // Now advance clock for 1.5hrs.
1409 mClock->advance(90min);
1410 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1411
1412 // New installation.
1413 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1414 {}, {}));
1415
1416 // New callback present.
1417 ASSERT_EQ(storageId, mTimedQueue->mId);
1418 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1419 auto callback2 = mTimedQueue->mWhat;
1420 mTimedQueue->clearJob(storageId);
1421
1422 // Old callback should not disable readlogs (setIncFsMountOptions should be called only once).
1423 callback();
1424 // Advance clock for another 1.5hrs.
1425 mClock->advance(90min);
1426 // Still success even it's 3hrs past first install.
1427 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1428
1429 // New one should disable.
1430 callback2();
1431 // And timeout.
1432 mClock->advance(90min);
1433 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1434}
1435
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001436TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001437 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001438 mAppOpsManager->checkPermissionSuccess();
1439 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001440
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001441 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001442 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1443 // We are calling setIncFsMountOptions(true).
1444 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1445 // setIncFsMountOptions(false) is called on the callback.
1446 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1447 // After setIncFsMountOptions succeeded expecting to start watching.
1448 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1449 // After callback is called, disable read logs and remove callback.
1450 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1451 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001452 int storageId =
1453 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1454 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001455 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001456 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1457 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001458 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001459 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1460 mAppOpsManager->mStoredCallback->opChanged(0, {});
1461}
1462
1463TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001464 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001465
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001466 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001467 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1468 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1469 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1470 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1471 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1472 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001473 int storageId =
1474 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1475 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001476 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001477 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1478 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001479 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001480}
1481
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001482TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
1483 mAppOpsManager->checkPermissionNoCrossUsers();
1484
1485 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1486 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1487 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1488 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1489 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1490 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1491 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001492 int storageId =
1493 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1494 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001495 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001496 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1497 {}, {}));
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001498 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1499}
1500
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001501TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001502 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001503 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001504
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001505 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001506 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001507 // We are calling setIncFsMountOptions.
1508 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1509 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1510 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1511 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001512 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001513 int storageId =
1514 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1515 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001516 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001517 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1518 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001519 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001520}
1521
Songchun Fan3c82a302019-11-29 14:23:45 -08001522TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001523 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001524 int storageId =
1525 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1526 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001527 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001528
Songchun Fan103ba1d2020-02-03 17:32:32 -08001529 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001530 // <root>/*/mount/<storage>/test
1531 EXPECT_CALL(*mIncFs,
1532 makeDir(_, Truly([&](std::string_view arg) {
1533 return arg.starts_with(mRootDir.path) &&
1534 arg.ends_with("/mount/st_1_0/" + dir_path);
1535 }),
1536 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001537 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1538 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001539}
1540
1541TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001542 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001543 int storageId =
1544 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1545 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001546 auto first = "first"sv;
1547 auto second = "second"sv;
1548 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001549 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001550
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001551 EXPECT_CALL(*mIncFs,
1552 makeDirs(_, Truly([&](std::string_view arg) {
1553 return arg.starts_with(mRootDir.path) &&
1554 arg.ends_with("/mount/st_1_0/" + dir_path);
1555 }),
1556 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001557 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001558 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001559}
Songchun Fan374f7652020-08-20 08:40:29 -07001560
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001561TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1562 mIncFs->countFilledBlocksFails();
1563 mFs->hasNoFile();
1564
1565 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001566 int storageId =
1567 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1568 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001569 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1570}
1571
1572TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1573 mIncFs->countFilledBlocksFails();
1574 mFs->hasFiles();
1575
1576 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001577 int storageId =
1578 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1579 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001580 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1581 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1582}
1583
1584TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1585 mIncFs->countFilledBlocksEmpty();
1586 mFs->hasFiles();
1587
1588 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001589 int storageId =
1590 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1591 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001592 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1593 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1594}
1595
1596TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1597 mIncFs->countFilledBlocksFullyLoaded();
1598 mFs->hasFiles();
1599
1600 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001601 int storageId =
1602 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1603 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001604 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1605 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1606}
1607
Songchun Fan425862f2020-08-25 13:12:16 -07001608TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001609 mIncFs->countFilledBlocksSuccess();
1610 mFs->hasNoFile();
1611
1612 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001613 int storageId =
1614 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1615 IncrementalService::CreateOptions::CreateNew);
1616 ASSERT_EQ(1,
1617 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1618 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001619}
1620
1621TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1622 mIncFs->countFilledBlocksFails();
1623 mFs->hasFiles();
1624
1625 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001626 int storageId =
1627 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1628 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001629 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001630 ASSERT_EQ(-1,
1631 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1632 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001633}
1634
Songchun Fan425862f2020-08-25 13:12:16 -07001635TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001636 mIncFs->countFilledBlocksEmpty();
1637 mFs->hasFiles();
1638
1639 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001640 int storageId =
1641 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1642 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001643 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001644 ASSERT_EQ(1,
1645 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1646 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001647}
1648
1649TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1650 mIncFs->countFilledBlocksSuccess();
1651 mFs->hasFiles();
1652
1653 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001654 int storageId =
1655 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1656 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001657 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001658 ASSERT_EQ(0.5,
1659 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1660 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001661}
Songchun Fana7098592020-09-03 11:45:53 -07001662
1663TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1664 mIncFs->countFilledBlocksSuccess();
1665 mFs->hasFiles();
1666
1667 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001668 int storageId =
1669 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1670 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001671 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1672 new NiceMock<MockStorageLoadingProgressListener>};
1673 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1674 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1675 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1676 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1677 // Timed callback present.
1678 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1679 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1680 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1681 timedCallback();
1682 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1683 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1684 mIncrementalService->unregisterLoadingProgressListener(storageId);
1685 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1686}
1687
1688TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1689 mIncFs->countFilledBlocksFails();
1690 mFs->hasFiles();
1691
1692 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001693 int storageId =
1694 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1695 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001696 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1697 new NiceMock<MockStorageLoadingProgressListener>};
1698 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1699 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1700 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1701}
Songchun Fan2570ec02020-10-08 17:22:33 -07001702
1703TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1704 mIncFs->openMountSuccess();
1705 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1706 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1707 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1708
1709 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001710 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001711 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1712 IncrementalService::CreateOptions::CreateNew);
Songchun Fan2570ec02020-10-08 17:22:33 -07001713 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001714 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener,
1715 {});
1716
Songchun Fan2570ec02020-10-08 17:22:33 -07001717 StorageHealthCheckParams newParams;
1718 newParams.blockedTimeoutMs = 10000;
1719 newParams.unhealthyTimeoutMs = 20000;
1720 newParams.unhealthyMonitoringMs = 30000;
1721 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1722 newListener));
1723
1724 using MS = std::chrono::milliseconds;
1725 using MCS = std::chrono::microseconds;
1726
1727 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1728 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1729
1730 const uint64_t kFirstTimestampUs = 1000000000ll;
1731 const uint64_t kBlockedTimestampUs =
1732 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1733 const uint64_t kUnhealthyTimestampUs =
1734 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1735
1736 // test that old listener was not called
1737 EXPECT_CALL(*listener.get(),
1738 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1739 .Times(0);
1740 EXPECT_CALL(*newListenerMock,
1741 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1742 .Times(1);
1743 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1744 .Times(1);
1745 EXPECT_CALL(*newListenerMock,
1746 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1747 .Times(1);
1748 EXPECT_CALL(*newListenerMock,
1749 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1750 .Times(1);
1751 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1752 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1753
1754 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1755 ASSERT_EQ(storageId, newListener->mStorageId);
1756
1757 auto timedCallback = mTimedQueue->mWhat;
1758 mTimedQueue->clearJob(storageId);
1759
1760 // test when health status is blocked with transport error
1761 mDataLoader->transportError(storageId);
1762 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1763 timedCallback();
1764 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1765 timedCallback = mTimedQueue->mWhat;
1766 mTimedQueue->clearJob(storageId);
1767
1768 // test when health status is blocked with storage error
1769 mDataLoader->storageError(storageId);
1770 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1771 timedCallback();
1772 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1773 timedCallback = mTimedQueue->mWhat;
1774 mTimedQueue->clearJob(storageId);
1775
1776 // test when health status is unhealthy with transport error
1777 mDataLoader->transportError(storageId);
1778 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1779 timedCallback();
1780 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1781 mTimedQueue->clearJob(storageId);
1782}
1783
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001784static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1785 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1786 std::vector<PerUidReadTimeouts> result;
1787 for (auto&& tuple : tuples) {
1788 result.emplace_back();
1789 auto& timeouts = result.back();
1790 timeouts.uid = std::get<0>(tuple);
1791 timeouts.minTimeUs = std::get<1>(tuple);
1792 timeouts.minPendingTimeUs = std::get<2>(tuple);
1793 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1794 }
1795 return result;
1796}
1797
1798static ErrorCode checkPerUidTimeouts(const Control& control,
1799 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1800 std::vector<PerUidReadTimeouts> expected =
1801 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1802 EXPECT_EQ(expected, perUidReadTimeouts);
1803 return 0;
1804}
1805
1806static ErrorCode checkPerUidTimeoutsEmpty(
1807 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1808 EXPECT_EQ(0u, perUidReadTimeouts.size());
1809 return 0;
1810}
1811
1812TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001813 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001814 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1815 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001816 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001817 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1818 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001819 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001820 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1821 TemporaryDir tempDir;
1822 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001823 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1824 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001825 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001826 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1827 createPerUidTimeouts(
1828 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001829}
1830
1831TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1832 mVold->setIncFsMountOptionsSuccess();
1833 mAppOpsManager->checkPermissionSuccess();
1834 mFs->hasFiles();
1835
1836 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1837 // First call.
1838 .WillOnce(Invoke(&checkPerUidTimeouts))
1839 // Fully loaded and no readlogs.
1840 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1841 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1842
1843 // Empty storage.
1844 mIncFs->countFilledBlocksEmpty();
1845
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001846 // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue.
1847 mDataLoaderParcel.packageName = "android";
1848
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001849 TemporaryDir tempDir;
1850 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001851 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1852 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001853 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001854 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1855 createPerUidTimeouts(
1856 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001857
1858 {
1859 // Timed callback present -> 0 progress.
1860 ASSERT_EQ(storageId, mTimedQueue->mId);
1861 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1862 const auto timedCallback = mTimedQueue->mWhat;
1863 mTimedQueue->clearJob(storageId);
1864
1865 // Still loading.
1866 mIncFs->countFilledBlocksSuccess();
1867
1868 // Call it again.
1869 timedCallback();
1870 }
1871
1872 {
1873 // Still present -> 0.5 progress.
1874 ASSERT_EQ(storageId, mTimedQueue->mId);
1875 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1876 const auto timedCallback = mTimedQueue->mWhat;
1877 mTimedQueue->clearJob(storageId);
1878
1879 // Fully loaded but readlogs collection enabled.
1880 mIncFs->countFilledBlocksFullyLoaded();
1881 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1882
1883 // Call it again.
1884 timedCallback();
1885 }
1886
1887 {
1888 // Still present -> fully loaded + readlogs.
1889 ASSERT_EQ(storageId, mTimedQueue->mId);
1890 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1891 const auto timedCallback = mTimedQueue->mWhat;
1892 mTimedQueue->clearJob(storageId);
1893
1894 // Now disable readlogs.
1895 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1896
1897 // Call it again.
1898 timedCallback();
1899 }
1900
1901 // No callbacks anymore -> fully loaded and no readlogs.
1902 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1903}
1904
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001905TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) {
1906 const auto invalidStorageId = 100;
1907 android::os::PersistableBundle result{};
1908 mIncrementalService->getMetrics(invalidStorageId, &result);
1909 int64_t expected = -1, value = -1;
1910 ASSERT_FALSE(
1911 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1912 .c_str()),
1913 &value));
1914 ASSERT_EQ(expected, value);
1915 ASSERT_TRUE(result.empty());
1916}
1917
1918TEST_F(IncrementalServiceTest, testNoMetrics) {
1919 mVold->setIncFsMountOptionsSuccess();
1920 TemporaryDir tempDir;
1921 int storageId =
1922 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1923 IncrementalService::CreateOptions::CreateNew);
1924 ASSERT_GE(storageId, 0);
1925 android::os::PersistableBundle result{};
1926 mIncrementalService->getMetrics(storageId, &result);
1927 int64_t expected = -1, value = -1;
1928 ASSERT_FALSE(
1929 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1930 .c_str()),
1931 &value));
1932 ASSERT_EQ(expected, value);
1933 ASSERT_EQ(0, (int)result.size());
1934}
1935
1936TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) {
1937 mVold->setIncFsMountOptionsSuccess();
1938 TemporaryDir tempDir;
1939 int storageId =
1940 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1941 IncrementalService::CreateOptions::CreateNew);
1942 ASSERT_GE(storageId, 0);
1943 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1944 {}, {}));
1945 android::os::PersistableBundle result{};
1946 mIncrementalService->getMetrics(storageId, &result);
1947 int64_t expected = -1, value = -1;
1948 ASSERT_FALSE(result.getLong(String16("invalid"), &value));
1949 ASSERT_EQ(expected, value);
1950 ASSERT_EQ(1, (int)result.size());
1951}
1952
Songchun Fan3c82a302019-11-29 14:23:45 -08001953} // namespace android::os::incremental