blob: 54bc95dc213ba51119ede5e65b357e98136a8b71 [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 Fan374f7652020-08-20 08:40:29 -0700365 MOCK_CONST_METHOD2(countFilledBlocks,
366 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
367 std::string_view path));
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -0700368 MOCK_CONST_METHOD2(isFileFullyLoaded,
369 incfs::LoadingState(const Control& control, std::string_view path));
370 MOCK_CONST_METHOD1(isEverythingFullyLoaded, incfs::LoadingState(const Control& control));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800371 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700372 ErrorCode(const Control& control, std::string_view from,
373 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800374 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700375 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700376 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Yurii Zubrytskyi65fc38a2021-03-17 13:18:30 -0700377 MOCK_CONST_METHOD3(reserveSpace,
378 ErrorCode(const Control& control, std::string_view path, IncFsSize size));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700379 MOCK_CONST_METHOD3(waitForPendingReads,
380 WaitResult(const Control& control, std::chrono::milliseconds timeout,
381 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800382 MOCK_CONST_METHOD2(setUidReadTimeouts,
383 ErrorCode(const Control& control,
384 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700385
Yurii Zubrytskyi65fc38a2021-03-17 13:18:30 -0700386 MockIncFs() {
387 ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return());
388 ON_CALL(*this, reserveSpace(_, _, _)).WillByDefault(Return(0));
389 }
Songchun Fan3c82a302019-11-29 14:23:45 -0800390
391 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
392 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700393
394 void countFilledBlocksSuccess() {
395 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
396 }
397
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700398 void countFilledBlocksFullyLoaded() {
399 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
400 }
401
Songchun Fan374f7652020-08-20 08:40:29 -0700402 void countFilledBlocksFails() {
403 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
404 }
405
406 void countFilledBlocksEmpty() {
407 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
408 }
409
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700410 void openMountSuccess() {
411 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
412 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700413
414 // 1000ms
415 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700416 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700417 .WillByDefault(
418 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
419 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
420 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
421 return android::incfs::WaitResult::HaveData;
422 }));
423 }
424
425 void waitForPendingReadsTimeout() {
426 ON_CALL(*this, waitForPendingReads(_, _, _))
427 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700428 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700429
430 static constexpr auto kPendingReadsFd = 42;
431 Control openMountForHealth(std::string_view) {
Yurii Zubrytskyi5f692922020-12-08 07:35:24 -0800432 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700433 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700434
Songchun Fan20d6ef22020-03-03 09:47:15 -0800435 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800436 metadata::Mount m;
437 m.mutable_storage()->set_id(100);
438 m.mutable_loader()->set_package_name("com.test");
439 m.mutable_loader()->set_arguments("com.uri");
440 const auto metadata = m.SerializeAsString();
441 m.mutable_loader()->release_arguments();
442 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800443 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800444 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800445 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800446 metadata::Storage st;
447 st.set_id(100);
448 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800449 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800450 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800451 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800452 metadata::BindPoint bp;
453 std::string destPath = "dest";
454 std::string srcPath = "src";
455 bp.set_storage_id(100);
456 bp.set_allocated_dest_path(&destPath);
457 bp.set_allocated_source_subdir(&srcPath);
458 const auto metadata = bp.SerializeAsString();
459 bp.release_source_subdir();
460 bp.release_dest_path();
461 return std::vector<char>(metadata.begin(), metadata.end());
462 }
463};
464
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700465class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700466public:
467 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700468 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700469 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
470
471 void checkPermissionSuccess() {
472 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
473 }
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -0800474 void checkPermissionNoCrossUsers() {
475 ON_CALL(*this,
476 checkPermission("android.permission.LOADER_USAGE_STATS",
477 "android:loader_usage_stats", _))
478 .WillByDefault(Return(android::incremental::Ok()));
479 ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
480 .WillByDefault(
481 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
482 }
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700483 void checkPermissionFails() {
484 ON_CALL(*this, checkPermission(_, _, _))
485 .WillByDefault(
486 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
487 }
488 void initializeStartWatchingMode() {
489 ON_CALL(*this, startWatchingMode(_, _, _))
490 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
491 }
492 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
493 mStoredCallback = cb;
494 }
495
496 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700497};
498
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700499class MockJniWrapper : public JniWrapper {
500public:
501 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
502
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700503 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700504};
505
506class MockLooperWrapper : public LooperWrapper {
507public:
508 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
509 MOCK_METHOD1(removeFd, int(int));
510 MOCK_METHOD0(wake, void());
511 MOCK_METHOD1(pollAll, int(int));
512
513 MockLooperWrapper() {
514 ON_CALL(*this, addFd(_, _, _, _, _))
515 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
516 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700517 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700518 }
519
520 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
521 mCallback = callback;
522 mCallbackData = data;
523 return 0;
524 }
525
526 int clearCallback(int) {
527 mCallback = nullptr;
528 mCallbackData = nullptr;
529 return 0;
530 }
531
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700532 int wait10Ms(int) {
533 // This is called from a loop in runCmdLooper.
534 // Sleeping for 10ms only to avoid busy looping.
535 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700536 return 0;
537 }
538
539 android::Looper_callbackFunc mCallback = nullptr;
540 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700541};
542
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700543class MockTimedQueueWrapper : public TimedQueueWrapper {
544public:
545 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
546 MOCK_METHOD1(removeJobs, void(MountId));
547 MOCK_METHOD0(stop, void());
548
549 MockTimedQueueWrapper() {
550 ON_CALL(*this, addJob(_, _, _))
551 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
552 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
553 }
554
555 void storeJob(MountId id, Milliseconds after, Job what) {
556 mId = id;
557 mAfter = after;
558 mWhat = std::move(what);
559 }
560
561 void clearJob(MountId id) {
562 if (mId == id) {
563 mAfter = {};
564 mWhat = {};
565 }
566 }
567
568 MountId mId = -1;
569 Milliseconds mAfter;
570 Job mWhat;
571};
572
Songchun Fan374f7652020-08-20 08:40:29 -0700573class MockFsWrapper : public FsWrapper {
574public:
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800575 MOCK_CONST_METHOD2(listFilesRecursive, void(std::string_view, FileCallback));
576 void hasNoFile() { ON_CALL(*this, listFilesRecursive(_, _)).WillByDefault(Return()); }
Songchun Fan374f7652020-08-20 08:40:29 -0700577 void hasFiles() {
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800578 ON_CALL(*this, listFilesRecursive(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -0700579 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
580 }
Yurii Zubrytskyi3fde5722021-02-19 00:08:36 -0800581 void fakeFiles(std::string_view directoryPath, FileCallback onFile) {
582 for (auto file : {"base.apk", "split.apk", "lib/a.so"}) {
583 if (!onFile(file)) break;
584 }
Songchun Fan374f7652020-08-20 08:40:29 -0700585 }
586};
587
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800588class MockClockWrapper : public ClockWrapper {
589public:
590 MOCK_CONST_METHOD0(now, TimePoint());
591
592 void start() { ON_CALL(*this, now()).WillByDefault(Invoke(this, &MockClockWrapper::getClock)); }
593 template <class Delta>
594 void advance(Delta delta) {
595 mClock += delta;
596 }
597
598 TimePoint getClock() const { return mClock; }
599
600 TimePoint mClock = Clock::now();
601};
602
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700603class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
604public:
605 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
606
607 MockStorageHealthListener() {
608 ON_CALL(*this, onHealthStatus(_, _))
609 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
610 }
611
612 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
613 mStorageId = storageId;
614 mStatus = status;
615 return binder::Status::ok();
616 }
617
618 int32_t mStorageId = -1;
619 int32_t mStatus = -1;
620};
621
Songchun Fana7098592020-09-03 11:45:53 -0700622class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
623public:
624 MockStorageLoadingProgressListener() = default;
625 MOCK_METHOD2(onStorageLoadingProgressChanged,
626 binder::Status(int32_t storageId, float progress));
627 MOCK_METHOD0(onAsBinder, IBinder*());
628};
629
Songchun Fan3c82a302019-11-29 14:23:45 -0800630class MockServiceManager : public ServiceManagerWrapper {
631public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800632 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700633 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700634 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700635 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700636 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700637 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700638 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700639 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800640 std::unique_ptr<MockFsWrapper> fs, std::unique_ptr<MockClockWrapper> clock)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800641 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700642 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700643 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700644 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700645 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700646 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700647 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700648 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800649 mFs(std::move(fs)),
650 mClock(std::move(clock)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800651 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800652 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
653 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800654 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800655 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700656 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
657 return std::move(mAppOpsManager);
658 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700659 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700660 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700661 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700662 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
663 return std::move(mProgressUpdateJobQueue);
664 }
Songchun Fan374f7652020-08-20 08:40:29 -0700665 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800666 std::unique_ptr<ClockWrapper> getClock() final { return std::move(mClock); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800667
668private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800669 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800670 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800671 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700672 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700673 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700674 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700675 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700676 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700677 std::unique_ptr<MockFsWrapper> mFs;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800678 std::unique_ptr<MockClockWrapper> mClock;
Songchun Fan3c82a302019-11-29 14:23:45 -0800679};
680
681// --- IncrementalServiceTest ---
682
Songchun Fan3c82a302019-11-29 14:23:45 -0800683class IncrementalServiceTest : public testing::Test {
684public:
685 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800686 auto vold = std::make_unique<NiceMock<MockVoldService>>();
687 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700688 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
689 mDataLoader = dataLoader.get();
690 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800691 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800692 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
693 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700694 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
695 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700696 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
697 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700698 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
699 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700700 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
701 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700702 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
703 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700704 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
705 mFs = fs.get();
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800706 auto clock = std::make_unique<NiceMock<MockClockWrapper>>();
707 mClock = clock.get();
Songchun Fana7098592020-09-03 11:45:53 -0700708 mIncrementalService = std::make_unique<
709 IncrementalService>(MockServiceManager(std::move(vold),
710 std::move(dataloaderManager),
711 std::move(incFs), std::move(appOps),
712 std::move(jni), std::move(looper),
713 std::move(timedQueue),
714 std::move(progressUpdateJobQueue),
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800715 std::move(fs), std::move(clock)),
Songchun Fana7098592020-09-03 11:45:53 -0700716 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800717 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800718 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700719 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800720 mIncrementalService->onSystemReady();
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800721 mClock->start();
Songchun Fan374f7652020-08-20 08:40:29 -0700722 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800723 }
724
725 void setUpExistingMountDir(const std::string& rootDir) {
726 const auto dir = rootDir + "/dir1";
727 const auto mountDir = dir + "/mount";
728 const auto backingDir = dir + "/backing_store";
729 const auto storageDir = mountDir + "/st0";
730 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
731 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
732 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
733 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
734 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
735 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
736 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
737 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800738 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
739 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
740 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
741 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
742 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
743 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800744 }
745
Songchun Fan374f7652020-08-20 08:40:29 -0700746 void setupSuccess() {
747 mVold->mountIncFsSuccess();
748 mIncFs->makeFileSuccess();
749 mVold->bindMountSuccess();
750 mDataLoaderManager->bindToDataLoaderSuccess();
751 mDataLoaderManager->getDataLoaderSuccess();
752 }
753
Songchun Fan1b76ccf2021-02-24 22:25:59 +0000754 void checkMillisSinceOldestPendingRead(int storageId, long expected) {
755 android::os::PersistableBundle result{};
756 mIncrementalService->getMetrics(storageId, &result);
757 int64_t value = -1;
758 ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
759 METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
760 .c_str()),
761 &value));
762 ASSERT_EQ(expected, value);
763 ASSERT_EQ(1, (int)result.size());
764 }
765
Songchun Fan3c82a302019-11-29 14:23:45 -0800766protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700767 NiceMock<MockVoldService>* mVold = nullptr;
768 NiceMock<MockIncFs>* mIncFs = nullptr;
769 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
770 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
771 NiceMock<MockJniWrapper>* mJni = nullptr;
772 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700773 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700774 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700775 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800776 NiceMock<MockClockWrapper>* mClock = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700777 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800778 std::unique_ptr<IncrementalService> mIncrementalService;
779 TemporaryDir mRootDir;
780 DataLoaderParamsParcel mDataLoaderParcel;
781};
782
Songchun Fan3c82a302019-11-29 14:23:45 -0800783TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
784 mVold->mountIncFsFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800785 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800786 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800787 int storageId =
788 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
789 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800790 ASSERT_LT(storageId, 0);
791}
792
793TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
794 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800795 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700796 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800797 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800798 int storageId =
799 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
800 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800801 ASSERT_LT(storageId, 0);
802}
803
804TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
805 mVold->mountIncFsSuccess();
806 mIncFs->makeFileFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800807 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700808 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800809 EXPECT_CALL(*mVold, unmountIncFs(_));
810 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800811 int storageId =
812 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
813 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800814 ASSERT_LT(storageId, 0);
815}
816
817TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
818 mVold->mountIncFsSuccess();
819 mIncFs->makeFileSuccess();
820 mVold->bindMountFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800821 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700822 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800823 EXPECT_CALL(*mVold, unmountIncFs(_));
824 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800825 int storageId =
826 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
827 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800828 ASSERT_LT(storageId, 0);
829}
830
831TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
832 mVold->mountIncFsSuccess();
833 mIncFs->makeFileSuccess();
834 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700835 mDataLoaderManager->bindToDataLoaderFails();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800836 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700837 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700838 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
839 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
840 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800841 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
842 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800843 int storageId =
844 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
845 IncrementalService::CreateOptions::CreateNew);
846 ASSERT_GE(storageId, 0);
847 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800848}
849
850TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700851 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800852 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700853 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800854 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
855 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800856 int storageId =
857 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
858 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800859 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800860 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800861 mIncrementalService->deleteStorage(storageId);
862}
863
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800864TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
865 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(6);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700866 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800867 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
868 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700869 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800870 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
871 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800872 int storageId =
873 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
874 IncrementalService::CreateOptions::CreateNew);
Songchun Fan3c82a302019-11-29 14:23:45 -0800875 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800876 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800877
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700878 // Simulated crash/other connection breakage.
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800879
880 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
881 .WillByDefault(Invoke(mDataLoaderManager,
882 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
883 mDataLoaderManager->setDataLoaderStatusDestroyed();
884
885 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
886 .WillByDefault(Invoke(mDataLoaderManager,
887 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
888 mDataLoaderManager->setDataLoaderStatusDestroyed();
889
890 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
891 .WillByDefault(Invoke(mDataLoaderManager,
892 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
893 mDataLoaderManager->setDataLoaderStatusDestroyed();
894
895 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
896 .WillByDefault(Invoke(mDataLoaderManager,
897 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
898 mDataLoaderManager->setDataLoaderStatusDestroyed();
899
900 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
901 .WillByDefault(Invoke(mDataLoaderManager,
902 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700903 mDataLoaderManager->setDataLoaderStatusDestroyed();
904}
905
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800906TEST_F(IncrementalServiceTest, testDataLoaderOnRestart) {
907 mIncFs->waitForPendingReadsSuccess();
908 mIncFs->openMountSuccess();
909
910 constexpr auto bindRetryInterval = 5s;
911
912 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(10);
913 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
914 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(6);
915 EXPECT_CALL(*mDataLoader, start(_)).Times(6);
916 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
917 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -0700918 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800919 TemporaryDir tempDir;
920 int storageId =
921 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
922 IncrementalService::CreateOptions::CreateNew);
923 ASSERT_GE(storageId, 0);
924
925 // First binds to DataLoader fails... because it's restart.
926 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
927 .WillByDefault(Invoke(mDataLoaderManager,
928 &MockDataLoaderManager::bindToDataLoaderNotOkWithNoDelay));
929
930 // Request DL start.
931 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
932
933 // Retry callback present.
934 ASSERT_EQ(storageId, mTimedQueue->mId);
935 ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
936 auto retryCallback = mTimedQueue->mWhat;
937 mTimedQueue->clearJob(storageId);
938
939 // Expecting the same bindToDataLoaderNotOkWithNoDelay call.
940 mClock->advance(5s);
941
942 retryCallback();
943 // Retry callback present.
944 ASSERT_EQ(storageId, mTimedQueue->mId);
945 ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
946 retryCallback = mTimedQueue->mWhat;
947 mTimedQueue->clearJob(storageId);
948
949 // Returning "binding" so that we can retry.
950 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
951 .WillByDefault(Invoke(mDataLoaderManager,
952 &MockDataLoaderManager::bindToDataLoaderBindingWithNoDelay));
953
954 // Expecting bindToDataLoaderBindingWithNoDelay call.
955 mClock->advance(5s);
956
957 retryCallback();
958 // No retry callback.
959 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
960 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
961
962 // Should not change the bindToDataLoader call count
963 ASSERT_NE(nullptr, mLooper->mCallback);
964 ASSERT_NE(nullptr, mLooper->mCallbackData);
965 auto looperCb = mLooper->mCallback;
966 auto looperCbData = mLooper->mCallbackData;
967 looperCb(-1, -1, looperCbData);
968
969 // Expecting the same bindToDataLoaderBindingWithNoDelay call.
970 mClock->advance(5s);
971
972 // Use pending reads callback to trigger binding.
973 looperCb(-1, -1, looperCbData);
974
975 // No retry callback.
976 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
977 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
978
979 // Now we are out of 10m "retry" budget, let's finally bind.
980 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
981 .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOk));
982 mClock->advance(11min);
983
984 // Use pending reads callback to trigger binding.
985 looperCb(-1, -1, looperCbData);
986
987 // No retry callback.
988 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
989 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
990
991 // And test the rest of the backoff.
992 // Simulated crash/other connection breakage.
993 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
994 .WillByDefault(Invoke(mDataLoaderManager,
995 &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
996 mDataLoaderManager->setDataLoaderStatusDestroyed();
997
998 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
999 .WillByDefault(Invoke(mDataLoaderManager,
1000 &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
1001 mDataLoaderManager->setDataLoaderStatusDestroyed();
1002
1003 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1004 .WillByDefault(Invoke(mDataLoaderManager,
1005 &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
1006 mDataLoaderManager->setDataLoaderStatusDestroyed();
1007
1008 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1009 .WillByDefault(Invoke(mDataLoaderManager,
1010 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
1011 mDataLoaderManager->setDataLoaderStatusDestroyed();
1012
1013 ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
1014 .WillByDefault(Invoke(mDataLoaderManager,
1015 &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
1016 mDataLoaderManager->setDataLoaderStatusDestroyed();
1017}
1018
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001019TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -07001020 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001021 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001022 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001023 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1024 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1025 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1026 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1027 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001028 int storageId =
1029 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1030 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001031 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001032 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1033 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001034 mDataLoaderManager->setDataLoaderStatusCreated();
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001035 mDataLoaderManager->setDataLoaderStatusStarted();
1036}
1037
1038TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -07001039 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001040 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001041 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001042 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001043 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1044 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1045 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1046 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001047 int storageId =
1048 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1049 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001050 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001051 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1052 {}, {}));
Alex Buynytskyy0b202662020-04-13 09:53:04 -07001053 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -08001054}
1055
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001056TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001057 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001058 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001059 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1060 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1061 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1062 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1063 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1064 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001065 int storageId =
1066 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1067 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001068 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001069 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1070 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001071 mDataLoaderManager->setDataLoaderStatusUnavailable();
1072}
1073
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001074TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnrecoverable) {
1075 mDataLoader->initializeCreateOkNoStatus();
1076 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
1077 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1078 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1079 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1080 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1081 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1082 TemporaryDir tempDir;
1083 int storageId =
1084 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1085 IncrementalService::CreateOptions::CreateNew);
1086 ASSERT_GE(storageId, 0);
1087 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1088 {}, {}));
1089 mDataLoaderManager->setDataLoaderStatusUnrecoverable();
1090}
1091
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001092TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001093 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001094 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001095 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -07001096
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001097 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -07001098 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001099 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
1100 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -07001101 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001102 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1103 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
1104 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
1105 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001106 int storageId =
1107 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1108 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001109 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001110 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1111 {}, {}));
Alex Buynytskyycca2c112020-05-05 12:48:41 -07001112 mDataLoaderManager->setDataLoaderStatusUnavailable();
1113 ASSERT_NE(nullptr, mLooper->mCallback);
1114 ASSERT_NE(nullptr, mLooper->mCallbackData);
1115 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1116}
1117
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001118TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001119 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001120
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001121 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001122 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1123 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1124 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
1125 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1126 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1127 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
1128 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001129 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001130
1131 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1132 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
1133 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
1134 .Times(2);
1135 EXPECT_CALL(*listenerMock,
1136 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1137 .Times(1);
1138 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1139 .Times(1);
1140 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
1141 .Times(2);
1142
1143 StorageHealthCheckParams params;
1144 params.blockedTimeoutMs = 10000;
1145 params.unhealthyTimeoutMs = 20000;
1146 params.unhealthyMonitoringMs = 30000;
1147
1148 using MS = std::chrono::milliseconds;
1149 using MCS = std::chrono::microseconds;
1150
1151 const auto blockedTimeout = MS(params.blockedTimeoutMs);
1152 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
1153 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
1154
1155 const uint64_t kFirstTimestampUs = 1000000000ll;
1156 const uint64_t kBlockedTimestampUs =
1157 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1158 const uint64_t kUnhealthyTimestampUs =
1159 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1160
1161 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001162 int storageId =
1163 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1164 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001165 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001166 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
1167 std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001168
1169 // Healthy state, registered for pending reads.
1170 ASSERT_NE(nullptr, mLooper->mCallback);
1171 ASSERT_NE(nullptr, mLooper->mCallbackData);
1172 ASSERT_EQ(storageId, listener->mStorageId);
1173 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001174 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001175
1176 // Looper/epoll callback.
1177 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1178 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1179
1180 // Unregister from pending reads and wait.
1181 ASSERT_EQ(nullptr, mLooper->mCallback);
1182 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1183 ASSERT_EQ(storageId, listener->mStorageId);
1184 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
1185 // Timed callback present.
1186 ASSERT_EQ(storageId, mTimedQueue->mId);
1187 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
1188 auto timedCallback = mTimedQueue->mWhat;
1189 mTimedQueue->clearJob(storageId);
1190
1191 // Timed job callback for blocked.
1192 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1193 timedCallback();
1194
1195 // Still not registered, and blocked.
1196 ASSERT_EQ(nullptr, mLooper->mCallback);
1197 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1198 ASSERT_EQ(storageId, listener->mStorageId);
1199 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001200 checkMillisSinceOldestPendingRead(storageId, params.blockedTimeoutMs);
1201
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001202 // Timed callback present.
1203 ASSERT_EQ(storageId, mTimedQueue->mId);
1204 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
1205 timedCallback = mTimedQueue->mWhat;
1206 mTimedQueue->clearJob(storageId);
1207
1208 // Timed job callback for unhealthy.
1209 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1210 timedCallback();
1211
1212 // Still not registered, and blocked.
1213 ASSERT_EQ(nullptr, mLooper->mCallback);
1214 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1215 ASSERT_EQ(storageId, listener->mStorageId);
1216 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001217 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1218
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001219 // Timed callback present.
1220 ASSERT_EQ(storageId, mTimedQueue->mId);
1221 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1222 timedCallback = mTimedQueue->mWhat;
1223 mTimedQueue->clearJob(storageId);
1224
1225 // One more unhealthy.
1226 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1227 timedCallback();
1228
1229 // Still not registered, and blocked.
1230 ASSERT_EQ(nullptr, mLooper->mCallback);
1231 ASSERT_EQ(nullptr, mLooper->mCallbackData);
1232 ASSERT_EQ(storageId, listener->mStorageId);
1233 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001234 checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
1235
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001236 // Timed callback present.
1237 ASSERT_EQ(storageId, mTimedQueue->mId);
1238 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
1239 timedCallback = mTimedQueue->mWhat;
1240 mTimedQueue->clearJob(storageId);
1241
1242 // And now healthy.
1243 mIncFs->waitForPendingReadsTimeout();
1244 timedCallback();
1245
1246 // Healthy state, registered for pending reads.
1247 ASSERT_NE(nullptr, mLooper->mCallback);
1248 ASSERT_NE(nullptr, mLooper->mCallbackData);
1249 ASSERT_EQ(storageId, listener->mStorageId);
1250 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001251 checkMillisSinceOldestPendingRead(storageId, 0);
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -07001252}
1253
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001254TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001255 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001256 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001257
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001258 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001259 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001260 // We are calling setIncFsMountOptions(true).
1261 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1262 // After setIncFsMountOptions succeeded expecting to start watching.
1263 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1264 // Not expecting callback removal.
1265 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001266 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001267 int storageId =
1268 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1269 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001270 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001271 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1272 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001273 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001274}
1275
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001276TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001277 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001278 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001279
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001280 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1281 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1282 // Enabling and then disabling readlogs.
1283 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1284 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1285 // After setIncFsMountOptions succeeded expecting to start watching.
1286 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1287 // Not expecting callback removal.
1288 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1289 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001290 int storageId =
1291 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1292 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001293 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001294 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1295 {}, {}));
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001296 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1297 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001298 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001299 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1300}
1301
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001302TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) {
1303 mVold->setIncFsMountOptionsSuccess();
1304 mAppOpsManager->checkPermissionSuccess();
1305
1306 const auto readLogsMaxInterval = 2h;
1307
1308 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1309 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1310 // Enabling and then disabling readlogs.
1311 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(2);
1312 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1313 // After setIncFsMountOptions succeeded expecting to start watching.
1314 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1315 // Not expecting callback removal.
1316 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1317 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
1318 TemporaryDir tempDir;
1319 int storageId =
1320 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1321 IncrementalService::CreateOptions::CreateNew);
1322 ASSERT_GE(storageId, 0);
1323 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1324 {}, {}));
1325
1326 // Disable readlogs callback present.
1327 ASSERT_EQ(storageId, mTimedQueue->mId);
1328 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1329 auto callback = mTimedQueue->mWhat;
1330 mTimedQueue->clearJob(storageId);
1331
1332 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1333 // Now advance clock for 1hr.
1334 mClock->advance(1h);
1335 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1336 // Now call the timed callback, it should turn off the readlogs.
1337 callback();
1338 // Now advance clock for 2hrs.
1339 mClock->advance(readLogsMaxInterval);
1340 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1341}
1342
1343TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) {
1344 mVold->setIncFsMountOptionsSuccess();
1345 mAppOpsManager->checkPermissionSuccess();
1346
1347 const auto readLogsMaxInterval = 2h;
1348
1349 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1350 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1351 // Enabling and then disabling readlogs.
1352 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
1353 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(0);
1354 // After setIncFsMountOptions succeeded expecting to start watching.
1355 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1356 // Not expecting callback removal.
1357 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1358 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1359 // System data loader.
1360 mDataLoaderParcel.packageName = "android";
1361 TemporaryDir tempDir;
1362 int storageId =
1363 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1364 IncrementalService::CreateOptions::CreateNew);
1365 ASSERT_GE(storageId, 0);
1366 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1367 {}, {}));
1368
1369 // No readlogs callback.
1370 ASSERT_EQ(mTimedQueue->mAfter, 0ms);
1371 ASSERT_EQ(mTimedQueue->mWhat, nullptr);
1372
1373 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1374 // Now advance clock for 1hr.
1375 mClock->advance(1h);
1376 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1377 // Now advance clock for 2hrs.
1378 mClock->advance(readLogsMaxInterval);
1379 ASSERT_EQ(mDataLoader->setStorageParams(true), 0);
1380}
1381
1382TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) {
1383 mVold->setIncFsMountOptionsSuccess();
1384 mAppOpsManager->checkPermissionSuccess();
1385
1386 const auto readLogsMaxInterval = 2h;
1387
1388 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
1389 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1390 // Enabling and then disabling readlogs.
1391 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
1392 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1393 // After setIncFsMountOptions succeeded expecting to start watching.
1394 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1395 // Not expecting callback removal.
1396 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1397 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
1398 TemporaryDir tempDir;
1399 int storageId =
1400 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1401 IncrementalService::CreateOptions::CreateNew);
1402 ASSERT_GE(storageId, 0);
1403
1404 auto dataLoaderParcel = mDataLoaderParcel;
1405 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {},
1406 {}, {}));
1407
1408 // Disable readlogs callback present.
1409 ASSERT_EQ(storageId, mTimedQueue->mId);
1410 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1411 auto callback = mTimedQueue->mWhat;
1412 mTimedQueue->clearJob(storageId);
1413
1414 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1415 // Now advance clock for 1.5hrs.
1416 mClock->advance(90min);
1417 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1418
1419 // New installation.
1420 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1421 {}, {}));
1422
1423 // New callback present.
1424 ASSERT_EQ(storageId, mTimedQueue->mId);
1425 ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
1426 auto callback2 = mTimedQueue->mWhat;
1427 mTimedQueue->clearJob(storageId);
1428
1429 // Old callback should not disable readlogs (setIncFsMountOptions should be called only once).
1430 callback();
1431 // Advance clock for another 1.5hrs.
1432 mClock->advance(90min);
1433 // Still success even it's 3hrs past first install.
1434 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1435
1436 // New one should disable.
1437 callback2();
1438 // And timeout.
1439 mClock->advance(90min);
1440 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1441}
1442
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001443TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001444 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001445 mAppOpsManager->checkPermissionSuccess();
1446 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001447
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001448 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001449 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1450 // We are calling setIncFsMountOptions(true).
1451 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1452 // setIncFsMountOptions(false) is called on the callback.
1453 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1454 // After setIncFsMountOptions succeeded expecting to start watching.
1455 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1456 // After callback is called, disable read logs and remove callback.
1457 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1458 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001459 int storageId =
1460 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1461 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001462 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001463 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1464 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001465 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001466 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1467 mAppOpsManager->mStoredCallback->opChanged(0, {});
1468}
1469
1470TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001471 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001472
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001473 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001474 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1475 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1476 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1477 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1478 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1479 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001480 int storageId =
1481 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1482 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001483 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001484 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1485 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001486 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001487}
1488
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001489TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
1490 mAppOpsManager->checkPermissionNoCrossUsers();
1491
1492 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1493 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1494 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1495 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1496 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1497 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1498 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001499 int storageId =
1500 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1501 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001502 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001503 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1504 {}, {}));
Alex Buynytskyy42d4ba42021-01-12 11:10:03 -08001505 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1506}
1507
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001508TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001509 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001510 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001511
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001512 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001513 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001514 // We are calling setIncFsMountOptions.
1515 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1516 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1517 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1518 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001519 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001520 int storageId =
1521 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1522 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001523 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001524 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1525 {}, {}));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001526 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001527}
1528
Songchun Fan3c82a302019-11-29 14:23:45 -08001529TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001530 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001531 int storageId =
1532 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1533 IncrementalService::CreateOptions::CreateNew);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001534 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001535
Songchun Fan103ba1d2020-02-03 17:32:32 -08001536 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001537 // <root>/*/mount/<storage>/test
1538 EXPECT_CALL(*mIncFs,
1539 makeDir(_, Truly([&](std::string_view arg) {
1540 return arg.starts_with(mRootDir.path) &&
1541 arg.ends_with("/mount/st_1_0/" + dir_path);
1542 }),
1543 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001544 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1545 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001546}
1547
1548TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001549 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001550 int storageId =
1551 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1552 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001553 auto first = "first"sv;
1554 auto second = "second"sv;
1555 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001556 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001557
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001558 EXPECT_CALL(*mIncFs,
1559 makeDirs(_, Truly([&](std::string_view arg) {
1560 return arg.starts_with(mRootDir.path) &&
1561 arg.ends_with("/mount/st_1_0/" + dir_path);
1562 }),
1563 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001564 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001565 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001566}
Songchun Fan374f7652020-08-20 08:40:29 -07001567
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001568TEST_F(IncrementalServiceTest, testIsFileFullyLoadedNoData) {
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001569 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001570 int storageId =
1571 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1572 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001573 EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
1574 .Times(1)
1575 .WillOnce(Return(incfs::LoadingState::MissingBlocks));
1576 ASSERT_GT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001577}
1578
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001579TEST_F(IncrementalServiceTest, testIsFileFullyLoadedError) {
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001580 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001581 int storageId =
1582 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1583 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001584 EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
1585 .Times(1)
1586 .WillOnce(Return(incfs::LoadingState(-1)));
1587 ASSERT_LT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001588}
1589
1590TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001591 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001592 int storageId =
1593 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1594 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -07001595 EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _))
1596 .Times(1)
1597 .WillOnce(Return(incfs::LoadingState::Full));
1598 ASSERT_EQ(0, (int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001599}
1600
Songchun Fan425862f2020-08-25 13:12:16 -07001601TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001602 mIncFs->countFilledBlocksSuccess();
1603 mFs->hasNoFile();
1604
1605 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001606 int storageId =
1607 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1608 IncrementalService::CreateOptions::CreateNew);
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -07001609 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001610}
1611
1612TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1613 mIncFs->countFilledBlocksFails();
1614 mFs->hasFiles();
1615
1616 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001617 int storageId =
1618 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1619 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001620 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -07001621 ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001622}
1623
Songchun Fan425862f2020-08-25 13:12:16 -07001624TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001625 mIncFs->countFilledBlocksEmpty();
1626 mFs->hasFiles();
1627
1628 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001629 int storageId =
1630 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1631 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001632 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -07001633 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001634}
1635
1636TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1637 mIncFs->countFilledBlocksSuccess();
1638 mFs->hasFiles();
1639
1640 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001641 int storageId =
1642 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1643 IncrementalService::CreateOptions::CreateNew);
Songchun Fan374f7652020-08-20 08:40:29 -07001644 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -07001645 ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001646}
Songchun Fana7098592020-09-03 11:45:53 -07001647
1648TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1649 mIncFs->countFilledBlocksSuccess();
1650 mFs->hasFiles();
1651
1652 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001653 int storageId =
1654 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1655 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001656 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1657 new NiceMock<MockStorageLoadingProgressListener>};
1658 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1659 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1660 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1661 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1662 // Timed callback present.
1663 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1664 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1665 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1666 timedCallback();
1667 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1668 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1669 mIncrementalService->unregisterLoadingProgressListener(storageId);
1670 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1671}
1672
1673TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1674 mIncFs->countFilledBlocksFails();
1675 mFs->hasFiles();
1676
1677 TemporaryDir tempDir;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001678 int storageId =
1679 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1680 IncrementalService::CreateOptions::CreateNew);
Songchun Fana7098592020-09-03 11:45:53 -07001681 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1682 new NiceMock<MockStorageLoadingProgressListener>};
1683 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1684 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1685 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1686}
Songchun Fan2570ec02020-10-08 17:22:33 -07001687
1688TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1689 mIncFs->openMountSuccess();
1690 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1691 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1692 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1693
1694 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001695 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001696 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1697 IncrementalService::CreateOptions::CreateNew);
Songchun Fan2570ec02020-10-08 17:22:33 -07001698 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001699 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener,
1700 {});
1701
Songchun Fan2570ec02020-10-08 17:22:33 -07001702 StorageHealthCheckParams newParams;
1703 newParams.blockedTimeoutMs = 10000;
1704 newParams.unhealthyTimeoutMs = 20000;
1705 newParams.unhealthyMonitoringMs = 30000;
1706 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1707 newListener));
1708
1709 using MS = std::chrono::milliseconds;
1710 using MCS = std::chrono::microseconds;
1711
1712 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1713 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1714
1715 const uint64_t kFirstTimestampUs = 1000000000ll;
1716 const uint64_t kBlockedTimestampUs =
1717 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1718 const uint64_t kUnhealthyTimestampUs =
1719 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1720
1721 // test that old listener was not called
1722 EXPECT_CALL(*listener.get(),
1723 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1724 .Times(0);
1725 EXPECT_CALL(*newListenerMock,
1726 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1727 .Times(1);
1728 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1729 .Times(1);
1730 EXPECT_CALL(*newListenerMock,
1731 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1732 .Times(1);
1733 EXPECT_CALL(*newListenerMock,
1734 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1735 .Times(1);
1736 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1737 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1738
1739 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1740 ASSERT_EQ(storageId, newListener->mStorageId);
1741
1742 auto timedCallback = mTimedQueue->mWhat;
1743 mTimedQueue->clearJob(storageId);
1744
1745 // test when health status is blocked with transport error
1746 mDataLoader->transportError(storageId);
1747 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1748 timedCallback();
1749 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1750 timedCallback = mTimedQueue->mWhat;
1751 mTimedQueue->clearJob(storageId);
1752
1753 // test when health status is blocked with storage error
1754 mDataLoader->storageError(storageId);
1755 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1756 timedCallback();
1757 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1758 timedCallback = mTimedQueue->mWhat;
1759 mTimedQueue->clearJob(storageId);
1760
1761 // test when health status is unhealthy with transport error
1762 mDataLoader->transportError(storageId);
1763 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1764 timedCallback();
1765 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1766 mTimedQueue->clearJob(storageId);
1767}
1768
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001769static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1770 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1771 std::vector<PerUidReadTimeouts> result;
1772 for (auto&& tuple : tuples) {
1773 result.emplace_back();
1774 auto& timeouts = result.back();
1775 timeouts.uid = std::get<0>(tuple);
1776 timeouts.minTimeUs = std::get<1>(tuple);
1777 timeouts.minPendingTimeUs = std::get<2>(tuple);
1778 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1779 }
1780 return result;
1781}
1782
1783static ErrorCode checkPerUidTimeouts(const Control& control,
1784 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1785 std::vector<PerUidReadTimeouts> expected =
1786 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1787 EXPECT_EQ(expected, perUidReadTimeouts);
1788 return 0;
1789}
1790
1791static ErrorCode checkPerUidTimeoutsEmpty(
1792 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1793 EXPECT_EQ(0u, perUidReadTimeouts.size());
1794 return 0;
1795}
1796
1797TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -08001798 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001799 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1800 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001801 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001802 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1803 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001804 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001805 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1806 TemporaryDir tempDir;
1807 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001808 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1809 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001810 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001811 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1812 createPerUidTimeouts(
1813 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001814}
1815
1816TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1817 mVold->setIncFsMountOptionsSuccess();
1818 mAppOpsManager->checkPermissionSuccess();
1819 mFs->hasFiles();
1820
1821 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1822 // First call.
1823 .WillOnce(Invoke(&checkPerUidTimeouts))
1824 // Fully loaded and no readlogs.
1825 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1826 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1827
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -07001828 // Loading storage.
1829 EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
1830 .WillOnce(Return(incfs::LoadingState::MissingBlocks))
1831 .WillOnce(Return(incfs::LoadingState::MissingBlocks))
1832 .WillOnce(Return(incfs::LoadingState::Full))
1833 .WillOnce(Return(incfs::LoadingState::Full));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001834
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -07001835 // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue.
1836 mDataLoaderParcel.packageName = "android";
1837
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001838 TemporaryDir tempDir;
1839 int storageId =
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001840 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1841 IncrementalService::CreateOptions::CreateNew);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001842 ASSERT_GE(storageId, 0);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -08001843 mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
1844 createPerUidTimeouts(
1845 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001846
1847 {
1848 // Timed callback present -> 0 progress.
1849 ASSERT_EQ(storageId, mTimedQueue->mId);
1850 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1851 const auto timedCallback = mTimedQueue->mWhat;
1852 mTimedQueue->clearJob(storageId);
1853
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001854 // Call it again.
1855 timedCallback();
1856 }
1857
1858 {
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -07001859 // Still present -> some progress.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001860 ASSERT_EQ(storageId, mTimedQueue->mId);
1861 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1862 const auto timedCallback = mTimedQueue->mWhat;
1863 mTimedQueue->clearJob(storageId);
1864
1865 // Fully loaded but readlogs collection enabled.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001866 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1867
1868 // Call it again.
1869 timedCallback();
1870 }
1871
1872 {
1873 // Still present -> fully loaded + readlogs.
1874 ASSERT_EQ(storageId, mTimedQueue->mId);
1875 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1876 const auto timedCallback = mTimedQueue->mWhat;
1877 mTimedQueue->clearJob(storageId);
1878
1879 // Now disable readlogs.
1880 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1881
1882 // Call it again.
1883 timedCallback();
1884 }
1885
1886 // No callbacks anymore -> fully loaded and no readlogs.
1887 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1888}
1889
Songchun Fan1b76ccf2021-02-24 22:25:59 +00001890TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) {
1891 const auto invalidStorageId = 100;
1892 android::os::PersistableBundle result{};
1893 mIncrementalService->getMetrics(invalidStorageId, &result);
1894 int64_t expected = -1, value = -1;
1895 ASSERT_FALSE(
1896 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1897 .c_str()),
1898 &value));
1899 ASSERT_EQ(expected, value);
1900 ASSERT_TRUE(result.empty());
1901}
1902
1903TEST_F(IncrementalServiceTest, testNoMetrics) {
1904 mVold->setIncFsMountOptionsSuccess();
1905 TemporaryDir tempDir;
1906 int storageId =
1907 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1908 IncrementalService::CreateOptions::CreateNew);
1909 ASSERT_GE(storageId, 0);
1910 android::os::PersistableBundle result{};
1911 mIncrementalService->getMetrics(storageId, &result);
1912 int64_t expected = -1, value = -1;
1913 ASSERT_FALSE(
1914 result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
1915 .c_str()),
1916 &value));
1917 ASSERT_EQ(expected, value);
1918 ASSERT_EQ(0, (int)result.size());
1919}
1920
1921TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) {
1922 mVold->setIncFsMountOptionsSuccess();
1923 TemporaryDir tempDir;
1924 int storageId =
1925 mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
1926 IncrementalService::CreateOptions::CreateNew);
1927 ASSERT_GE(storageId, 0);
1928 ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
1929 {}, {}));
1930 android::os::PersistableBundle result{};
1931 mIncrementalService->getMetrics(storageId, &result);
1932 int64_t expected = -1, value = -1;
1933 ASSERT_FALSE(result.getLong(String16("invalid"), &value));
1934 ASSERT_EQ(expected, value);
1935 ASSERT_EQ(1, (int)result.size());
1936}
1937
Songchun Fan3c82a302019-11-29 14:23:45 -08001938} // namespace android::os::incremental