blob: 50d1e3612cb09fa56946bdf737b037240178c9ac [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 Zubrytskyi256a1a42021-03-18 14:21:54 -0700369 MOCK_CONST_METHOD2(isFileFullyLoaded,
370 incfs::LoadingState(const Control& control, std::string_view path));
371 MOCK_CONST_METHOD1(isEverythingFullyLoaded, incfs::LoadingState(const Control& control));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800372 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700373 ErrorCode(const Control& control, std::string_view from,
374 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800375 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700376 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700377 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Yurii Zubrytskyi65fc38a2021-03-17 13:18:30 -0700378 MOCK_CONST_METHOD3(reserveSpace,
379 ErrorCode(const Control& control, std::string_view path, IncFsSize size));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700380 MOCK_CONST_METHOD3(waitForPendingReads,
381 WaitResult(const Control& control, std::chrono::milliseconds timeout,
382 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800383 MOCK_CONST_METHOD2(setUidReadTimeouts,
384 ErrorCode(const Control& control,
385 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700386
Yurii Zubrytskyi65fc38a2021-03-17 13:18:30 -0700387 MockIncFs() {
388 ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return());
389 ON_CALL(*this, reserveSpace(_, _, _)).WillByDefault(Return(0));
390 }
Songchun Fan3c82a302019-11-29 14:23:45 -0800391
392 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
393 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700394
395 void countFilledBlocksSuccess() {
396 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
397 }
398
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700399 void countFilledBlocksFullyLoaded() {
400 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
401 }
402
Songchun Fan374f7652020-08-20 08:40:29 -0700403 void countFilledBlocksFails() {
404 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
405 }
406
407 void countFilledBlocksEmpty() {
408 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
409 }
410
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700411 void openMountSuccess() {
412 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
413 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700414
415 // 1000ms
416 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700417 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700418 .WillByDefault(
419 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
420 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
421 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
422 return android::incfs::WaitResult::HaveData;
423 }));
424 }
425
426 void waitForPendingReadsTimeout() {
427 ON_CALL(*this, waitForPendingReads(_, _, _))
428 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700429 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700430
431 static constexpr auto kPendingReadsFd = 42;
432 Control openMountForHealth(std::string_view) {
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800433 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700434 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700435
Songchun Fan20d6ef22020-03-03 09:47:15 -0800436 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800437 metadata::Mount m;
438 m.mutable_storage()->set_id(100);
439 m.mutable_loader()->set_package_name("com.test");
440 m.mutable_loader()->set_arguments("com.uri");
441 const auto metadata = m.SerializeAsString();
442 m.mutable_loader()->release_arguments();
443 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800444 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800445 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800446 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800447 metadata::Storage st;
448 st.set_id(100);
449 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800450 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800451 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800452 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800453 metadata::BindPoint bp;
454 std::string destPath = "dest";
455 std::string srcPath = "src";
456 bp.set_storage_id(100);
457 bp.set_allocated_dest_path(&destPath);
458 bp.set_allocated_source_subdir(&srcPath);
459 const auto metadata = bp.SerializeAsString();
460 bp.release_source_subdir();
461 bp.release_dest_path();
462 return std::vector<char>(metadata.begin(), metadata.end());
463 }
464};
465
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700466class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700467public:
468 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700469 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700470 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
471
472 void checkPermissionSuccess() {
473 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
474 }
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -0800475 void checkPermissionNoCrossUsers() {
476 ON_CALL(*this,
477 checkPermission("android.permission.LOADER_USAGE_STATS",
478 "android:loader_usage_stats", _))
479 .WillByDefault(Return(android::incremental::Ok()));
480 ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
481 .WillByDefault(
482 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
483 }
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700484 void checkPermissionFails() {
485 ON_CALL(*this, checkPermission(_, _, _))
486 .WillByDefault(
487 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
488 }
489 void initializeStartWatchingMode() {
490 ON_CALL(*this, startWatchingMode(_, _, _))
491 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
492 }
493 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
494 mStoredCallback = cb;
495 }
496
497 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700498};
499
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700500class MockJniWrapper : public JniWrapper {
501public:
502 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
503
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700504 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700505};
506
507class MockLooperWrapper : public LooperWrapper {
508public:
509 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
510 MOCK_METHOD1(removeFd, int(int));
511 MOCK_METHOD0(wake, void());
512 MOCK_METHOD1(pollAll, int(int));
513
514 MockLooperWrapper() {
515 ON_CALL(*this, addFd(_, _, _, _, _))
516 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
517 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700518 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700519 }
520
521 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
522 mCallback = callback;
523 mCallbackData = data;
524 return 0;
525 }
526
527 int clearCallback(int) {
528 mCallback = nullptr;
529 mCallbackData = nullptr;
530 return 0;
531 }
532
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700533 int wait10Ms(int) {
534 // This is called from a loop in runCmdLooper.
535 // Sleeping for 10ms only to avoid busy looping.
536 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700537 return 0;
538 }
539
540 android::Looper_callbackFunc mCallback = nullptr;
541 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700542};
543
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700544class MockTimedQueueWrapper : public TimedQueueWrapper {
545public:
546 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
547 MOCK_METHOD1(removeJobs, void(MountId));
548 MOCK_METHOD0(stop, void());
549
550 MockTimedQueueWrapper() {
551 ON_CALL(*this, addJob(_, _, _))
552 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
553 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
554 }
555
556 void storeJob(MountId id, Milliseconds after, Job what) {
557 mId = id;
558 mAfter = after;
559 mWhat = std::move(what);
560 }
561
562 void clearJob(MountId id) {
563 if (mId == id) {
564 mAfter = {};
565 mWhat = {};
566 }
567 }
568
569 MountId mId = -1;
570 Milliseconds mAfter;
571 Job mWhat;
572};
573
Songchun Fan374f7652020-08-20 08:40:29 -0700574class MockFsWrapper : public FsWrapper {
575public:
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800576 MOCK_CONST_METHOD2(listFilesRecursive, void(std::string_view, FileCallback));
577 void hasNoFile() { ON_CALL(*this, listFilesRecursive(_, _)).WillByDefault(Return()); }
Songchun Fan374f7652020-08-20 08:40:29 -0700578 void hasFiles() {
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800579 ON_CALL(*this, listFilesRecursive(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -0700580 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
581 }
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800582 void fakeFiles(std::string_view directoryPath, FileCallback onFile) {
583 for (auto file : {"base.apk", "split.apk", "lib/a.so"}) {
584 if (!onFile(file)) break;
585 }
Songchun Fan374f7652020-08-20 08:40:29 -0700586 }
587};
588
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800589class MockClockWrapper : public ClockWrapper {
590public:
591 MOCK_CONST_METHOD0(now, TimePoint());
592
593 void start() { ON_CALL(*this, now()).WillByDefault(Invoke(this, &MockClockWrapper::getClock)); }
594 template <class Delta>
595 void advance(Delta delta) {
596 mClock += delta;
597 }
598
599 TimePoint getClock() const { return mClock; }
600
601 TimePoint mClock = Clock::now();
602};
603
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700604class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
605public:
606 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
607
608 MockStorageHealthListener() {
609 ON_CALL(*this, onHealthStatus(_, _))
610 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
611 }
612
613 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
614 mStorageId = storageId;
615 mStatus = status;
616 return binder::Status::ok();
617 }
618
619 int32_t mStorageId = -1;
620 int32_t mStatus = -1;
621};
622
Songchun Fana7098592020-09-03 11:45:53 -0700623class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
624public:
625 MockStorageLoadingProgressListener() = default;
626 MOCK_METHOD2(onStorageLoadingProgressChanged,
627 binder::Status(int32_t storageId, float progress));
628 MOCK_METHOD0(onAsBinder, IBinder*());
629};
630
Songchun Fan3c82a302019-11-29 14:23:45 -0800631class MockServiceManager : public ServiceManagerWrapper {
632public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800633 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700634 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700635 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700636 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700637 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700638 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700639 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700640 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800641 std::unique_ptr<MockFsWrapper> fs, std::unique_ptr<MockClockWrapper> clock)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800642 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700643 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700644 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700645 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700646 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700647 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700648 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700649 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800650 mFs(std::move(fs)),
651 mClock(std::move(clock)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800652 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800653 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
654 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800655 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800656 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700657 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
658 return std::move(mAppOpsManager);
659 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700660 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700661 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700662 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700663 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
664 return std::move(mProgressUpdateJobQueue);
665 }
Songchun Fan374f7652020-08-20 08:40:29 -0700666 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800667 std::unique_ptr<ClockWrapper> getClock() final { return std::move(mClock); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800668
669private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800670 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800671 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800672 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700673 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700674 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700675 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700676 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700677 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700678 std::unique_ptr<MockFsWrapper> mFs;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800679 std::unique_ptr<MockClockWrapper> mClock;
Songchun Fan3c82a302019-11-29 14:23:45 -0800680};
681
682// --- IncrementalServiceTest ---
683
Songchun Fan3c82a302019-11-29 14:23:45 -0800684class IncrementalServiceTest : public testing::Test {
685public:
686 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800687 auto vold = std::make_unique<NiceMock<MockVoldService>>();
688 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700689 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
690 mDataLoader = dataLoader.get();
691 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800692 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800693 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
694 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700695 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
696 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700697 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
698 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700699 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
700 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700701 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
702 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700703 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
704 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700705 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
706 mFs = fs.get();
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800707 auto clock = std::make_unique<NiceMock<MockClockWrapper>>();
708 mClock = clock.get();
Songchun Fana7098592020-09-03 11:45:53 -0700709 mIncrementalService = std::make_unique<
710 IncrementalService>(MockServiceManager(std::move(vold),
711 std::move(dataloaderManager),
712 std::move(incFs), std::move(appOps),
713 std::move(jni), std::move(looper),
714 std::move(timedQueue),
715 std::move(progressUpdateJobQueue),
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800716 std::move(fs), std::move(clock)),
Songchun Fana7098592020-09-03 11:45:53 -0700717 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800718 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800719 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700720 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800721 mIncrementalService->onSystemReady();
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800722 mClock->start();
Songchun Fan374f7652020-08-20 08:40:29 -0700723 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800724 }
725
726 void setUpExistingMountDir(const std::string& rootDir) {
727 const auto dir = rootDir + "/dir1";
728 const auto mountDir = dir + "/mount";
729 const auto backingDir = dir + "/backing_store";
730 const auto storageDir = mountDir + "/st0";
731 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
732 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
733 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
734 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
735 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
736 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
737 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
738 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800739 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
740 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
741 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
742 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
743 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
744 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800745 }
746
Songchun Fan374f7652020-08-20 08:40:29 -0700747 void setupSuccess() {
748 mVold->mountIncFsSuccess();
749 mIncFs->makeFileSuccess();
750 mVold->bindMountSuccess();
751 mDataLoaderManager->bindToDataLoaderSuccess();
752 mDataLoaderManager->getDataLoaderSuccess();
753 }
754
Songchun Fan1b76ccf2021-02-24 22:25:59 +0000755 void checkMillisSinceOldestPendingRead(int storageId, long expected) {
756 android::os::PersistableBundle result{};
757 mIncrementalService->getMetrics(storageId, &result);
758 int64_t value = -1;
759 ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
760 METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
761 .c_str()),
762 &value));
763 ASSERT_EQ(expected, value);
764 ASSERT_EQ(1, (int)result.size());
765 }
766
Songchun Fan3c82a302019-11-29 14:23:45 -0800767protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700768 NiceMock<MockVoldService>* mVold = nullptr;
769 NiceMock<MockIncFs>* mIncFs = nullptr;
770 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
771 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
772 NiceMock<MockJniWrapper>* mJni = nullptr;
773 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700774 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700775 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700776 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800777 NiceMock<MockClockWrapper>* mClock = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700778 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800779 std::unique_ptr<IncrementalService> mIncrementalService;
780 TemporaryDir mRootDir;
781 DataLoaderParamsParcel mDataLoaderParcel;
782};
783
Songchun Fan3c82a302019-11-29 14:23:45 -0800784TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
785 mVold->mountIncFsFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800786 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800787 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800788 int storageId =
789 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
790 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800791 ASSERT_LT(storageId, 0);
792}
793
794TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
795 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800796 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700797 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800798 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800799 int storageId =
800 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
801 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800802 ASSERT_LT(storageId, 0);
803}
804
805TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
806 mVold->mountIncFsSuccess();
807 mIncFs->makeFileFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800808 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700809 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800810 EXPECT_CALL(*mVold, unmountIncFs(_));
811 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800812 int storageId =
813 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
814 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800815 ASSERT_LT(storageId, 0);
816}
817
818TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
819 mVold->mountIncFsSuccess();
820 mIncFs->makeFileSuccess();
821 mVold->bindMountFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800822 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700823 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800824 EXPECT_CALL(*mVold, unmountIncFs(_));
825 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800826 int storageId =
827 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
828 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800829 ASSERT_LT(storageId, 0);
830}
831
832TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
833 mVold->mountIncFsSuccess();
834 mIncFs->makeFileSuccess();
835 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700836 mDataLoaderManager->bindToDataLoaderFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800837 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700838 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700839 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
840 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
841 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800842 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
843 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800844 int storageId =
845 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
846 IncrementalService::CreateOptions::CreateNew);
847 ASSERT_GE(storageId, 0);
848 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800849}
850
851TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700852 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800853 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700854 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800855 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
856 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800857 int storageId =
858 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
859 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800860 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800861 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800862 mIncrementalService->deleteStorage(storageId);
863}
864
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800865TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
866 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(6);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700867 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800868 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
869 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700870 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800871 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
872 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800873 int storageId =
874 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
875 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800876 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800877 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800878
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700879 // Simulated crash/other connection breakage.
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800880
881 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
882 .WillByDefault(Invoke(mDataLoaderManager,
883 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
884 mDataLoaderManager->setDataLoaderStatusDestroyed();
885
886 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
887 .WillByDefault(Invoke(mDataLoaderManager,
888 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
889 mDataLoaderManager->setDataLoaderStatusDestroyed();
890
891 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
892 .WillByDefault(Invoke(mDataLoaderManager,
893 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
894 mDataLoaderManager->setDataLoaderStatusDestroyed();
895
896 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
897 .WillByDefault(Invoke(mDataLoaderManager,
898 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
899 mDataLoaderManager->setDataLoaderStatusDestroyed();
900
901 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
902 .WillByDefault(Invoke(mDataLoaderManager,
903 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700904 mDataLoaderManager->setDataLoaderStatusDestroyed();
905}
906
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800907TEST_F(IncrementalServiceTest, testDataLoaderOnRestart) {
908 mIncFs->waitForPendingReadsSuccess();
909 mIncFs->openMountSuccess();
910
911 constexpr auto bindRetryInterval = 5s;
912
913 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(10);
914 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
915 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
916 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
917 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
918 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -0700919 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800920 TemporaryDir tempDir;
921 int storageId =
922 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
923 IncrementalService::CreateOptions::CreateNew);
924 ASSERT_GE(storageId, 0);
925
926 // First binds to DataLoader fails... because it's restart.
927 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
928 .WillByDefault(Invoke(mDataLoaderManager,
929 &MockDataLoaderManager::bindToDataLoaderNotOkWithNoDelay));
930
931 // Request DL start.
932 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
933
934 // Retry callback present.
935 ASSERT_EQ(storageId, mTimedQueue->mId);
936 ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
937 auto retryCallback = mTimedQueue->mWhat;
938 mTimedQueue->clearJob(storageId);
939
940 // Expecting the same bindToDataLoaderNotOkWithNoDelay call.
941 mClock->advance(5s);
942
943 retryCallback();
944 // Retry callback present.
945 ASSERT_EQ(storageId, mTimedQueue->mId);
946 ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
947 retryCallback = mTimedQueue->mWhat;
948 mTimedQueue->clearJob(storageId);
949
950 // Returning "binding" so that we can retry.
951 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
952 .WillByDefault(Invoke(mDataLoaderManager,
953 &MockDataLoaderManager::bindToDataLoaderBindingWithNoDelay));
954
955 // Expecting bindToDataLoaderBindingWithNoDelay call.
956 mClock->advance(5s);
957
958 retryCallback();
959 // No retry callback.
960 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
961 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
962
963 // Should not change the bindToDataLoader call count
964 ASSERT_NE(nullptr, mLooper->mCallback);
965 ASSERT_NE(nullptr, mLooper->mCallbackData);
966 auto looperCb = mLooper->mCallback;
967 auto looperCbData = mLooper->mCallbackData;
968 looperCb(-1, -1, looperCbData);
969
970 // Expecting the same bindToDataLoaderBindingWithNoDelay call.
971 mClock->advance(5s);
972
973 // Use pending reads callback to trigger binding.
974 looperCb(-1, -1, looperCbData);
975
976 // No retry callback.
977 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
978 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
979
980 // Now we are out of 10m "retry" budget, let's finally bind.
981 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
982 .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOk));
983 mClock->advance(11min);
984
985 // Use pending reads callback to trigger binding.
986 looperCb(-1, -1, looperCbData);
987
988 // No retry callback.
989 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
990 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
991
992 // And test the rest of the backoff.
993 // Simulated crash/other connection breakage.
994 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
995 .WillByDefault(Invoke(mDataLoaderManager,
996 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
997 mDataLoaderManager->setDataLoaderStatusDestroyed();
998
999 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1000 .WillByDefault(Invoke(mDataLoaderManager,
1001 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
1002 mDataLoaderManager->setDataLoaderStatusDestroyed();
1003
1004 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1005 .WillByDefault(Invoke(mDataLoaderManager,
1006 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
1007 mDataLoaderManager->setDataLoaderStatusDestroyed();
1008
1009 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1010 .WillByDefault(Invoke(mDataLoaderManager,
1011 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
1012 mDataLoaderManager->setDataLoaderStatusDestroyed();
1013
1014 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1015 .WillByDefault(Invoke(mDataLoaderManager,
1016 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
1017 mDataLoaderManager->setDataLoaderStatusDestroyed();
1018}
1019
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001020TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -07001021 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001022 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001023 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001024 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1025 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1026 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1027 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1028 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001029 int storageId =
1030 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1031 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001032 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001033 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1034 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001035 mDataLoaderManager->setDataLoaderStatusCreated();
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001036 mDataLoaderManager->setDataLoaderStatusStarted();
1037}
1038
1039TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -07001040 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001041 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001042 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001043 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001044 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1045 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1046 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1047 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001048 int storageId =
1049 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1050 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001051 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001052 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1053 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001054 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -08001055}
1056
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001057TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001058 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001059 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001060 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1061 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1062 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1063 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1064 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1065 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001066 int storageId =
1067 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1068 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001069 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001070 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1071 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001072 mDataLoaderManager->setDataLoaderStatusUnavailable();
1073}
1074
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001075TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnrecoverable) {
1076 mDataLoader->initializeCreateOkNoStatus();
1077 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
1078 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1079 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1080 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1081 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1082 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1083 TemporaryDir tempDir;
1084 int storageId =
1085 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1086 IncrementalService::CreateOptions::CreateNew);
1087 ASSERT_GE(storageId, 0);
1088 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1089 {}, {}));
1090 mDataLoaderManager->setDataLoaderStatusUnrecoverable();
1091}
1092
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001093TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001094 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001095 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001096 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -07001097
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001098 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -07001099 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001100 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
1101 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -07001102 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001103 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1104 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
1105 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
1106 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001107 int storageId =
1108 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1109 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001110 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001111 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1112 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001113 mDataLoaderManager->setDataLoaderStatusUnavailable();
1114 ASSERT_NE(nullptr, mLooper->mCallback);
1115 ASSERT_NE(nullptr, mLooper->mCallbackData);
1116 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1117}
1118
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001119TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001120 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001121
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001122 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001123 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1124 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1125 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1126 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1127 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1128 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
1129 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001130 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001131
1132 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1133 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
1134 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
1135 .Times(2);
1136 EXPECT_CALL(*listenerMock,
1137 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1138 .Times(1);
1139 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1140 .Times(1);
1141 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
1142 .Times(2);
1143
1144 StorageHealthCheckParams params;
1145 params.blockedTimeoutMs = 10000;
1146 params.unhealthyTimeoutMs = 20000;
1147 params.unhealthyMonitoringMs = 30000;
1148
1149 using MS = std::chrono::milliseconds;
1150 using MCS = std::chrono::microseconds;
1151
1152 const auto blockedTimeout = MS(params.blockedTimeoutMs);
1153 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
1154 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
1155
1156 const uint64_t kFirstTimestampUs = 1000000000ll;
1157 const uint64_t kBlockedTimestampUs =
1158 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1159 const uint64_t kUnhealthyTimestampUs =
1160 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1161
1162 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001163 int storageId =
1164 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1165 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001166 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001167 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
1168 std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001169
1170 // Healthy state, registered for pending reads.
1171 ASSERT_NE(nullptr, mLooper->mCallback);
1172 ASSERT_NE(nullptr, mLooper->mCallbackData);
1173 ASSERT_EQ(storageId, listener->mStorageId);
1174 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001175 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001176
1177 // Looper/epoll callback.
1178 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1179 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1180
1181 // Unregister from pending reads and wait.
1182 ASSERT_EQ(nullptr, mLooper->mCallback);
1183 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1184 ASSERT_EQ(storageId, listener->mStorageId);
1185 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
1186 // Timed callback present.
1187 ASSERT_EQ(storageId, mTimedQueue->mId);
1188 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
1189 auto timedCallback = mTimedQueue->mWhat;
1190 mTimedQueue->clearJob(storageId);
1191
1192 // Timed job callback for blocked.
1193 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1194 timedCallback();
1195
1196 // Still not registered, and blocked.
1197 ASSERT_EQ(nullptr, mLooper->mCallback);
1198 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1199 ASSERT_EQ(storageId, listener->mStorageId);
1200 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001201 checkMillisSinceOldestPendingRead(storageId, params.blockedTimeoutMs);
1202
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001203 // Timed callback present.
1204 ASSERT_EQ(storageId, mTimedQueue->mId);
1205 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
1206 timedCallback = mTimedQueue->mWhat;
1207 mTimedQueue->clearJob(storageId);
1208
1209 // Timed job callback for unhealthy.
1210 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1211 timedCallback();
1212
1213 // Still not registered, and blocked.
1214 ASSERT_EQ(nullptr, mLooper->mCallback);
1215 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1216 ASSERT_EQ(storageId, listener->mStorageId);
1217 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001218 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1219
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001220 // Timed callback present.
1221 ASSERT_EQ(storageId, mTimedQueue->mId);
1222 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1223 timedCallback = mTimedQueue->mWhat;
1224 mTimedQueue->clearJob(storageId);
1225
1226 // One more unhealthy.
1227 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1228 timedCallback();
1229
1230 // Still not registered, and blocked.
1231 ASSERT_EQ(nullptr, mLooper->mCallback);
1232 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1233 ASSERT_EQ(storageId, listener->mStorageId);
1234 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001235 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1236
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001237 // Timed callback present.
1238 ASSERT_EQ(storageId, mTimedQueue->mId);
1239 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1240 timedCallback = mTimedQueue->mWhat;
1241 mTimedQueue->clearJob(storageId);
1242
1243 // And now healthy.
1244 mIncFs->waitForPendingReadsTimeout();
1245 timedCallback();
1246
1247 // Healthy state, registered for pending reads.
1248 ASSERT_NE(nullptr, mLooper->mCallback);
1249 ASSERT_NE(nullptr, mLooper->mCallbackData);
1250 ASSERT_EQ(storageId, listener->mStorageId);
1251 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001252 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001253}
1254
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001255TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001256 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001257 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001258
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001259 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001260 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001261 // We are calling setIncFsMountOptions(true).
1262 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1263 // After setIncFsMountOptions succeeded expecting to start watching.
1264 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1265 // Not expecting callback removal.
1266 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001267 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001268 int storageId =
1269 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1270 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001271 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001272 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1273 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001274 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001275}
1276
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001277TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001278 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001279 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001280
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001281 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1282 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1283 // Enabling and then disabling readlogs.
1284 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1285 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1286 // After setIncFsMountOptions succeeded expecting to start watching.
1287 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1288 // Not expecting callback removal.
1289 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1290 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001291 int storageId =
1292 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1293 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001294 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001295 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1296 {}, {}));
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001297 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1298 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001299 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001300 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1301}
1302
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001303TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) {
1304 mVold->setIncFsMountOptionsSuccess();
1305 mAppOpsManager->checkPermissionSuccess();
1306
1307 const auto readLogsMaxInterval = 2h;
1308
1309 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1310 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1311 // Enabling and then disabling readlogs.
1312 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(2);
1313 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1314 // After setIncFsMountOptions succeeded expecting to start watching.
1315 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1316 // Not expecting callback removal.
1317 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1318 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
1319 TemporaryDir tempDir;
1320 int storageId =
1321 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1322 IncrementalService::CreateOptions::CreateNew);
1323 ASSERT_GE(storageId, 0);
1324 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1325 {}, {}));
1326
1327 // Disable readlogs callback present.
1328 ASSERT_EQ(storageId, mTimedQueue->mId);
1329 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1330 auto callback = mTimedQueue->mWhat;
1331 mTimedQueue->clearJob(storageId);
1332
1333 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1334 // Now advance clock for 1hr.
1335 mClock->advance(1h);
1336 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1337 // Now call the timed callback, it should turn off the readlogs.
1338 callback();
1339 // Now advance clock for 2hrs.
1340 mClock->advance(readLogsMaxInterval);
1341 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1342}
1343
1344TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) {
1345 mVold->setIncFsMountOptionsSuccess();
1346 mAppOpsManager->checkPermissionSuccess();
1347
1348 const auto readLogsMaxInterval = 2h;
1349
1350 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1351 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1352 // Enabling and then disabling readlogs.
1353 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
1354 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(0);
1355 // After setIncFsMountOptions succeeded expecting to start watching.
1356 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1357 // Not expecting callback removal.
1358 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1359 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1360 // System data loader.
1361 mDataLoaderParcel.packageName = "android";
1362 TemporaryDir tempDir;
1363 int storageId =
1364 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1365 IncrementalService::CreateOptions::CreateNew);
1366 ASSERT_GE(storageId, 0);
1367 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1368 {}, {}));
1369
1370 // No readlogs callback.
1371 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
1372 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
1373
1374 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1375 // Now advance clock for 1hr.
1376 mClock->advance(1h);
1377 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1378 // Now advance clock for 2hrs.
1379 mClock->advance(readLogsMaxInterval);
1380 ASSERT_EQ(mDataLoader->setStorageParams(true), 0);
1381}
1382
1383TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) {
1384 mVold->setIncFsMountOptionsSuccess();
1385 mAppOpsManager->checkPermissionSuccess();
1386
1387 const auto readLogsMaxInterval = 2h;
1388
1389 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
1390 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1391 // Enabling and then disabling readlogs.
1392 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
1393 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1394 // After setIncFsMountOptions succeeded expecting to start watching.
1395 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1396 // Not expecting callback removal.
1397 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1398 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
1399 TemporaryDir tempDir;
1400 int storageId =
1401 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1402 IncrementalService::CreateOptions::CreateNew);
1403 ASSERT_GE(storageId, 0);
1404
1405 auto dataLoaderParcel = mDataLoaderParcel;
1406 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {},
1407 {}, {}));
1408
1409 // Disable readlogs callback present.
1410 ASSERT_EQ(storageId, mTimedQueue->mId);
1411 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1412 auto callback = mTimedQueue->mWhat;
1413 mTimedQueue->clearJob(storageId);
1414
1415 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1416 // Now advance clock for 1.5hrs.
1417 mClock->advance(90min);
1418 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1419
1420 // New installation.
1421 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1422 {}, {}));
1423
1424 // New callback present.
1425 ASSERT_EQ(storageId, mTimedQueue->mId);
1426 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1427 auto callback2 = mTimedQueue->mWhat;
1428 mTimedQueue->clearJob(storageId);
1429
1430 // Old callback should not disable readlogs (setIncFsMountOptions should be called only once).
1431 callback();
1432 // Advance clock for another 1.5hrs.
1433 mClock->advance(90min);
1434 // Still success even it's 3hrs past first install.
1435 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1436
1437 // New one should disable.
1438 callback2();
1439 // And timeout.
1440 mClock->advance(90min);
1441 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1442}
1443
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001444TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001445 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001446 mAppOpsManager->checkPermissionSuccess();
1447 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001448
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001449 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001450 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1451 // We are calling setIncFsMountOptions(true).
1452 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1453 // setIncFsMountOptions(false) is called on the callback.
1454 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1455 // After setIncFsMountOptions succeeded expecting to start watching.
1456 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1457 // After callback is called, disable read logs and remove callback.
1458 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1459 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001460 int storageId =
1461 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1462 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001463 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001464 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1465 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001466 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001467 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1468 mAppOpsManager->mStoredCallback->opChanged(0, {});
1469}
1470
1471TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001472 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001473
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001474 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001475 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1476 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1477 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1478 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1479 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1480 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001481 int storageId =
1482 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1483 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001484 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001485 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1486 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001487 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001488}
1489
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001490TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
1491 mAppOpsManager->checkPermissionNoCrossUsers();
1492
1493 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1494 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1495 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1496 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1497 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1498 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1499 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001500 int storageId =
1501 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1502 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001503 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001504 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1505 {}, {}));
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001506 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1507}
1508
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001509TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001510 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001511 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001512
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001513 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001514 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001515 // We are calling setIncFsMountOptions.
1516 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1517 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1518 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1519 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001520 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001521 int storageId =
1522 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1523 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001524 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001525 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1526 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001527 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001528}
1529
Songchun Fan3c82a302019-11-29 14:23:45 -08001530TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001531 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001532 int storageId =
1533 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1534 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001535 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001536
Songchun Fan103ba1d2020-02-03 17:32:32 -08001537 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001538 // <root>/*/mount/<storage>/test
1539 EXPECT_CALL(*mIncFs,
1540 makeDir(_, Truly([&](std::string_view arg) {
1541 return arg.starts_with(mRootDir.path) &&
1542 arg.ends_with("/mount/st_1_0/" + dir_path);
1543 }),
1544 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001545 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1546 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001547}
1548
1549TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001550 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001551 int storageId =
1552 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1553 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001554 auto first = "first"sv;
1555 auto second = "second"sv;
1556 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001557 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001558
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001559 EXPECT_CALL(*mIncFs,
1560 makeDirs(_, Truly([&](std::string_view arg) {
1561 return arg.starts_with(mRootDir.path) &&
1562 arg.ends_with("/mount/st_1_0/" + dir_path);
1563 }),
1564 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001565 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001566 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001567}
Songchun Fan374f7652020-08-20 08:40:29 -07001568
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001569TEST_F(IncrementalServiceTest, testIsFileFullyLoadedNoData) {
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001570 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001571 int storageId =
1572 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1573 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001574 EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
1575 .Times(1)
1576 .WillOnce(Return(incfs::LoadingState::MissingBlocks));
1577 ASSERT_GT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001578}
1579
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001580TEST_F(IncrementalServiceTest, testIsFileFullyLoadedError) {
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001581 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001582 int storageId =
1583 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1584 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001585 EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
1586 .Times(1)
1587 .WillOnce(Return(incfs::LoadingState(-1)));
1588 ASSERT_LT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001589}
1590
1591TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001592 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001593 int storageId =
1594 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1595 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001596 EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
1597 .Times(1)
1598 .WillOnce(Return(incfs::LoadingState::Full));
1599 ASSERT_EQ(0, (int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001600}
1601
Songchun Fan425862f2020-08-25 13:12:16 -07001602TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001603 mIncFs->countFilledBlocksSuccess();
1604 mFs->hasNoFile();
1605
1606 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001607 int storageId =
1608 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1609 IncrementalService::CreateOptions::CreateNew);
1610 ASSERT_EQ(1,
1611 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1612 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001613}
1614
1615TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1616 mIncFs->countFilledBlocksFails();
1617 mFs->hasFiles();
1618
1619 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001620 int storageId =
1621 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1622 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001623 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001624 ASSERT_EQ(-1,
1625 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1626 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001627}
1628
Songchun Fan425862f2020-08-25 13:12:16 -07001629TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001630 mIncFs->countFilledBlocksEmpty();
1631 mFs->hasFiles();
1632
1633 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001634 int storageId =
1635 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1636 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001637 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001638 ASSERT_EQ(1,
1639 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1640 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001641}
1642
1643TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1644 mIncFs->countFilledBlocksSuccess();
1645 mFs->hasFiles();
1646
1647 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001648 int storageId =
1649 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1650 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001651 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001652 ASSERT_EQ(0.5,
1653 mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false)
1654 .getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001655}
Songchun Fana7098592020-09-03 11:45:53 -07001656
1657TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1658 mIncFs->countFilledBlocksSuccess();
1659 mFs->hasFiles();
1660
1661 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001662 int storageId =
1663 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1664 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001665 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1666 new NiceMock<MockStorageLoadingProgressListener>};
1667 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1668 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1669 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1670 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1671 // Timed callback present.
1672 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1673 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1674 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1675 timedCallback();
1676 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1677 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1678 mIncrementalService->unregisterLoadingProgressListener(storageId);
1679 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1680}
1681
1682TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1683 mIncFs->countFilledBlocksFails();
1684 mFs->hasFiles();
1685
1686 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001687 int storageId =
1688 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1689 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001690 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1691 new NiceMock<MockStorageLoadingProgressListener>};
1692 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1693 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1694 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1695}
Songchun Fan2570ec02020-10-08 17:22:33 -07001696
1697TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1698 mIncFs->openMountSuccess();
1699 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1700 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1701 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1702
1703 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001704 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001705 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1706 IncrementalService::CreateOptions::CreateNew);
Songchun Fan2570ec02020-10-08 17:22:33 -07001707 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001708 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener,
1709 {});
1710
Songchun Fan2570ec02020-10-08 17:22:33 -07001711 StorageHealthCheckParams newParams;
1712 newParams.blockedTimeoutMs = 10000;
1713 newParams.unhealthyTimeoutMs = 20000;
1714 newParams.unhealthyMonitoringMs = 30000;
1715 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1716 newListener));
1717
1718 using MS = std::chrono::milliseconds;
1719 using MCS = std::chrono::microseconds;
1720
1721 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1722 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1723
1724 const uint64_t kFirstTimestampUs = 1000000000ll;
1725 const uint64_t kBlockedTimestampUs =
1726 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1727 const uint64_t kUnhealthyTimestampUs =
1728 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1729
1730 // test that old listener was not called
1731 EXPECT_CALL(*listener.get(),
1732 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1733 .Times(0);
1734 EXPECT_CALL(*newListenerMock,
1735 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1736 .Times(1);
1737 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1738 .Times(1);
1739 EXPECT_CALL(*newListenerMock,
1740 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1741 .Times(1);
1742 EXPECT_CALL(*newListenerMock,
1743 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1744 .Times(1);
1745 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1746 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1747
1748 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1749 ASSERT_EQ(storageId, newListener->mStorageId);
1750
1751 auto timedCallback = mTimedQueue->mWhat;
1752 mTimedQueue->clearJob(storageId);
1753
1754 // test when health status is blocked with transport error
1755 mDataLoader->transportError(storageId);
1756 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1757 timedCallback();
1758 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1759 timedCallback = mTimedQueue->mWhat;
1760 mTimedQueue->clearJob(storageId);
1761
1762 // test when health status is blocked with storage error
1763 mDataLoader->storageError(storageId);
1764 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1765 timedCallback();
1766 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1767 timedCallback = mTimedQueue->mWhat;
1768 mTimedQueue->clearJob(storageId);
1769
1770 // test when health status is unhealthy with transport error
1771 mDataLoader->transportError(storageId);
1772 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1773 timedCallback();
1774 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1775 mTimedQueue->clearJob(storageId);
1776}
1777
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001778static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1779 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1780 std::vector<PerUidReadTimeouts> result;
1781 for (auto&& tuple : tuples) {
1782 result.emplace_back();
1783 auto& timeouts = result.back();
1784 timeouts.uid = std::get<0>(tuple);
1785 timeouts.minTimeUs = std::get<1>(tuple);
1786 timeouts.minPendingTimeUs = std::get<2>(tuple);
1787 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1788 }
1789 return result;
1790}
1791
1792static ErrorCode checkPerUidTimeouts(const Control& control,
1793 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1794 std::vector<PerUidReadTimeouts> expected =
1795 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1796 EXPECT_EQ(expected, perUidReadTimeouts);
1797 return 0;
1798}
1799
1800static ErrorCode checkPerUidTimeoutsEmpty(
1801 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1802 EXPECT_EQ(0u, perUidReadTimeouts.size());
1803 return 0;
1804}
1805
1806TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001807 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001808 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1809 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001810 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001811 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1812 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001813 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001814 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1815 TemporaryDir tempDir;
1816 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001817 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1818 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001819 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001820 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1821 createPerUidTimeouts(
1822 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001823}
1824
1825TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1826 mVold->setIncFsMountOptionsSuccess();
1827 mAppOpsManager->checkPermissionSuccess();
1828 mFs->hasFiles();
1829
1830 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1831 // First call.
1832 .WillOnce(Invoke(&checkPerUidTimeouts))
1833 // Fully loaded and no readlogs.
1834 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1835 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1836
1837 // Empty storage.
1838 mIncFs->countFilledBlocksEmpty();
1839
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001840 // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue.
1841 mDataLoaderParcel.packageName = "android";
1842
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001843 TemporaryDir tempDir;
1844 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001845 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1846 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001847 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001848 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1849 createPerUidTimeouts(
1850 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001851
1852 {
1853 // Timed callback present -> 0 progress.
1854 ASSERT_EQ(storageId, mTimedQueue->mId);
1855 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1856 const auto timedCallback = mTimedQueue->mWhat;
1857 mTimedQueue->clearJob(storageId);
1858
1859 // Still loading.
1860 mIncFs->countFilledBlocksSuccess();
1861
1862 // Call it again.
1863 timedCallback();
1864 }
1865
1866 {
1867 // Still present -> 0.5 progress.
1868 ASSERT_EQ(storageId, mTimedQueue->mId);
1869 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1870 const auto timedCallback = mTimedQueue->mWhat;
1871 mTimedQueue->clearJob(storageId);
1872
1873 // Fully loaded but readlogs collection enabled.
1874 mIncFs->countFilledBlocksFullyLoaded();
1875 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1876
1877 // Call it again.
1878 timedCallback();
1879 }
1880
1881 {
1882 // Still present -> fully loaded + readlogs.
1883 ASSERT_EQ(storageId, mTimedQueue->mId);
1884 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1885 const auto timedCallback = mTimedQueue->mWhat;
1886 mTimedQueue->clearJob(storageId);
1887
1888 // Now disable readlogs.
1889 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1890
1891 // Call it again.
1892 timedCallback();
1893 }
1894
1895 // No callbacks anymore -> fully loaded and no readlogs.
1896 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1897}
1898
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001899TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) {
1900 const auto invalidStorageId = 100;
1901 android::os::PersistableBundle result{};
1902 mIncrementalService->getMetrics(invalidStorageId, &result);
1903 int64_t expected = -1, value = -1;
1904 ASSERT_FALSE(
1905 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1906 .c_str()),
1907 &value));
1908 ASSERT_EQ(expected, value);
1909 ASSERT_TRUE(result.empty());
1910}
1911
1912TEST_F(IncrementalServiceTest, testNoMetrics) {
1913 mVold->setIncFsMountOptionsSuccess();
1914 TemporaryDir tempDir;
1915 int storageId =
1916 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1917 IncrementalService::CreateOptions::CreateNew);
1918 ASSERT_GE(storageId, 0);
1919 android::os::PersistableBundle result{};
1920 mIncrementalService->getMetrics(storageId, &result);
1921 int64_t expected = -1, value = -1;
1922 ASSERT_FALSE(
1923 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1924 .c_str()),
1925 &value));
1926 ASSERT_EQ(expected, value);
1927 ASSERT_EQ(0, (int)result.size());
1928}
1929
1930TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) {
1931 mVold->setIncFsMountOptionsSuccess();
1932 TemporaryDir tempDir;
1933 int storageId =
1934 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1935 IncrementalService::CreateOptions::CreateNew);
1936 ASSERT_GE(storageId, 0);
1937 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1938 {}, {}));
1939 android::os::PersistableBundle result{};
1940 mIncrementalService->getMetrics(storageId, &result);
1941 int64_t expected = -1, value = -1;
1942 ASSERT_FALSE(result.getLong(String16("invalid"), &value));
1943 ASSERT_EQ(expected, value);
1944 ASSERT_EQ(1, (int)result.size());
1945}
1946
Songchun Fan3c82a302019-11-29 14:23:45 -08001947} // namespace android::os::incremental