blob: 02eaa2fe07b1cb3eb5b7e68a1bc8d9d2084403df [file] [log] [blame]
Songchun Fan3c82a302019-11-29 14:23:45 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android-base/file.h>
18#include <android-base/logging.h>
19#include <android-base/unique_fd.h>
20#include <binder/ParcelFileDescriptor.h>
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23#include <utils/Log.h>
24
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -070025#include <chrono>
Songchun Fan3c82a302019-11-29 14:23:45 -080026#include <future>
27
28#include "IncrementalService.h"
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070029#include "IncrementalServiceValidation.h"
Songchun Fan3c82a302019-11-29 14:23:45 -080030#include "Metadata.pb.h"
31#include "ServiceWrappers.h"
32
33using namespace testing;
34using namespace android::incremental;
35using namespace std::literals;
36using testing::_;
37using testing::Invoke;
38using testing::NiceMock;
39
40#undef LOG_TAG
41#define LOG_TAG "IncrementalServiceTest"
42
43using namespace android::incfs;
44using namespace android::content::pm;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080045using PerUidReadTimeouts = android::os::incremental::PerUidReadTimeouts;
Songchun Fan3c82a302019-11-29 14:23:45 -080046
47namespace android::os::incremental {
48
49class MockVoldService : public VoldServiceWrapper {
50public:
51 MOCK_CONST_METHOD4(mountIncFs,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080052 binder::Status(const std::string& backingPath, const std::string& targetDir,
Songchun Fan3c82a302019-11-29 14:23:45 -080053 int32_t flags,
54 IncrementalFileSystemControlParcel* _aidl_return));
55 MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
56 MOCK_CONST_METHOD2(bindMount,
57 binder::Status(const std::string& sourceDir, const std::string& argetDir));
Songchun Fan374f7652020-08-20 08:40:29 -070058 MOCK_CONST_METHOD2(
59 setIncFsMountOptions,
60 binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
61 bool));
Songchun Fan3c82a302019-11-29 14:23:45 -080062
63 void mountIncFsFails() {
64 ON_CALL(*this, mountIncFs(_, _, _, _))
65 .WillByDefault(
66 Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
67 }
68 void mountIncFsInvalidControlParcel() {
69 ON_CALL(*this, mountIncFs(_, _, _, _))
70 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
71 }
72 void mountIncFsSuccess() {
73 ON_CALL(*this, mountIncFs(_, _, _, _))
74 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
75 }
76 void bindMountFails() {
77 ON_CALL(*this, bindMount(_, _))
78 .WillByDefault(Return(
79 binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
80 }
81 void bindMountSuccess() {
82 ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
83 }
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070084 void setIncFsMountOptionsFails() const {
85 ON_CALL(*this, setIncFsMountOptions(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -070086 .WillByDefault(Return(
87 binder::Status::fromExceptionCode(1, String8("failed to set options"))));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070088 }
89 void setIncFsMountOptionsSuccess() {
90 ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
91 }
Songchun Fan3c82a302019-11-29 14:23:45 -080092 binder::Status getInvalidControlParcel(const std::string& imagePath,
93 const std::string& targetDir, int32_t flags,
94 IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080095 _aidl_return = {};
Songchun Fan3c82a302019-11-29 14:23:45 -080096 return binder::Status::ok();
97 }
98 binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
99 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800100 _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
101 _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
102 _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
Songchun Fan3c82a302019-11-29 14:23:45 -0800103 return binder::Status::ok();
104 }
105
106private:
107 TemporaryFile cmdFile;
108 TemporaryFile logFile;
Songchun Fan3c82a302019-11-29 14:23:45 -0800109};
110
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700111class MockDataLoader : public IDataLoader {
Songchun Fan3c82a302019-11-29 14:23:45 -0800112public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700113 MockDataLoader() {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700114 ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk));
115 ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk));
116 ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk));
117 ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk));
118 ON_CALL(*this, prepareImage(_, _, _))
119 .WillByDefault(Invoke(this, &MockDataLoader::prepareImageOk));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700120 }
Songchun Fan68645c42020-02-27 15:57:35 -0800121 IBinder* onAsBinder() override { return nullptr; }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700122 MOCK_METHOD4(create,
123 binder::Status(int32_t id, const DataLoaderParamsParcel& params,
124 const FileSystemControlParcel& control,
125 const sp<IDataLoaderStatusListener>& listener));
126 MOCK_METHOD1(start, binder::Status(int32_t id));
127 MOCK_METHOD1(stop, binder::Status(int32_t id));
128 MOCK_METHOD1(destroy, binder::Status(int32_t id));
129 MOCK_METHOD3(prepareImage,
130 binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles,
131 const std::vector<std::string>& removedFiles));
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700132
133 void initializeCreateOkNoStatus() {
134 ON_CALL(*this, create(_, _, _, _))
135 .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus));
136 }
137
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700138 binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params,
139 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700140 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700141 createOkNoStatus(id, params, control, listener);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700142 if (mListener) {
143 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED);
144 }
145 return binder::Status::ok();
146 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700147 binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
148 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700149 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700150 mServiceConnector = control.service;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700151 mListener = listener;
152 return binder::Status::ok();
153 }
154 binder::Status startOk(int32_t id) {
155 if (mListener) {
156 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
157 }
158 return binder::Status::ok();
159 }
160 binder::Status stopOk(int32_t id) {
161 if (mListener) {
162 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
163 }
164 return binder::Status::ok();
165 }
166 binder::Status destroyOk(int32_t id) {
167 if (mListener) {
168 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
169 }
170 mListener = nullptr;
171 return binder::Status::ok();
172 }
173 binder::Status prepareImageOk(int32_t id,
174 const ::std::vector<content::pm::InstallationFileParcel>&,
175 const ::std::vector<::std::string>&) {
176 if (mListener) {
177 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
178 }
179 return binder::Status::ok();
180 }
Songchun Fan2570ec02020-10-08 17:22:33 -0700181 binder::Status storageError(int32_t id) {
182 if (mListener) {
183 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_STORAGE_ERROR);
184 }
185 return binder::Status::ok();
186 }
187 binder::Status transportError(int32_t id) {
188 if (mListener) {
189 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_INTEGRITY_ERROR);
190 }
191 return binder::Status::ok();
192 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700193 int32_t setStorageParams(bool enableReadLogs) {
194 int32_t result = -1;
195 EXPECT_NE(mServiceConnector.get(), nullptr);
196 EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
197 return result;
198 }
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700199
200private:
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700201 sp<IIncrementalServiceConnector> mServiceConnector;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700202 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800203};
204
205class MockDataLoaderManager : public DataLoaderManagerWrapper {
206public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700207 MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
208 EXPECT_TRUE(mDataLoaderHolder != nullptr);
209 }
210
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700211 MOCK_CONST_METHOD4(bindToDataLoader,
Songchun Fan68645c42020-02-27 15:57:35 -0800212 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
Songchun Fan3c82a302019-11-29 14:23:45 -0800213 const sp<IDataLoaderStatusListener>& listener,
214 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800215 MOCK_CONST_METHOD2(getDataLoader,
216 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700217 MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800218
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700219 void bindToDataLoaderSuccess() {
220 ON_CALL(*this, bindToDataLoader(_, _, _, _))
221 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700222 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700223 void bindToDataLoaderFails() {
224 ON_CALL(*this, bindToDataLoader(_, _, _, _))
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700225 .WillByDefault(Return(
226 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
227 }
228 void getDataLoaderSuccess() {
229 ON_CALL(*this, getDataLoader(_, _))
230 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
231 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700232 void unbindFromDataLoaderSuccess() {
233 ON_CALL(*this, unbindFromDataLoader(_))
234 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700235 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700236 binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
237 const sp<IDataLoaderStatusListener>& listener,
238 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800239 mId = mountId;
240 mListener = listener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700241 mDataLoader = mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800242 *_aidl_return = true;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700243 if (mListener) {
244 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
245 }
246 return binder::Status::ok();
Songchun Fan3c82a302019-11-29 14:23:45 -0800247 }
Songchun Fan68645c42020-02-27 15:57:35 -0800248 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
249 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800250 return binder::Status::ok();
251 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700252 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800253 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800254 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700255 void setDataLoaderStatusStarted() {
256 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
257 }
258 void setDataLoaderStatusDestroyed() {
259 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
260 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700261 void setDataLoaderStatusUnavailable() {
262 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
263 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700264 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700265 if (mDataLoader) {
266 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
267 return status;
268 }
269 mDataLoader = nullptr;
270 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700271 if (mListener) {
272 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
273 }
274 return binder::Status::ok();
275 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700276
Songchun Fan3c82a302019-11-29 14:23:45 -0800277private:
278 int mId;
279 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700280 sp<IDataLoader> mDataLoader;
281 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800282};
283
284class MockIncFs : public IncFsWrapper {
285public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700286 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
287 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800288 MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
Songchun Fan3c82a302019-11-29 14:23:45 -0800289 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800290 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800291 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800292 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700293 MOCK_CONST_METHOD3(makeDirs,
294 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800295 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
296 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
297 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan6944f1e2020-11-06 15:24:24 -0800298 MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
Songchun Fan374f7652020-08-20 08:40:29 -0700299 MOCK_CONST_METHOD2(countFilledBlocks,
300 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
301 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800302 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700303 ErrorCode(const Control& control, std::string_view from,
304 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800305 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700306 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700307 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700308 MOCK_CONST_METHOD3(waitForPendingReads,
309 WaitResult(const Control& control, std::chrono::milliseconds timeout,
310 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800311 MOCK_CONST_METHOD2(setUidReadTimeouts,
312 ErrorCode(const Control& control,
313 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700314
315 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800316
317 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
318 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700319
320 void countFilledBlocksSuccess() {
321 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
322 }
323
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700324 void countFilledBlocksFullyLoaded() {
325 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
326 }
327
Songchun Fan374f7652020-08-20 08:40:29 -0700328 void countFilledBlocksFails() {
329 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
330 }
331
332 void countFilledBlocksEmpty() {
333 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
334 }
335
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700336 void openMountSuccess() {
337 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
338 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700339
340 // 1000ms
341 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700342 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700343 .WillByDefault(
344 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
345 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
346 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
347 return android::incfs::WaitResult::HaveData;
348 }));
349 }
350
351 void waitForPendingReadsTimeout() {
352 ON_CALL(*this, waitForPendingReads(_, _, _))
353 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700354 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700355
356 static constexpr auto kPendingReadsFd = 42;
357 Control openMountForHealth(std::string_view) {
358 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1));
359 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700360
Songchun Fan20d6ef22020-03-03 09:47:15 -0800361 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800362 metadata::Mount m;
363 m.mutable_storage()->set_id(100);
364 m.mutable_loader()->set_package_name("com.test");
365 m.mutable_loader()->set_arguments("com.uri");
366 const auto metadata = m.SerializeAsString();
367 m.mutable_loader()->release_arguments();
368 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800369 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800370 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800371 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800372 metadata::Storage st;
373 st.set_id(100);
374 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800375 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800376 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800377 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800378 metadata::BindPoint bp;
379 std::string destPath = "dest";
380 std::string srcPath = "src";
381 bp.set_storage_id(100);
382 bp.set_allocated_dest_path(&destPath);
383 bp.set_allocated_source_subdir(&srcPath);
384 const auto metadata = bp.SerializeAsString();
385 bp.release_source_subdir();
386 bp.release_dest_path();
387 return std::vector<char>(metadata.begin(), metadata.end());
388 }
389};
390
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700391class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700392public:
393 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700394 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700395 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
396
397 void checkPermissionSuccess() {
398 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
399 }
400 void checkPermissionFails() {
401 ON_CALL(*this, checkPermission(_, _, _))
402 .WillByDefault(
403 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
404 }
405 void initializeStartWatchingMode() {
406 ON_CALL(*this, startWatchingMode(_, _, _))
407 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
408 }
409 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
410 mStoredCallback = cb;
411 }
412
413 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700414};
415
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700416class MockJniWrapper : public JniWrapper {
417public:
418 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
419
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700420 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700421};
422
423class MockLooperWrapper : public LooperWrapper {
424public:
425 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
426 MOCK_METHOD1(removeFd, int(int));
427 MOCK_METHOD0(wake, void());
428 MOCK_METHOD1(pollAll, int(int));
429
430 MockLooperWrapper() {
431 ON_CALL(*this, addFd(_, _, _, _, _))
432 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
433 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700434 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700435 }
436
437 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
438 mCallback = callback;
439 mCallbackData = data;
440 return 0;
441 }
442
443 int clearCallback(int) {
444 mCallback = nullptr;
445 mCallbackData = nullptr;
446 return 0;
447 }
448
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700449 int wait10Ms(int) {
450 // This is called from a loop in runCmdLooper.
451 // Sleeping for 10ms only to avoid busy looping.
452 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700453 return 0;
454 }
455
456 android::Looper_callbackFunc mCallback = nullptr;
457 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700458};
459
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700460class MockTimedQueueWrapper : public TimedQueueWrapper {
461public:
462 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
463 MOCK_METHOD1(removeJobs, void(MountId));
464 MOCK_METHOD0(stop, void());
465
466 MockTimedQueueWrapper() {
467 ON_CALL(*this, addJob(_, _, _))
468 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
469 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
470 }
471
472 void storeJob(MountId id, Milliseconds after, Job what) {
473 mId = id;
474 mAfter = after;
475 mWhat = std::move(what);
476 }
477
478 void clearJob(MountId id) {
479 if (mId == id) {
480 mAfter = {};
481 mWhat = {};
482 }
483 }
484
485 MountId mId = -1;
486 Milliseconds mAfter;
487 Job mWhat;
488};
489
Songchun Fan374f7652020-08-20 08:40:29 -0700490class MockFsWrapper : public FsWrapper {
491public:
492 MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
493 void hasNoFile() {
494 ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
495 }
496 void hasFiles() {
497 ON_CALL(*this, listFilesRecursive(_))
498 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
499 }
500 std::vector<std::string> fakeFiles(std::string_view directoryPath) {
501 return {"base.apk", "split.apk", "lib/a.so"};
502 }
503};
504
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700505class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
506public:
507 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
508
509 MockStorageHealthListener() {
510 ON_CALL(*this, onHealthStatus(_, _))
511 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
512 }
513
514 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
515 mStorageId = storageId;
516 mStatus = status;
517 return binder::Status::ok();
518 }
519
520 int32_t mStorageId = -1;
521 int32_t mStatus = -1;
522};
523
Songchun Fana7098592020-09-03 11:45:53 -0700524class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
525public:
526 MockStorageLoadingProgressListener() = default;
527 MOCK_METHOD2(onStorageLoadingProgressChanged,
528 binder::Status(int32_t storageId, float progress));
529 MOCK_METHOD0(onAsBinder, IBinder*());
530};
531
Songchun Fan3c82a302019-11-29 14:23:45 -0800532class MockServiceManager : public ServiceManagerWrapper {
533public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800534 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700535 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700536 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700537 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700538 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700539 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700540 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700541 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Songchun Fan374f7652020-08-20 08:40:29 -0700542 std::unique_ptr<MockFsWrapper> fs)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800543 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700544 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700545 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700546 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700547 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700548 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700549 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700550 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Songchun Fan374f7652020-08-20 08:40:29 -0700551 mFs(std::move(fs)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800552 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800553 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
554 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800555 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800556 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700557 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
558 return std::move(mAppOpsManager);
559 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700560 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700561 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700562 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700563 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
564 return std::move(mProgressUpdateJobQueue);
565 }
Songchun Fan374f7652020-08-20 08:40:29 -0700566 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800567
568private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800569 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800570 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800571 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700572 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700573 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700574 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700575 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700576 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700577 std::unique_ptr<MockFsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800578};
579
580// --- IncrementalServiceTest ---
581
Songchun Fan3c82a302019-11-29 14:23:45 -0800582class IncrementalServiceTest : public testing::Test {
583public:
584 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800585 auto vold = std::make_unique<NiceMock<MockVoldService>>();
586 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700587 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
588 mDataLoader = dataLoader.get();
589 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800590 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800591 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
592 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700593 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
594 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700595 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
596 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700597 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
598 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700599 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
600 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700601 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
602 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700603 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
604 mFs = fs.get();
Songchun Fana7098592020-09-03 11:45:53 -0700605 mIncrementalService = std::make_unique<
606 IncrementalService>(MockServiceManager(std::move(vold),
607 std::move(dataloaderManager),
608 std::move(incFs), std::move(appOps),
609 std::move(jni), std::move(looper),
610 std::move(timedQueue),
611 std::move(progressUpdateJobQueue),
612 std::move(fs)),
613 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800614 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800615 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700616 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800617 mIncrementalService->onSystemReady();
Songchun Fan374f7652020-08-20 08:40:29 -0700618 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800619 }
620
621 void setUpExistingMountDir(const std::string& rootDir) {
622 const auto dir = rootDir + "/dir1";
623 const auto mountDir = dir + "/mount";
624 const auto backingDir = dir + "/backing_store";
625 const auto storageDir = mountDir + "/st0";
626 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
627 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
628 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
629 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
630 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
631 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
632 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
633 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800634 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
635 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
636 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
637 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
638 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
639 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800640 }
641
Songchun Fan374f7652020-08-20 08:40:29 -0700642 void setupSuccess() {
643 mVold->mountIncFsSuccess();
644 mIncFs->makeFileSuccess();
645 mVold->bindMountSuccess();
646 mDataLoaderManager->bindToDataLoaderSuccess();
647 mDataLoaderManager->getDataLoaderSuccess();
648 }
649
Songchun Fan3c82a302019-11-29 14:23:45 -0800650protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700651 NiceMock<MockVoldService>* mVold = nullptr;
652 NiceMock<MockIncFs>* mIncFs = nullptr;
653 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
654 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
655 NiceMock<MockJniWrapper>* mJni = nullptr;
656 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700657 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700658 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700659 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700660 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800661 std::unique_ptr<IncrementalService> mIncrementalService;
662 TemporaryDir mRootDir;
663 DataLoaderParamsParcel mDataLoaderParcel;
664};
665
Songchun Fan3c82a302019-11-29 14:23:45 -0800666TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
667 mVold->mountIncFsFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700668 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800669 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700670 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
671 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800672 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800673 ASSERT_LT(storageId, 0);
674}
675
676TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
677 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700678 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
679 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800680 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700681 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
682 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800683 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800684 ASSERT_LT(storageId, 0);
685}
686
687TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
688 mVold->mountIncFsSuccess();
689 mIncFs->makeFileFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700690 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
691 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800692 EXPECT_CALL(*mVold, unmountIncFs(_));
693 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700694 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
695 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800696 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800697 ASSERT_LT(storageId, 0);
698}
699
700TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
701 mVold->mountIncFsSuccess();
702 mIncFs->makeFileSuccess();
703 mVold->bindMountFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700704 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
705 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800706 EXPECT_CALL(*mVold, unmountIncFs(_));
707 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700708 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
709 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800710 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800711 ASSERT_LT(storageId, 0);
712}
713
714TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
715 mVold->mountIncFsSuccess();
716 mIncFs->makeFileSuccess();
717 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700718 mDataLoaderManager->bindToDataLoaderFails();
719 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
720 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700721 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
722 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
723 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800724 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
725 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700726 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
727 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800728 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800729 ASSERT_LT(storageId, 0);
730}
731
732TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700733 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
734 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700735 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
736 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
737 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800738 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
739 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700740 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
741 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800742 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800743 ASSERT_GE(storageId, 0);
744 mIncrementalService->deleteStorage(storageId);
745}
746
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700747TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700748 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
749 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700750 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
751 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
752 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800753 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
754 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700755 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
756 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800757 {}, {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800758 ASSERT_GE(storageId, 0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700759 // Simulated crash/other connection breakage.
760 mDataLoaderManager->setDataLoaderStatusDestroyed();
761}
762
763TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700764 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700765 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
766 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700767 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
768 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
769 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
770 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
771 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700772 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
773 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800774 {}, {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700775 ASSERT_GE(storageId, 0);
776 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800777 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700778 mDataLoaderManager->setDataLoaderStatusStarted();
779}
780
781TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700782 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700783 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
784 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700785 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700786 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
787 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
788 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
789 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700790 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
791 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800792 {}, {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700793 ASSERT_GE(storageId, 0);
794 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
795 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800796}
797
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700798TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700799 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700800 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
801 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
802 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
803 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
804 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
805 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
806 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700807 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
808 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800809 {}, {}, {}, {});
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700810 ASSERT_GE(storageId, 0);
811 mDataLoaderManager->setDataLoaderStatusUnavailable();
812}
813
814TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700815 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700816 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700817 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -0700818
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700819 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700820 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700821 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
822 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700823 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700824 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
825 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
826 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
827 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700828 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
829 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800830 {}, {}, {}, {});
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700831 ASSERT_GE(storageId, 0);
832 mDataLoaderManager->setDataLoaderStatusUnavailable();
833 ASSERT_NE(nullptr, mLooper->mCallback);
834 ASSERT_NE(nullptr, mLooper->mCallbackData);
835 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
836}
837
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700838TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700839 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700840
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700841 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
842 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
843 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
844 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
845 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
846 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
847 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
848 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
849 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
850
851 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
852 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
853 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
854 .Times(2);
855 EXPECT_CALL(*listenerMock,
856 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
857 .Times(1);
858 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
859 .Times(1);
860 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
861 .Times(2);
862
863 StorageHealthCheckParams params;
864 params.blockedTimeoutMs = 10000;
865 params.unhealthyTimeoutMs = 20000;
866 params.unhealthyMonitoringMs = 30000;
867
868 using MS = std::chrono::milliseconds;
869 using MCS = std::chrono::microseconds;
870
871 const auto blockedTimeout = MS(params.blockedTimeoutMs);
872 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
873 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
874
875 const uint64_t kFirstTimestampUs = 1000000000ll;
876 const uint64_t kBlockedTimestampUs =
877 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
878 const uint64_t kUnhealthyTimestampUs =
879 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
880
881 TemporaryDir tempDir;
882 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
883 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800884 {}, std::move(params), listener, {});
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700885 ASSERT_GE(storageId, 0);
886
887 // Healthy state, registered for pending reads.
888 ASSERT_NE(nullptr, mLooper->mCallback);
889 ASSERT_NE(nullptr, mLooper->mCallbackData);
890 ASSERT_EQ(storageId, listener->mStorageId);
891 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
892
893 // Looper/epoll callback.
894 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
895 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
896
897 // Unregister from pending reads and wait.
898 ASSERT_EQ(nullptr, mLooper->mCallback);
899 ASSERT_EQ(nullptr, mLooper->mCallbackData);
900 ASSERT_EQ(storageId, listener->mStorageId);
901 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
902 // Timed callback present.
903 ASSERT_EQ(storageId, mTimedQueue->mId);
904 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
905 auto timedCallback = mTimedQueue->mWhat;
906 mTimedQueue->clearJob(storageId);
907
908 // Timed job callback for blocked.
909 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
910 timedCallback();
911
912 // Still not registered, and blocked.
913 ASSERT_EQ(nullptr, mLooper->mCallback);
914 ASSERT_EQ(nullptr, mLooper->mCallbackData);
915 ASSERT_EQ(storageId, listener->mStorageId);
916 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
917 // Timed callback present.
918 ASSERT_EQ(storageId, mTimedQueue->mId);
919 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
920 timedCallback = mTimedQueue->mWhat;
921 mTimedQueue->clearJob(storageId);
922
923 // Timed job callback for unhealthy.
924 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
925 timedCallback();
926
927 // Still not registered, and blocked.
928 ASSERT_EQ(nullptr, mLooper->mCallback);
929 ASSERT_EQ(nullptr, mLooper->mCallbackData);
930 ASSERT_EQ(storageId, listener->mStorageId);
931 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
932 // Timed callback present.
933 ASSERT_EQ(storageId, mTimedQueue->mId);
934 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
935 timedCallback = mTimedQueue->mWhat;
936 mTimedQueue->clearJob(storageId);
937
938 // One more unhealthy.
939 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
940 timedCallback();
941
942 // Still not registered, and blocked.
943 ASSERT_EQ(nullptr, mLooper->mCallback);
944 ASSERT_EQ(nullptr, mLooper->mCallbackData);
945 ASSERT_EQ(storageId, listener->mStorageId);
946 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
947 // Timed callback present.
948 ASSERT_EQ(storageId, mTimedQueue->mId);
949 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
950 timedCallback = mTimedQueue->mWhat;
951 mTimedQueue->clearJob(storageId);
952
953 // And now healthy.
954 mIncFs->waitForPendingReadsTimeout();
955 timedCallback();
956
957 // Healthy state, registered for pending reads.
958 ASSERT_NE(nullptr, mLooper->mCallback);
959 ASSERT_NE(nullptr, mLooper->mCallbackData);
960 ASSERT_EQ(storageId, listener->mStorageId);
961 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
962}
963
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700964TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700965 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700966 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700967
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700968 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700969 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700970 // We are calling setIncFsMountOptions(true).
971 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
972 // After setIncFsMountOptions succeeded expecting to start watching.
973 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
974 // Not expecting callback removal.
975 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700976 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700977 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
978 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800979 {}, {}, {}, {});
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700980 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700981 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700982}
983
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700984TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700985 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700986 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700987
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700988 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
989 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
990 // Enabling and then disabling readlogs.
991 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
992 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
993 // After setIncFsMountOptions succeeded expecting to start watching.
994 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
995 // Not expecting callback removal.
996 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
997 TemporaryDir tempDir;
998 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
999 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001000 {}, {}, {}, {});
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001001 ASSERT_GE(storageId, 0);
1002 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1003 // Now disable.
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001004 mIncrementalService->disallowReadLogs(storageId);
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -07001005 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1006}
1007
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001008TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001009 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001010 mAppOpsManager->checkPermissionSuccess();
1011 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001012
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001013 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001014 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1015 // We are calling setIncFsMountOptions(true).
1016 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1017 // setIncFsMountOptions(false) is called on the callback.
1018 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1019 // After setIncFsMountOptions succeeded expecting to start watching.
1020 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1021 // After callback is called, disable read logs and remove callback.
1022 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1023 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001024 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1025 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001026 {}, {}, {}, {});
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001027 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001028 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001029 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1030 mAppOpsManager->mStoredCallback->opChanged(0, {});
1031}
1032
1033TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001034 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001035
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001036 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001037 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1038 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1039 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1040 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1041 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1042 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001043 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1044 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001045 {}, {}, {}, {});
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001046 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001047 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001048}
1049
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001050TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001051 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001052 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001053
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001054 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001055 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001056 // We are calling setIncFsMountOptions.
1057 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1058 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1059 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1060 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001061 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001062 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1063 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001064 {}, {}, {}, {});
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001065 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001066 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001067}
1068
Songchun Fan3c82a302019-11-29 14:23:45 -08001069TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001070 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001071 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1072 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001073 {}, {}, {}, {});
Songchun Fan103ba1d2020-02-03 17:32:32 -08001074 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001075
Songchun Fan103ba1d2020-02-03 17:32:32 -08001076 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001077 // <root>/*/mount/<storage>/test
1078 EXPECT_CALL(*mIncFs,
1079 makeDir(_, Truly([&](std::string_view arg) {
1080 return arg.starts_with(mRootDir.path) &&
1081 arg.ends_with("/mount/st_1_0/" + dir_path);
1082 }),
1083 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001084 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1085 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001086}
1087
1088TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001089 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001090 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1091 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001092 {}, {}, {}, {});
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001093 auto first = "first"sv;
1094 auto second = "second"sv;
1095 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001096 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001097
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001098 EXPECT_CALL(*mIncFs,
1099 makeDirs(_, Truly([&](std::string_view arg) {
1100 return arg.starts_with(mRootDir.path) &&
1101 arg.ends_with("/mount/st_1_0/" + dir_path);
1102 }),
1103 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001104 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001105 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001106}
Songchun Fan374f7652020-08-20 08:40:29 -07001107
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001108TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1109 mIncFs->countFilledBlocksFails();
1110 mFs->hasNoFile();
1111
1112 TemporaryDir tempDir;
1113 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1114 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001115 {}, {}, {}, {});
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001116 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1117}
1118
1119TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1120 mIncFs->countFilledBlocksFails();
1121 mFs->hasFiles();
1122
1123 TemporaryDir tempDir;
1124 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1125 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001126 {}, {}, {}, {});
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001127 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1128 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1129}
1130
1131TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1132 mIncFs->countFilledBlocksEmpty();
1133 mFs->hasFiles();
1134
1135 TemporaryDir tempDir;
1136 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1137 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001138 {}, {}, {}, {});
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001139 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1140 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1141}
1142
1143TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1144 mIncFs->countFilledBlocksFullyLoaded();
1145 mFs->hasFiles();
1146
1147 TemporaryDir tempDir;
1148 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1149 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001150 {}, {}, {}, {});
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001151 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1152 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1153}
1154
Songchun Fan425862f2020-08-25 13:12:16 -07001155TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001156 mIncFs->countFilledBlocksSuccess();
1157 mFs->hasNoFile();
1158
1159 TemporaryDir tempDir;
1160 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1161 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001162 {}, {}, {}, {});
1163 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001164}
1165
1166TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1167 mIncFs->countFilledBlocksFails();
1168 mFs->hasFiles();
1169
1170 TemporaryDir tempDir;
1171 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1172 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001173 {}, {}, {}, {});
Songchun Fan374f7652020-08-20 08:40:29 -07001174 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001175 ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001176}
1177
Songchun Fan425862f2020-08-25 13:12:16 -07001178TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001179 mIncFs->countFilledBlocksEmpty();
1180 mFs->hasFiles();
1181
1182 TemporaryDir tempDir;
1183 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1184 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001185 {}, {}, {}, {});
Songchun Fan374f7652020-08-20 08:40:29 -07001186 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001187 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001188}
1189
1190TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1191 mIncFs->countFilledBlocksSuccess();
1192 mFs->hasFiles();
1193
1194 TemporaryDir tempDir;
1195 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1196 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001197 {}, {}, {}, {});
Songchun Fan374f7652020-08-20 08:40:29 -07001198 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001199 ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId).getProgress());
Songchun Fan374f7652020-08-20 08:40:29 -07001200}
Songchun Fana7098592020-09-03 11:45:53 -07001201
1202TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1203 mIncFs->countFilledBlocksSuccess();
1204 mFs->hasFiles();
1205
1206 TemporaryDir tempDir;
1207 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1208 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001209 {}, {}, {}, {});
Songchun Fana7098592020-09-03 11:45:53 -07001210 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1211 new NiceMock<MockStorageLoadingProgressListener>};
1212 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1213 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1214 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1215 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1216 // Timed callback present.
1217 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1218 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1219 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1220 timedCallback();
1221 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1222 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1223 mIncrementalService->unregisterLoadingProgressListener(storageId);
1224 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1225}
1226
1227TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1228 mIncFs->countFilledBlocksFails();
1229 mFs->hasFiles();
1230
1231 TemporaryDir tempDir;
1232 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1233 IncrementalService::CreateOptions::CreateNew,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001234 {}, {}, {}, {});
Songchun Fana7098592020-09-03 11:45:53 -07001235 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1236 new NiceMock<MockStorageLoadingProgressListener>};
1237 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1238 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1239 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1240}
Songchun Fan2570ec02020-10-08 17:22:33 -07001241
1242TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1243 mIncFs->openMountSuccess();
1244 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1245 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1246 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1247
1248 TemporaryDir tempDir;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001249 int storageId =
1250 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1251 IncrementalService::CreateOptions::CreateNew, {},
1252 StorageHealthCheckParams{}, listener, {});
Songchun Fan2570ec02020-10-08 17:22:33 -07001253 ASSERT_GE(storageId, 0);
1254 StorageHealthCheckParams newParams;
1255 newParams.blockedTimeoutMs = 10000;
1256 newParams.unhealthyTimeoutMs = 20000;
1257 newParams.unhealthyMonitoringMs = 30000;
1258 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1259 newListener));
1260
1261 using MS = std::chrono::milliseconds;
1262 using MCS = std::chrono::microseconds;
1263
1264 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1265 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1266
1267 const uint64_t kFirstTimestampUs = 1000000000ll;
1268 const uint64_t kBlockedTimestampUs =
1269 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1270 const uint64_t kUnhealthyTimestampUs =
1271 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1272
1273 // test that old listener was not called
1274 EXPECT_CALL(*listener.get(),
1275 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1276 .Times(0);
1277 EXPECT_CALL(*newListenerMock,
1278 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1279 .Times(1);
1280 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1281 .Times(1);
1282 EXPECT_CALL(*newListenerMock,
1283 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1284 .Times(1);
1285 EXPECT_CALL(*newListenerMock,
1286 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1287 .Times(1);
1288 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1289 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1290
1291 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1292 ASSERT_EQ(storageId, newListener->mStorageId);
1293
1294 auto timedCallback = mTimedQueue->mWhat;
1295 mTimedQueue->clearJob(storageId);
1296
1297 // test when health status is blocked with transport error
1298 mDataLoader->transportError(storageId);
1299 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1300 timedCallback();
1301 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1302 timedCallback = mTimedQueue->mWhat;
1303 mTimedQueue->clearJob(storageId);
1304
1305 // test when health status is blocked with storage error
1306 mDataLoader->storageError(storageId);
1307 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1308 timedCallback();
1309 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1310 timedCallback = mTimedQueue->mWhat;
1311 mTimedQueue->clearJob(storageId);
1312
1313 // test when health status is unhealthy with transport error
1314 mDataLoader->transportError(storageId);
1315 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1316 timedCallback();
1317 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1318 mTimedQueue->clearJob(storageId);
1319}
1320
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -08001321static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
1322 std::initializer_list<std::tuple<int, int, int, int>> tuples) {
1323 std::vector<PerUidReadTimeouts> result;
1324 for (auto&& tuple : tuples) {
1325 result.emplace_back();
1326 auto& timeouts = result.back();
1327 timeouts.uid = std::get<0>(tuple);
1328 timeouts.minTimeUs = std::get<1>(tuple);
1329 timeouts.minPendingTimeUs = std::get<2>(tuple);
1330 timeouts.maxPendingTimeUs = std::get<3>(tuple);
1331 }
1332 return result;
1333}
1334
1335static ErrorCode checkPerUidTimeouts(const Control& control,
1336 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1337 std::vector<PerUidReadTimeouts> expected =
1338 createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
1339 EXPECT_EQ(expected, perUidReadTimeouts);
1340 return 0;
1341}
1342
1343static ErrorCode checkPerUidTimeoutsEmpty(
1344 const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
1345 EXPECT_EQ(0u, perUidReadTimeouts.size());
1346 return 0;
1347}
1348
1349TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
1350 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
1351 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
1352 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
1353 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
1354 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
1355 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
1356 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
1357 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1358 TemporaryDir tempDir;
1359 int storageId =
1360 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1361 IncrementalService::CreateOptions::CreateNew, {}, {},
1362 {},
1363 createPerUidTimeouts(
1364 {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
1365 ASSERT_GE(storageId, 0);
1366}
1367
1368TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
1369 mVold->setIncFsMountOptionsSuccess();
1370 mAppOpsManager->checkPermissionSuccess();
1371 mFs->hasFiles();
1372
1373 EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
1374 // First call.
1375 .WillOnce(Invoke(&checkPerUidTimeouts))
1376 // Fully loaded and no readlogs.
1377 .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
1378 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
1379
1380 // Empty storage.
1381 mIncFs->countFilledBlocksEmpty();
1382
1383 TemporaryDir tempDir;
1384 int storageId =
1385 mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1386 IncrementalService::CreateOptions::CreateNew, {}, {},
1387 {},
1388 createPerUidTimeouts({{0, 1, 2, 3},
1389 {1, 2, 3, 4},
1390 {2, 3, 4, 100000000}}));
1391 ASSERT_GE(storageId, 0);
1392
1393 {
1394 // Timed callback present -> 0 progress.
1395 ASSERT_EQ(storageId, mTimedQueue->mId);
1396 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1397 const auto timedCallback = mTimedQueue->mWhat;
1398 mTimedQueue->clearJob(storageId);
1399
1400 // Still loading.
1401 mIncFs->countFilledBlocksSuccess();
1402
1403 // Call it again.
1404 timedCallback();
1405 }
1406
1407 {
1408 // Still present -> 0.5 progress.
1409 ASSERT_EQ(storageId, mTimedQueue->mId);
1410 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1411 const auto timedCallback = mTimedQueue->mWhat;
1412 mTimedQueue->clearJob(storageId);
1413
1414 // Fully loaded but readlogs collection enabled.
1415 mIncFs->countFilledBlocksFullyLoaded();
1416 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
1417
1418 // Call it again.
1419 timedCallback();
1420 }
1421
1422 {
1423 // Still present -> fully loaded + readlogs.
1424 ASSERT_EQ(storageId, mTimedQueue->mId);
1425 ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
1426 const auto timedCallback = mTimedQueue->mWhat;
1427 mTimedQueue->clearJob(storageId);
1428
1429 // Now disable readlogs.
1430 ASSERT_GE(mDataLoader->setStorageParams(false), 0);
1431
1432 // Call it again.
1433 timedCallback();
1434 }
1435
1436 // No callbacks anymore -> fully loaded and no readlogs.
1437 ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
1438}
1439
Songchun Fan3c82a302019-11-29 14:23:45 -08001440} // namespace android::os::incremental