blob: 9b8cf4084bf17d3d38d710af8ddf1b1588d1f7ac [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;
45
46namespace android::os::incremental {
47
48class MockVoldService : public VoldServiceWrapper {
49public:
50 MOCK_CONST_METHOD4(mountIncFs,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080051 binder::Status(const std::string& backingPath, const std::string& targetDir,
Songchun Fan3c82a302019-11-29 14:23:45 -080052 int32_t flags,
53 IncrementalFileSystemControlParcel* _aidl_return));
54 MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
55 MOCK_CONST_METHOD2(bindMount,
56 binder::Status(const std::string& sourceDir, const std::string& argetDir));
Songchun Fan374f7652020-08-20 08:40:29 -070057 MOCK_CONST_METHOD2(
58 setIncFsMountOptions,
59 binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
60 bool));
Songchun Fan3c82a302019-11-29 14:23:45 -080061
62 void mountIncFsFails() {
63 ON_CALL(*this, mountIncFs(_, _, _, _))
64 .WillByDefault(
65 Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
66 }
67 void mountIncFsInvalidControlParcel() {
68 ON_CALL(*this, mountIncFs(_, _, _, _))
69 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
70 }
71 void mountIncFsSuccess() {
72 ON_CALL(*this, mountIncFs(_, _, _, _))
73 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
74 }
75 void bindMountFails() {
76 ON_CALL(*this, bindMount(_, _))
77 .WillByDefault(Return(
78 binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
79 }
80 void bindMountSuccess() {
81 ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
82 }
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070083 void setIncFsMountOptionsFails() const {
84 ON_CALL(*this, setIncFsMountOptions(_, _))
Songchun Fan374f7652020-08-20 08:40:29 -070085 .WillByDefault(Return(
86 binder::Status::fromExceptionCode(1, String8("failed to set options"))));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -070087 }
88 void setIncFsMountOptionsSuccess() {
89 ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
90 }
Songchun Fan3c82a302019-11-29 14:23:45 -080091 binder::Status getInvalidControlParcel(const std::string& imagePath,
92 const std::string& targetDir, int32_t flags,
93 IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080094 _aidl_return = {};
Songchun Fan3c82a302019-11-29 14:23:45 -080095 return binder::Status::ok();
96 }
97 binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
98 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080099 _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
100 _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
101 _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
Songchun Fan3c82a302019-11-29 14:23:45 -0800102 return binder::Status::ok();
103 }
104
105private:
106 TemporaryFile cmdFile;
107 TemporaryFile logFile;
Songchun Fan3c82a302019-11-29 14:23:45 -0800108};
109
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700110class MockDataLoader : public IDataLoader {
Songchun Fan3c82a302019-11-29 14:23:45 -0800111public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700112 MockDataLoader() {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700113 ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk));
114 ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk));
115 ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk));
116 ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk));
117 ON_CALL(*this, prepareImage(_, _, _))
118 .WillByDefault(Invoke(this, &MockDataLoader::prepareImageOk));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700119 }
Songchun Fan68645c42020-02-27 15:57:35 -0800120 IBinder* onAsBinder() override { return nullptr; }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700121 MOCK_METHOD4(create,
122 binder::Status(int32_t id, const DataLoaderParamsParcel& params,
123 const FileSystemControlParcel& control,
124 const sp<IDataLoaderStatusListener>& listener));
125 MOCK_METHOD1(start, binder::Status(int32_t id));
126 MOCK_METHOD1(stop, binder::Status(int32_t id));
127 MOCK_METHOD1(destroy, binder::Status(int32_t id));
128 MOCK_METHOD3(prepareImage,
129 binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles,
130 const std::vector<std::string>& removedFiles));
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700131
132 void initializeCreateOkNoStatus() {
133 ON_CALL(*this, create(_, _, _, _))
134 .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus));
135 }
136
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700137 binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params,
138 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700139 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700140 createOkNoStatus(id, params, control, listener);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700141 if (mListener) {
142 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED);
143 }
144 return binder::Status::ok();
145 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700146 binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
147 const content::pm::FileSystemControlParcel& control,
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700148 const sp<content::pm::IDataLoaderStatusListener>& listener) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700149 mServiceConnector = control.service;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700150 mListener = listener;
151 return binder::Status::ok();
152 }
153 binder::Status startOk(int32_t id) {
154 if (mListener) {
155 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
156 }
157 return binder::Status::ok();
158 }
159 binder::Status stopOk(int32_t id) {
160 if (mListener) {
161 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
162 }
163 return binder::Status::ok();
164 }
165 binder::Status destroyOk(int32_t id) {
166 if (mListener) {
167 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
168 }
169 mListener = nullptr;
170 return binder::Status::ok();
171 }
172 binder::Status prepareImageOk(int32_t id,
173 const ::std::vector<content::pm::InstallationFileParcel>&,
174 const ::std::vector<::std::string>&) {
175 if (mListener) {
176 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
177 }
178 return binder::Status::ok();
179 }
Songchun Fan2570ec02020-10-08 17:22:33 -0700180 binder::Status storageError(int32_t id) {
181 if (mListener) {
182 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_STORAGE_ERROR);
183 }
184 return binder::Status::ok();
185 }
186 binder::Status transportError(int32_t id) {
187 if (mListener) {
188 mListener->reportStreamHealth(id, IDataLoaderStatusListener::STREAM_INTEGRITY_ERROR);
189 }
190 return binder::Status::ok();
191 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700192 int32_t setStorageParams(bool enableReadLogs) {
193 int32_t result = -1;
194 EXPECT_NE(mServiceConnector.get(), nullptr);
195 EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
196 return result;
197 }
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700198
199private:
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700200 sp<IIncrementalServiceConnector> mServiceConnector;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700201 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800202};
203
204class MockDataLoaderManager : public DataLoaderManagerWrapper {
205public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700206 MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
207 EXPECT_TRUE(mDataLoaderHolder != nullptr);
208 }
209
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700210 MOCK_CONST_METHOD4(bindToDataLoader,
Songchun Fan68645c42020-02-27 15:57:35 -0800211 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
Songchun Fan3c82a302019-11-29 14:23:45 -0800212 const sp<IDataLoaderStatusListener>& listener,
213 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800214 MOCK_CONST_METHOD2(getDataLoader,
215 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700216 MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800217
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700218 void bindToDataLoaderSuccess() {
219 ON_CALL(*this, bindToDataLoader(_, _, _, _))
220 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700221 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700222 void bindToDataLoaderFails() {
223 ON_CALL(*this, bindToDataLoader(_, _, _, _))
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700224 .WillByDefault(Return(
225 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
226 }
227 void getDataLoaderSuccess() {
228 ON_CALL(*this, getDataLoader(_, _))
229 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
230 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700231 void unbindFromDataLoaderSuccess() {
232 ON_CALL(*this, unbindFromDataLoader(_))
233 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700234 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700235 binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
236 const sp<IDataLoaderStatusListener>& listener,
237 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800238 mId = mountId;
239 mListener = listener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700240 mDataLoader = mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800241 *_aidl_return = true;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700242 if (mListener) {
243 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
244 }
245 return binder::Status::ok();
Songchun Fan3c82a302019-11-29 14:23:45 -0800246 }
Songchun Fan68645c42020-02-27 15:57:35 -0800247 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
248 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800249 return binder::Status::ok();
250 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700251 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800252 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800253 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700254 void setDataLoaderStatusStarted() {
255 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
256 }
257 void setDataLoaderStatusDestroyed() {
258 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
259 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700260 void setDataLoaderStatusUnavailable() {
261 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
262 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700263 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700264 if (mDataLoader) {
265 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
266 return status;
267 }
268 mDataLoader = nullptr;
269 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700270 if (mListener) {
271 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
272 }
273 return binder::Status::ok();
274 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700275
Songchun Fan3c82a302019-11-29 14:23:45 -0800276private:
277 int mId;
278 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700279 sp<IDataLoader> mDataLoader;
280 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800281};
282
283class MockIncFs : public IncFsWrapper {
284public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700285 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
286 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800287 MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
Songchun Fan3c82a302019-11-29 14:23:45 -0800288 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800289 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800290 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800291 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700292 MOCK_CONST_METHOD3(makeDirs,
293 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800294 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
295 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
296 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan6944f1e2020-11-06 15:24:24 -0800297 MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
Songchun Fan374f7652020-08-20 08:40:29 -0700298 MOCK_CONST_METHOD2(countFilledBlocks,
299 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
300 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800301 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700302 ErrorCode(const Control& control, std::string_view from,
303 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800304 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700305 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700306 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700307 MOCK_CONST_METHOD3(waitForPendingReads,
308 WaitResult(const Control& control, std::chrono::milliseconds timeout,
309 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700310
311 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800312
313 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
314 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700315
316 void countFilledBlocksSuccess() {
317 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
318 }
319
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700320 void countFilledBlocksFullyLoaded() {
321 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
322 }
323
Songchun Fan374f7652020-08-20 08:40:29 -0700324 void countFilledBlocksFails() {
325 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
326 }
327
328 void countFilledBlocksEmpty() {
329 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
330 }
331
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700332 void openMountSuccess() {
333 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
334 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700335
336 // 1000ms
337 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700338 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700339 .WillByDefault(
340 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
341 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
342 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
343 return android::incfs::WaitResult::HaveData;
344 }));
345 }
346
347 void waitForPendingReadsTimeout() {
348 ON_CALL(*this, waitForPendingReads(_, _, _))
349 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700350 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700351
352 static constexpr auto kPendingReadsFd = 42;
353 Control openMountForHealth(std::string_view) {
354 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1));
355 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700356
Songchun Fan20d6ef22020-03-03 09:47:15 -0800357 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800358 metadata::Mount m;
359 m.mutable_storage()->set_id(100);
360 m.mutable_loader()->set_package_name("com.test");
361 m.mutable_loader()->set_arguments("com.uri");
362 const auto metadata = m.SerializeAsString();
363 m.mutable_loader()->release_arguments();
364 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800365 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800366 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800367 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800368 metadata::Storage st;
369 st.set_id(100);
370 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800371 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800372 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800373 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800374 metadata::BindPoint bp;
375 std::string destPath = "dest";
376 std::string srcPath = "src";
377 bp.set_storage_id(100);
378 bp.set_allocated_dest_path(&destPath);
379 bp.set_allocated_source_subdir(&srcPath);
380 const auto metadata = bp.SerializeAsString();
381 bp.release_source_subdir();
382 bp.release_dest_path();
383 return std::vector<char>(metadata.begin(), metadata.end());
384 }
385};
386
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700387class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700388public:
389 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700390 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700391 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
392
393 void checkPermissionSuccess() {
394 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
395 }
396 void checkPermissionFails() {
397 ON_CALL(*this, checkPermission(_, _, _))
398 .WillByDefault(
399 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
400 }
401 void initializeStartWatchingMode() {
402 ON_CALL(*this, startWatchingMode(_, _, _))
403 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
404 }
405 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
406 mStoredCallback = cb;
407 }
408
409 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700410};
411
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700412class MockJniWrapper : public JniWrapper {
413public:
414 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
415
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700416 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700417};
418
419class MockLooperWrapper : public LooperWrapper {
420public:
421 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
422 MOCK_METHOD1(removeFd, int(int));
423 MOCK_METHOD0(wake, void());
424 MOCK_METHOD1(pollAll, int(int));
425
426 MockLooperWrapper() {
427 ON_CALL(*this, addFd(_, _, _, _, _))
428 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
429 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700430 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700431 }
432
433 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
434 mCallback = callback;
435 mCallbackData = data;
436 return 0;
437 }
438
439 int clearCallback(int) {
440 mCallback = nullptr;
441 mCallbackData = nullptr;
442 return 0;
443 }
444
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700445 int wait10Ms(int) {
446 // This is called from a loop in runCmdLooper.
447 // Sleeping for 10ms only to avoid busy looping.
448 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700449 return 0;
450 }
451
452 android::Looper_callbackFunc mCallback = nullptr;
453 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700454};
455
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700456class MockTimedQueueWrapper : public TimedQueueWrapper {
457public:
458 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
459 MOCK_METHOD1(removeJobs, void(MountId));
460 MOCK_METHOD0(stop, void());
461
462 MockTimedQueueWrapper() {
463 ON_CALL(*this, addJob(_, _, _))
464 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
465 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
466 }
467
468 void storeJob(MountId id, Milliseconds after, Job what) {
469 mId = id;
470 mAfter = after;
471 mWhat = std::move(what);
472 }
473
474 void clearJob(MountId id) {
475 if (mId == id) {
476 mAfter = {};
477 mWhat = {};
478 }
479 }
480
481 MountId mId = -1;
482 Milliseconds mAfter;
483 Job mWhat;
484};
485
Songchun Fan374f7652020-08-20 08:40:29 -0700486class MockFsWrapper : public FsWrapper {
487public:
488 MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
489 void hasNoFile() {
490 ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
491 }
492 void hasFiles() {
493 ON_CALL(*this, listFilesRecursive(_))
494 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
495 }
496 std::vector<std::string> fakeFiles(std::string_view directoryPath) {
497 return {"base.apk", "split.apk", "lib/a.so"};
498 }
499};
500
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700501class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
502public:
503 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
504
505 MockStorageHealthListener() {
506 ON_CALL(*this, onHealthStatus(_, _))
507 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
508 }
509
510 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
511 mStorageId = storageId;
512 mStatus = status;
513 return binder::Status::ok();
514 }
515
516 int32_t mStorageId = -1;
517 int32_t mStatus = -1;
518};
519
Songchun Fana7098592020-09-03 11:45:53 -0700520class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
521public:
522 MockStorageLoadingProgressListener() = default;
523 MOCK_METHOD2(onStorageLoadingProgressChanged,
524 binder::Status(int32_t storageId, float progress));
525 MOCK_METHOD0(onAsBinder, IBinder*());
526};
527
Songchun Fan3c82a302019-11-29 14:23:45 -0800528class MockServiceManager : public ServiceManagerWrapper {
529public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800530 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700531 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700532 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700533 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700534 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700535 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700536 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700537 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Songchun Fan374f7652020-08-20 08:40:29 -0700538 std::unique_ptr<MockFsWrapper> fs)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800539 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700540 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700541 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700542 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700543 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700544 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700545 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700546 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Songchun Fan374f7652020-08-20 08:40:29 -0700547 mFs(std::move(fs)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800548 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800549 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
550 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800551 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800552 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700553 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
554 return std::move(mAppOpsManager);
555 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700556 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700557 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700558 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700559 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
560 return std::move(mProgressUpdateJobQueue);
561 }
Songchun Fan374f7652020-08-20 08:40:29 -0700562 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800563
564private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800565 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800566 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800567 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700568 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700569 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700570 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700571 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700572 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700573 std::unique_ptr<MockFsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800574};
575
576// --- IncrementalServiceTest ---
577
Songchun Fan3c82a302019-11-29 14:23:45 -0800578class IncrementalServiceTest : public testing::Test {
579public:
580 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800581 auto vold = std::make_unique<NiceMock<MockVoldService>>();
582 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700583 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
584 mDataLoader = dataLoader.get();
585 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800586 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800587 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
588 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700589 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
590 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700591 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
592 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700593 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
594 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700595 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
596 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700597 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
598 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700599 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
600 mFs = fs.get();
Songchun Fana7098592020-09-03 11:45:53 -0700601 mIncrementalService = std::make_unique<
602 IncrementalService>(MockServiceManager(std::move(vold),
603 std::move(dataloaderManager),
604 std::move(incFs), std::move(appOps),
605 std::move(jni), std::move(looper),
606 std::move(timedQueue),
607 std::move(progressUpdateJobQueue),
608 std::move(fs)),
609 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800610 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800611 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700612 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800613 mIncrementalService->onSystemReady();
Songchun Fan374f7652020-08-20 08:40:29 -0700614 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800615 }
616
617 void setUpExistingMountDir(const std::string& rootDir) {
618 const auto dir = rootDir + "/dir1";
619 const auto mountDir = dir + "/mount";
620 const auto backingDir = dir + "/backing_store";
621 const auto storageDir = mountDir + "/st0";
622 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
623 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
624 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
625 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
626 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
627 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
628 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
629 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800630 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
631 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
632 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
633 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
634 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
635 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800636 }
637
Songchun Fan374f7652020-08-20 08:40:29 -0700638 void setupSuccess() {
639 mVold->mountIncFsSuccess();
640 mIncFs->makeFileSuccess();
641 mVold->bindMountSuccess();
642 mDataLoaderManager->bindToDataLoaderSuccess();
643 mDataLoaderManager->getDataLoaderSuccess();
644 }
645
Songchun Fan3c82a302019-11-29 14:23:45 -0800646protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700647 NiceMock<MockVoldService>* mVold = nullptr;
648 NiceMock<MockIncFs>* mIncFs = nullptr;
649 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
650 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
651 NiceMock<MockJniWrapper>* mJni = nullptr;
652 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700653 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700654 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700655 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700656 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800657 std::unique_ptr<IncrementalService> mIncrementalService;
658 TemporaryDir mRootDir;
659 DataLoaderParamsParcel mDataLoaderParcel;
660};
661
Songchun Fan3c82a302019-11-29 14:23:45 -0800662TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
663 mVold->mountIncFsFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700664 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800665 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700666 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
667 IncrementalService::CreateOptions::CreateNew,
668 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800669 ASSERT_LT(storageId, 0);
670}
671
672TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
673 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700674 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
675 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800676 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700677 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
678 IncrementalService::CreateOptions::CreateNew,
679 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800680 ASSERT_LT(storageId, 0);
681}
682
683TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
684 mVold->mountIncFsSuccess();
685 mIncFs->makeFileFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700686 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
687 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800688 EXPECT_CALL(*mVold, unmountIncFs(_));
689 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700690 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
691 IncrementalService::CreateOptions::CreateNew,
692 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800693 ASSERT_LT(storageId, 0);
694}
695
696TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
697 mVold->mountIncFsSuccess();
698 mIncFs->makeFileSuccess();
699 mVold->bindMountFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700700 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
701 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800702 EXPECT_CALL(*mVold, unmountIncFs(_));
703 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700704 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
705 IncrementalService::CreateOptions::CreateNew,
706 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800707 ASSERT_LT(storageId, 0);
708}
709
710TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
711 mVold->mountIncFsSuccess();
712 mIncFs->makeFileSuccess();
713 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700714 mDataLoaderManager->bindToDataLoaderFails();
715 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
716 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700717 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
718 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
719 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800720 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
721 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700722 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
723 IncrementalService::CreateOptions::CreateNew,
724 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800725 ASSERT_LT(storageId, 0);
726}
727
728TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700729 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
730 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700731 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
732 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
733 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800734 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
735 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700736 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
737 IncrementalService::CreateOptions::CreateNew,
738 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800739 ASSERT_GE(storageId, 0);
740 mIncrementalService->deleteStorage(storageId);
741}
742
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700743TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700744 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
745 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700746 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
747 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
748 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800749 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
750 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700751 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
752 IncrementalService::CreateOptions::CreateNew,
753 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800754 ASSERT_GE(storageId, 0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700755 // Simulated crash/other connection breakage.
756 mDataLoaderManager->setDataLoaderStatusDestroyed();
757}
758
759TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700760 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700761 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
762 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700763 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
764 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
765 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
766 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
767 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700768 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
769 IncrementalService::CreateOptions::CreateNew,
770 {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700771 ASSERT_GE(storageId, 0);
772 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800773 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700774 mDataLoaderManager->setDataLoaderStatusStarted();
775}
776
777TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700778 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700779 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
780 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700781 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700782 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
783 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
784 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
785 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700786 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
787 IncrementalService::CreateOptions::CreateNew,
788 {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700789 ASSERT_GE(storageId, 0);
790 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
791 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800792}
793
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700794TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700795 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700796 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
797 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
798 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
799 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
800 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
801 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
802 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700803 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
804 IncrementalService::CreateOptions::CreateNew,
805 {}, {}, {});
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700806 ASSERT_GE(storageId, 0);
807 mDataLoaderManager->setDataLoaderStatusUnavailable();
808}
809
810TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700811 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700812 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700813 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -0700814
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700815 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700816 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700817 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
818 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700819 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700820 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
821 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
822 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
823 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700824 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
825 IncrementalService::CreateOptions::CreateNew,
826 {}, {}, {});
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700827 ASSERT_GE(storageId, 0);
828 mDataLoaderManager->setDataLoaderStatusUnavailable();
829 ASSERT_NE(nullptr, mLooper->mCallback);
830 ASSERT_NE(nullptr, mLooper->mCallbackData);
831 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
832}
833
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700834TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700835 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700836
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700837 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
838 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
839 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
840 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
841 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
842 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
843 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
844 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
845 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
846
847 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
848 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
849 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
850 .Times(2);
851 EXPECT_CALL(*listenerMock,
852 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
853 .Times(1);
854 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
855 .Times(1);
856 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
857 .Times(2);
858
859 StorageHealthCheckParams params;
860 params.blockedTimeoutMs = 10000;
861 params.unhealthyTimeoutMs = 20000;
862 params.unhealthyMonitoringMs = 30000;
863
864 using MS = std::chrono::milliseconds;
865 using MCS = std::chrono::microseconds;
866
867 const auto blockedTimeout = MS(params.blockedTimeoutMs);
868 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
869 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
870
871 const uint64_t kFirstTimestampUs = 1000000000ll;
872 const uint64_t kBlockedTimestampUs =
873 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
874 const uint64_t kUnhealthyTimestampUs =
875 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
876
877 TemporaryDir tempDir;
878 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
879 IncrementalService::CreateOptions::CreateNew,
880 {}, std::move(params), listener);
881 ASSERT_GE(storageId, 0);
882
883 // Healthy state, registered for pending reads.
884 ASSERT_NE(nullptr, mLooper->mCallback);
885 ASSERT_NE(nullptr, mLooper->mCallbackData);
886 ASSERT_EQ(storageId, listener->mStorageId);
887 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
888
889 // Looper/epoll callback.
890 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
891 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
892
893 // Unregister from pending reads and wait.
894 ASSERT_EQ(nullptr, mLooper->mCallback);
895 ASSERT_EQ(nullptr, mLooper->mCallbackData);
896 ASSERT_EQ(storageId, listener->mStorageId);
897 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
898 // Timed callback present.
899 ASSERT_EQ(storageId, mTimedQueue->mId);
900 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
901 auto timedCallback = mTimedQueue->mWhat;
902 mTimedQueue->clearJob(storageId);
903
904 // Timed job callback for blocked.
905 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
906 timedCallback();
907
908 // Still not registered, and blocked.
909 ASSERT_EQ(nullptr, mLooper->mCallback);
910 ASSERT_EQ(nullptr, mLooper->mCallbackData);
911 ASSERT_EQ(storageId, listener->mStorageId);
912 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
913 // Timed callback present.
914 ASSERT_EQ(storageId, mTimedQueue->mId);
915 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
916 timedCallback = mTimedQueue->mWhat;
917 mTimedQueue->clearJob(storageId);
918
919 // Timed job callback for unhealthy.
920 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
921 timedCallback();
922
923 // Still not registered, and blocked.
924 ASSERT_EQ(nullptr, mLooper->mCallback);
925 ASSERT_EQ(nullptr, mLooper->mCallbackData);
926 ASSERT_EQ(storageId, listener->mStorageId);
927 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
928 // Timed callback present.
929 ASSERT_EQ(storageId, mTimedQueue->mId);
930 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
931 timedCallback = mTimedQueue->mWhat;
932 mTimedQueue->clearJob(storageId);
933
934 // One more unhealthy.
935 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
936 timedCallback();
937
938 // Still not registered, and blocked.
939 ASSERT_EQ(nullptr, mLooper->mCallback);
940 ASSERT_EQ(nullptr, mLooper->mCallbackData);
941 ASSERT_EQ(storageId, listener->mStorageId);
942 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
943 // Timed callback present.
944 ASSERT_EQ(storageId, mTimedQueue->mId);
945 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
946 timedCallback = mTimedQueue->mWhat;
947 mTimedQueue->clearJob(storageId);
948
949 // And now healthy.
950 mIncFs->waitForPendingReadsTimeout();
951 timedCallback();
952
953 // Healthy state, registered for pending reads.
954 ASSERT_NE(nullptr, mLooper->mCallback);
955 ASSERT_NE(nullptr, mLooper->mCallbackData);
956 ASSERT_EQ(storageId, listener->mStorageId);
957 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
958}
959
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700960TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700961 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700962 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700963
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700964 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700965 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700966 // We are calling setIncFsMountOptions(true).
967 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
968 // After setIncFsMountOptions succeeded expecting to start watching.
969 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
970 // Not expecting callback removal.
971 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700972 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700973 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
974 IncrementalService::CreateOptions::CreateNew,
975 {}, {}, {});
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700976 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700977 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700978}
979
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700980TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700981 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700982 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700983
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700984 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
985 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
986 // Enabling and then disabling readlogs.
987 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
988 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
989 // After setIncFsMountOptions succeeded expecting to start watching.
990 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
991 // Not expecting callback removal.
992 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
993 TemporaryDir tempDir;
994 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
995 IncrementalService::CreateOptions::CreateNew,
996 {}, {}, {});
997 ASSERT_GE(storageId, 0);
998 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
999 // Now disable.
1000 mIncrementalService->disableReadLogs(storageId);
1001 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
1002}
1003
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001004TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001005 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001006 mAppOpsManager->checkPermissionSuccess();
1007 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -07001008
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001009 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001010 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1011 // We are calling setIncFsMountOptions(true).
1012 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1013 // setIncFsMountOptions(false) is called on the callback.
1014 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1015 // After setIncFsMountOptions succeeded expecting to start watching.
1016 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1017 // After callback is called, disable read logs and remove callback.
1018 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1019 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001020 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1021 IncrementalService::CreateOptions::CreateNew,
1022 {}, {}, {});
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001023 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001024 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001025 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1026 mAppOpsManager->mStoredCallback->opChanged(0, {});
1027}
1028
1029TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001030 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001031
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001032 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001033 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1034 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1035 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1036 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1037 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1038 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001039 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1040 IncrementalService::CreateOptions::CreateNew,
1041 {}, {}, {});
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001042 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001043 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001044}
1045
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001046TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001047 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001048 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001049
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001050 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001051 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001052 // We are calling setIncFsMountOptions.
1053 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1054 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1055 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1056 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001057 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001058 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1059 IncrementalService::CreateOptions::CreateNew,
1060 {}, {}, {});
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001061 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001062 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001063}
1064
Songchun Fan3c82a302019-11-29 14:23:45 -08001065TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001066 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001067 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1068 IncrementalService::CreateOptions::CreateNew,
1069 {}, {}, {});
Songchun Fan103ba1d2020-02-03 17:32:32 -08001070 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001071
Songchun Fan103ba1d2020-02-03 17:32:32 -08001072 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001073 // <root>/*/mount/<storage>/test
1074 EXPECT_CALL(*mIncFs,
1075 makeDir(_, Truly([&](std::string_view arg) {
1076 return arg.starts_with(mRootDir.path) &&
1077 arg.ends_with("/mount/st_1_0/" + dir_path);
1078 }),
1079 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001080 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1081 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001082}
1083
1084TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001085 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001086 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1087 IncrementalService::CreateOptions::CreateNew,
1088 {}, {}, {});
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001089 auto first = "first"sv;
1090 auto second = "second"sv;
1091 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001092 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001093
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001094 EXPECT_CALL(*mIncFs,
1095 makeDirs(_, Truly([&](std::string_view arg) {
1096 return arg.starts_with(mRootDir.path) &&
1097 arg.ends_with("/mount/st_1_0/" + dir_path);
1098 }),
1099 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001100 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001101 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001102}
Songchun Fan374f7652020-08-20 08:40:29 -07001103
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001104TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1105 mIncFs->countFilledBlocksFails();
1106 mFs->hasNoFile();
1107
1108 TemporaryDir tempDir;
1109 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1110 IncrementalService::CreateOptions::CreateNew,
1111 {}, {}, {});
1112 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1113}
1114
1115TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1116 mIncFs->countFilledBlocksFails();
1117 mFs->hasFiles();
1118
1119 TemporaryDir tempDir;
1120 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1121 IncrementalService::CreateOptions::CreateNew,
1122 {}, {}, {});
1123 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1124 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1125}
1126
1127TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1128 mIncFs->countFilledBlocksEmpty();
1129 mFs->hasFiles();
1130
1131 TemporaryDir tempDir;
1132 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1133 IncrementalService::CreateOptions::CreateNew,
1134 {}, {}, {});
1135 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1136 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1137}
1138
1139TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1140 mIncFs->countFilledBlocksFullyLoaded();
1141 mFs->hasFiles();
1142
1143 TemporaryDir tempDir;
1144 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1145 IncrementalService::CreateOptions::CreateNew,
1146 {}, {}, {});
1147 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1148 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1149}
1150
Songchun Fan425862f2020-08-25 13:12:16 -07001151TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001152 mIncFs->countFilledBlocksSuccess();
1153 mFs->hasNoFile();
1154
1155 TemporaryDir tempDir;
1156 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1157 IncrementalService::CreateOptions::CreateNew,
1158 {}, {}, {});
Songchun Fan425862f2020-08-25 13:12:16 -07001159 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId));
Songchun Fan374f7652020-08-20 08:40:29 -07001160}
1161
1162TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1163 mIncFs->countFilledBlocksFails();
1164 mFs->hasFiles();
1165
1166 TemporaryDir tempDir;
1167 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1168 IncrementalService::CreateOptions::CreateNew,
1169 {}, {}, {});
1170 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1171 ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId));
1172}
1173
Songchun Fan425862f2020-08-25 13:12:16 -07001174TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001175 mIncFs->countFilledBlocksEmpty();
1176 mFs->hasFiles();
1177
1178 TemporaryDir tempDir;
1179 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1180 IncrementalService::CreateOptions::CreateNew,
1181 {}, {}, {});
1182 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Songchun Fan425862f2020-08-25 13:12:16 -07001183 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId));
Songchun Fan374f7652020-08-20 08:40:29 -07001184}
1185
1186TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1187 mIncFs->countFilledBlocksSuccess();
1188 mFs->hasFiles();
1189
1190 TemporaryDir tempDir;
1191 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1192 IncrementalService::CreateOptions::CreateNew,
1193 {}, {}, {});
1194 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
1195 ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId));
1196}
Songchun Fana7098592020-09-03 11:45:53 -07001197
1198TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1199 mIncFs->countFilledBlocksSuccess();
1200 mFs->hasFiles();
1201
1202 TemporaryDir tempDir;
1203 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1204 IncrementalService::CreateOptions::CreateNew,
1205 {}, {}, {});
1206 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1207 new NiceMock<MockStorageLoadingProgressListener>};
1208 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1209 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1210 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1211 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1212 // Timed callback present.
1213 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1214 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1215 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1216 timedCallback();
1217 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1218 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1219 mIncrementalService->unregisterLoadingProgressListener(storageId);
1220 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1221}
1222
1223TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1224 mIncFs->countFilledBlocksFails();
1225 mFs->hasFiles();
1226
1227 TemporaryDir tempDir;
1228 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1229 IncrementalService::CreateOptions::CreateNew,
1230 {}, {}, {});
1231 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1232 new NiceMock<MockStorageLoadingProgressListener>};
1233 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1234 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1235 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1236}
Songchun Fan2570ec02020-10-08 17:22:33 -07001237
1238TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) {
1239 mIncFs->openMountSuccess();
1240 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
1241 sp<NiceMock<MockStorageHealthListener>> newListener{new NiceMock<MockStorageHealthListener>};
1242 NiceMock<MockStorageHealthListener>* newListenerMock = newListener.get();
1243
1244 TemporaryDir tempDir;
1245 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1246 IncrementalService::CreateOptions::CreateNew,
1247 {}, StorageHealthCheckParams{}, listener);
1248 ASSERT_GE(storageId, 0);
1249 StorageHealthCheckParams newParams;
1250 newParams.blockedTimeoutMs = 10000;
1251 newParams.unhealthyTimeoutMs = 20000;
1252 newParams.unhealthyMonitoringMs = 30000;
1253 ASSERT_TRUE(mIncrementalService->registerStorageHealthListener(storageId, std::move(newParams),
1254 newListener));
1255
1256 using MS = std::chrono::milliseconds;
1257 using MCS = std::chrono::microseconds;
1258
1259 const auto blockedTimeout = MS(newParams.blockedTimeoutMs);
1260 const auto unhealthyTimeout = MS(newParams.unhealthyTimeoutMs);
1261
1262 const uint64_t kFirstTimestampUs = 1000000000ll;
1263 const uint64_t kBlockedTimestampUs =
1264 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
1265 const uint64_t kUnhealthyTimestampUs =
1266 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
1267
1268 // test that old listener was not called
1269 EXPECT_CALL(*listener.get(),
1270 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1271 .Times(0);
1272 EXPECT_CALL(*newListenerMock,
1273 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
1274 .Times(1);
1275 EXPECT_CALL(*newListenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
1276 .Times(1);
1277 EXPECT_CALL(*newListenerMock,
1278 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE))
1279 .Times(1);
1280 EXPECT_CALL(*newListenerMock,
1281 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT))
1282 .Times(1);
1283 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
1284 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
1285
1286 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, newListener->mStatus);
1287 ASSERT_EQ(storageId, newListener->mStorageId);
1288
1289 auto timedCallback = mTimedQueue->mWhat;
1290 mTimedQueue->clearJob(storageId);
1291
1292 // test when health status is blocked with transport error
1293 mDataLoader->transportError(storageId);
1294 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1295 timedCallback();
1296 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, newListener->mStatus);
1297 timedCallback = mTimedQueue->mWhat;
1298 mTimedQueue->clearJob(storageId);
1299
1300 // test when health status is blocked with storage error
1301 mDataLoader->storageError(storageId);
1302 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
1303 timedCallback();
1304 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_STORAGE, newListener->mStatus);
1305 timedCallback = mTimedQueue->mWhat;
1306 mTimedQueue->clearJob(storageId);
1307
1308 // test when health status is unhealthy with transport error
1309 mDataLoader->transportError(storageId);
1310 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
1311 timedCallback();
1312 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY_TRANSPORT, newListener->mStatus);
1313 mTimedQueue->clearJob(storageId);
1314}
1315
Songchun Fan3c82a302019-11-29 14:23:45 -08001316} // namespace android::os::incremental