blob: aec9fa1c3277e0ef62c9c9e8b5768146b2de2840 [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 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700180 int32_t setStorageParams(bool enableReadLogs) {
181 int32_t result = -1;
182 EXPECT_NE(mServiceConnector.get(), nullptr);
183 EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
184 return result;
185 }
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700186
187private:
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700188 sp<IIncrementalServiceConnector> mServiceConnector;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700189 sp<IDataLoaderStatusListener> mListener;
Songchun Fan68645c42020-02-27 15:57:35 -0800190};
191
192class MockDataLoaderManager : public DataLoaderManagerWrapper {
193public:
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700194 MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
195 EXPECT_TRUE(mDataLoaderHolder != nullptr);
196 }
197
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700198 MOCK_CONST_METHOD4(bindToDataLoader,
Songchun Fan68645c42020-02-27 15:57:35 -0800199 binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
Songchun Fan3c82a302019-11-29 14:23:45 -0800200 const sp<IDataLoaderStatusListener>& listener,
201 bool* _aidl_return));
Songchun Fan68645c42020-02-27 15:57:35 -0800202 MOCK_CONST_METHOD2(getDataLoader,
203 binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700204 MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
Songchun Fan3c82a302019-11-29 14:23:45 -0800205
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700206 void bindToDataLoaderSuccess() {
207 ON_CALL(*this, bindToDataLoader(_, _, _, _))
208 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700209 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700210 void bindToDataLoaderFails() {
211 ON_CALL(*this, bindToDataLoader(_, _, _, _))
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700212 .WillByDefault(Return(
213 (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
214 }
215 void getDataLoaderSuccess() {
216 ON_CALL(*this, getDataLoader(_, _))
217 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
218 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700219 void unbindFromDataLoaderSuccess() {
220 ON_CALL(*this, unbindFromDataLoader(_))
221 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700222 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700223 binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
224 const sp<IDataLoaderStatusListener>& listener,
225 bool* _aidl_return) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800226 mId = mountId;
227 mListener = listener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700228 mDataLoader = mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800229 *_aidl_return = true;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700230 if (mListener) {
231 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
232 }
233 return binder::Status::ok();
Songchun Fan3c82a302019-11-29 14:23:45 -0800234 }
Songchun Fan68645c42020-02-27 15:57:35 -0800235 binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
236 *_aidl_return = mDataLoader;
Songchun Fan3c82a302019-11-29 14:23:45 -0800237 return binder::Status::ok();
238 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700239 void setDataLoaderStatusCreated() {
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800240 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
Songchun Fan3c82a302019-11-29 14:23:45 -0800241 }
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700242 void setDataLoaderStatusStarted() {
243 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
244 }
245 void setDataLoaderStatusDestroyed() {
246 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
247 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700248 void setDataLoaderStatusUnavailable() {
249 mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
250 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700251 binder::Status unbindFromDataLoaderOk(int32_t id) {
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700252 if (mDataLoader) {
253 if (auto status = mDataLoader->destroy(id); !status.isOk()) {
254 return status;
255 }
256 mDataLoader = nullptr;
257 }
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700258 if (mListener) {
259 mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
260 }
261 return binder::Status::ok();
262 }
Alex Buynytskyy0a646ca2020-04-08 12:18:01 -0700263
Songchun Fan3c82a302019-11-29 14:23:45 -0800264private:
265 int mId;
266 sp<IDataLoaderStatusListener> mListener;
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700267 sp<IDataLoader> mDataLoader;
268 sp<IDataLoader> mDataLoaderHolder;
Songchun Fan3c82a302019-11-29 14:23:45 -0800269};
270
271class MockIncFs : public IncFsWrapper {
272public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700273 MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
274 MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800275 MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
Songchun Fan3c82a302019-11-29 14:23:45 -0800276 MOCK_CONST_METHOD5(makeFile,
Songchun Fan20d6ef22020-03-03 09:47:15 -0800277 ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800278 NewFileParams params));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800279 MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700280 MOCK_CONST_METHOD3(makeDirs,
281 ErrorCode(const Control& control, std::string_view path, int mode));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800282 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
283 MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
284 MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
Songchun Fan374f7652020-08-20 08:40:29 -0700285 MOCK_CONST_METHOD2(countFilledBlocks,
286 std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
287 std::string_view path));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800288 MOCK_CONST_METHOD3(link,
Songchun Fan374f7652020-08-20 08:40:29 -0700289 ErrorCode(const Control& control, std::string_view from,
290 std::string_view to));
Songchun Fan20d6ef22020-03-03 09:47:15 -0800291 MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700292 MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700293 MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700294 MOCK_CONST_METHOD3(waitForPendingReads,
295 WaitResult(const Control& control, std::chrono::milliseconds timeout,
296 std::vector<incfs::ReadInfo>* pendingReadsBuffer));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700297
298 MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800299
300 void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
301 void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
Songchun Fan374f7652020-08-20 08:40:29 -0700302
303 void countFilledBlocksSuccess() {
304 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
305 }
306
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700307 void countFilledBlocksFullyLoaded() {
308 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
309 }
310
Songchun Fan374f7652020-08-20 08:40:29 -0700311 void countFilledBlocksFails() {
312 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
313 }
314
315 void countFilledBlocksEmpty() {
316 ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
317 }
318
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700319 void openMountSuccess() {
320 ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
321 }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700322
323 // 1000ms
324 void waitForPendingReadsSuccess(uint64_t ts = 0) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700325 ON_CALL(*this, waitForPendingReads(_, _, _))
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700326 .WillByDefault(
327 Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
328 std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
329 pendingReadsBuffer->push_back({.bootClockTsUs = ts});
330 return android::incfs::WaitResult::HaveData;
331 }));
332 }
333
334 void waitForPendingReadsTimeout() {
335 ON_CALL(*this, waitForPendingReads(_, _, _))
336 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700337 }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700338
339 static constexpr auto kPendingReadsFd = 42;
340 Control openMountForHealth(std::string_view) {
341 return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1));
342 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700343
Songchun Fan20d6ef22020-03-03 09:47:15 -0800344 RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800345 metadata::Mount m;
346 m.mutable_storage()->set_id(100);
347 m.mutable_loader()->set_package_name("com.test");
348 m.mutable_loader()->set_arguments("com.uri");
349 const auto metadata = m.SerializeAsString();
350 m.mutable_loader()->release_arguments();
351 m.mutable_loader()->release_package_name();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800352 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800353 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800354 RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800355 metadata::Storage st;
356 st.set_id(100);
357 auto metadata = st.SerializeAsString();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800358 return {metadata.begin(), metadata.end()};
Songchun Fan3c82a302019-11-29 14:23:45 -0800359 }
Songchun Fan20d6ef22020-03-03 09:47:15 -0800360 RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800361 metadata::BindPoint bp;
362 std::string destPath = "dest";
363 std::string srcPath = "src";
364 bp.set_storage_id(100);
365 bp.set_allocated_dest_path(&destPath);
366 bp.set_allocated_source_subdir(&srcPath);
367 const auto metadata = bp.SerializeAsString();
368 bp.release_source_subdir();
369 bp.release_dest_path();
370 return std::vector<char>(metadata.begin(), metadata.end());
371 }
372};
373
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700374class MockAppOpsManager : public AppOpsManagerWrapper {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700375public:
376 MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700377 MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700378 MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
379
380 void checkPermissionSuccess() {
381 ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
382 }
383 void checkPermissionFails() {
384 ON_CALL(*this, checkPermission(_, _, _))
385 .WillByDefault(
386 Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
387 }
388 void initializeStartWatchingMode() {
389 ON_CALL(*this, startWatchingMode(_, _, _))
390 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
391 }
392 void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
393 mStoredCallback = cb;
394 }
395
396 sp<IAppOpsCallback> mStoredCallback;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700397};
398
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700399class MockJniWrapper : public JniWrapper {
400public:
401 MOCK_CONST_METHOD0(initializeForCurrentThread, void());
402
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700403 MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700404};
405
406class MockLooperWrapper : public LooperWrapper {
407public:
408 MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
409 MOCK_METHOD1(removeFd, int(int));
410 MOCK_METHOD0(wake, void());
411 MOCK_METHOD1(pollAll, int(int));
412
413 MockLooperWrapper() {
414 ON_CALL(*this, addFd(_, _, _, _, _))
415 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
416 ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700417 ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700418 }
419
420 int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
421 mCallback = callback;
422 mCallbackData = data;
423 return 0;
424 }
425
426 int clearCallback(int) {
427 mCallback = nullptr;
428 mCallbackData = nullptr;
429 return 0;
430 }
431
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700432 int wait10Ms(int) {
433 // This is called from a loop in runCmdLooper.
434 // Sleeping for 10ms only to avoid busy looping.
435 std::this_thread::sleep_for(10ms);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700436 return 0;
437 }
438
439 android::Looper_callbackFunc mCallback = nullptr;
440 void* mCallbackData = nullptr;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700441};
442
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700443class MockTimedQueueWrapper : public TimedQueueWrapper {
444public:
445 MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
446 MOCK_METHOD1(removeJobs, void(MountId));
447 MOCK_METHOD0(stop, void());
448
449 MockTimedQueueWrapper() {
450 ON_CALL(*this, addJob(_, _, _))
451 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
452 ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
453 }
454
455 void storeJob(MountId id, Milliseconds after, Job what) {
456 mId = id;
457 mAfter = after;
458 mWhat = std::move(what);
459 }
460
461 void clearJob(MountId id) {
462 if (mId == id) {
463 mAfter = {};
464 mWhat = {};
465 }
466 }
467
468 MountId mId = -1;
469 Milliseconds mAfter;
470 Job mWhat;
471};
472
Songchun Fan374f7652020-08-20 08:40:29 -0700473class MockFsWrapper : public FsWrapper {
474public:
475 MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
476 void hasNoFile() {
477 ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
478 }
479 void hasFiles() {
480 ON_CALL(*this, listFilesRecursive(_))
481 .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
482 }
483 std::vector<std::string> fakeFiles(std::string_view directoryPath) {
484 return {"base.apk", "split.apk", "lib/a.so"};
485 }
486};
487
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700488class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
489public:
490 MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
491
492 MockStorageHealthListener() {
493 ON_CALL(*this, onHealthStatus(_, _))
494 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
495 }
496
497 binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
498 mStorageId = storageId;
499 mStatus = status;
500 return binder::Status::ok();
501 }
502
503 int32_t mStorageId = -1;
504 int32_t mStatus = -1;
505};
506
Songchun Fana7098592020-09-03 11:45:53 -0700507class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
508public:
509 MockStorageLoadingProgressListener() = default;
510 MOCK_METHOD2(onStorageLoadingProgressChanged,
511 binder::Status(int32_t storageId, float progress));
512 MOCK_METHOD0(onAsBinder, IBinder*());
513};
514
Songchun Fan3c82a302019-11-29 14:23:45 -0800515class MockServiceManager : public ServiceManagerWrapper {
516public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800517 MockServiceManager(std::unique_ptr<MockVoldService> vold,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700518 std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700519 std::unique_ptr<MockIncFs> incfs,
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700520 std::unique_ptr<MockAppOpsManager> appOpsManager,
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700521 std::unique_ptr<MockJniWrapper> jni,
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700522 std::unique_ptr<MockLooperWrapper> looper,
Songchun Fan374f7652020-08-20 08:40:29 -0700523 std::unique_ptr<MockTimedQueueWrapper> timedQueue,
Songchun Fana7098592020-09-03 11:45:53 -0700524 std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
Songchun Fan374f7652020-08-20 08:40:29 -0700525 std::unique_ptr<MockFsWrapper> fs)
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800526 : mVold(std::move(vold)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700527 mDataLoaderManager(std::move(dataLoaderManager)),
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700528 mIncFs(std::move(incfs)),
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700529 mAppOpsManager(std::move(appOpsManager)),
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700530 mJni(std::move(jni)),
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700531 mLooper(std::move(looper)),
Songchun Fan374f7652020-08-20 08:40:29 -0700532 mTimedQueue(std::move(timedQueue)),
Songchun Fana7098592020-09-03 11:45:53 -0700533 mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
Songchun Fan374f7652020-08-20 08:40:29 -0700534 mFs(std::move(fs)) {}
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800535 std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
Songchun Fan68645c42020-02-27 15:57:35 -0800536 std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
537 return std::move(mDataLoaderManager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800538 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800539 std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
Songchun Fan374f7652020-08-20 08:40:29 -0700540 std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
541 return std::move(mAppOpsManager);
542 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700543 std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700544 std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700545 std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
Songchun Fana7098592020-09-03 11:45:53 -0700546 std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
547 return std::move(mProgressUpdateJobQueue);
548 }
Songchun Fan374f7652020-08-20 08:40:29 -0700549 std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
Songchun Fan3c82a302019-11-29 14:23:45 -0800550
551private:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800552 std::unique_ptr<MockVoldService> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800553 std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800554 std::unique_ptr<MockIncFs> mIncFs;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700555 std::unique_ptr<MockAppOpsManager> mAppOpsManager;
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700556 std::unique_ptr<MockJniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700557 std::unique_ptr<MockLooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700558 std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700559 std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700560 std::unique_ptr<MockFsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800561};
562
563// --- IncrementalServiceTest ---
564
Songchun Fan3c82a302019-11-29 14:23:45 -0800565class IncrementalServiceTest : public testing::Test {
566public:
567 void SetUp() override {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800568 auto vold = std::make_unique<NiceMock<MockVoldService>>();
569 mVold = vold.get();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700570 sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
571 mDataLoader = dataLoader.get();
572 auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
Songchun Fan68645c42020-02-27 15:57:35 -0800573 mDataLoaderManager = dataloaderManager.get();
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800574 auto incFs = std::make_unique<NiceMock<MockIncFs>>();
575 mIncFs = incFs.get();
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700576 auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
577 mAppOpsManager = appOps.get();
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700578 auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
579 mJni = jni.get();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700580 auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
581 mLooper = looper.get();
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700582 auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
583 mTimedQueue = timedQueue.get();
Songchun Fana7098592020-09-03 11:45:53 -0700584 auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
585 mProgressUpdateJobQueue = progressUpdateJobQueue.get();
Songchun Fan374f7652020-08-20 08:40:29 -0700586 auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
587 mFs = fs.get();
Songchun Fana7098592020-09-03 11:45:53 -0700588 mIncrementalService = std::make_unique<
589 IncrementalService>(MockServiceManager(std::move(vold),
590 std::move(dataloaderManager),
591 std::move(incFs), std::move(appOps),
592 std::move(jni), std::move(looper),
593 std::move(timedQueue),
594 std::move(progressUpdateJobQueue),
595 std::move(fs)),
596 mRootDir.path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800597 mDataLoaderParcel.packageName = "com.test";
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800598 mDataLoaderParcel.arguments = "uri";
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700599 mDataLoaderManager->unbindFromDataLoaderSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800600 mIncrementalService->onSystemReady();
Songchun Fan374f7652020-08-20 08:40:29 -0700601 setupSuccess();
Songchun Fan3c82a302019-11-29 14:23:45 -0800602 }
603
604 void setUpExistingMountDir(const std::string& rootDir) {
605 const auto dir = rootDir + "/dir1";
606 const auto mountDir = dir + "/mount";
607 const auto backingDir = dir + "/backing_store";
608 const auto storageDir = mountDir + "/st0";
609 ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
610 ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
611 ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
612 ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
613 const auto mountInfoFile = rootDir + "/dir1/mount/.info";
614 const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
615 ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
616 ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800617 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
618 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
619 ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
620 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
621 ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
622 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
Songchun Fan3c82a302019-11-29 14:23:45 -0800623 }
624
Songchun Fan374f7652020-08-20 08:40:29 -0700625 void setupSuccess() {
626 mVold->mountIncFsSuccess();
627 mIncFs->makeFileSuccess();
628 mVold->bindMountSuccess();
629 mDataLoaderManager->bindToDataLoaderSuccess();
630 mDataLoaderManager->getDataLoaderSuccess();
631 }
632
Songchun Fan3c82a302019-11-29 14:23:45 -0800633protected:
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700634 NiceMock<MockVoldService>* mVold = nullptr;
635 NiceMock<MockIncFs>* mIncFs = nullptr;
636 NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
637 NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
638 NiceMock<MockJniWrapper>* mJni = nullptr;
639 NiceMock<MockLooperWrapper>* mLooper = nullptr;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700640 NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
Songchun Fana7098592020-09-03 11:45:53 -0700641 NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
Songchun Fan374f7652020-08-20 08:40:29 -0700642 NiceMock<MockFsWrapper>* mFs = nullptr;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700643 NiceMock<MockDataLoader>* mDataLoader = nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800644 std::unique_ptr<IncrementalService> mIncrementalService;
645 TemporaryDir mRootDir;
646 DataLoaderParamsParcel mDataLoaderParcel;
647};
648
Songchun Fan3c82a302019-11-29 14:23:45 -0800649TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
650 mVold->mountIncFsFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700651 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800652 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700653 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
654 IncrementalService::CreateOptions::CreateNew,
655 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800656 ASSERT_LT(storageId, 0);
657}
658
659TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
660 mVold->mountIncFsInvalidControlParcel();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700661 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
662 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800663 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700664 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
665 IncrementalService::CreateOptions::CreateNew,
666 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800667 ASSERT_LT(storageId, 0);
668}
669
670TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
671 mVold->mountIncFsSuccess();
672 mIncFs->makeFileFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700673 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
674 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800675 EXPECT_CALL(*mVold, unmountIncFs(_));
676 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, testCreateStorageBindMountFails) {
684 mVold->mountIncFsSuccess();
685 mIncFs->makeFileSuccess();
686 mVold->bindMountFails();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700687 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
688 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800689 EXPECT_CALL(*mVold, unmountIncFs(_));
690 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700691 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
692 IncrementalService::CreateOptions::CreateNew,
693 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800694 ASSERT_LT(storageId, 0);
695}
696
697TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
698 mVold->mountIncFsSuccess();
699 mIncFs->makeFileSuccess();
700 mVold->bindMountSuccess();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700701 mDataLoaderManager->bindToDataLoaderFails();
702 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
703 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700704 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
705 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
706 EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
Songchun Fan3c82a302019-11-29 14:23:45 -0800707 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
708 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700709 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
710 IncrementalService::CreateOptions::CreateNew,
711 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800712 ASSERT_LT(storageId, 0);
713}
714
715TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700716 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
717 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700718 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
719 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
720 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800721 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
722 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700723 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
724 IncrementalService::CreateOptions::CreateNew,
725 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800726 ASSERT_GE(storageId, 0);
727 mIncrementalService->deleteStorage(storageId);
728}
729
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700730TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700731 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
732 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700733 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
734 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
735 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
Songchun Fan3c82a302019-11-29 14:23:45 -0800736 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
737 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700738 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
739 IncrementalService::CreateOptions::CreateNew,
740 {}, {}, {});
Songchun Fan3c82a302019-11-29 14:23:45 -0800741 ASSERT_GE(storageId, 0);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700742 // Simulated crash/other connection breakage.
743 mDataLoaderManager->setDataLoaderStatusDestroyed();
744}
745
746TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700747 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700748 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
749 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700750 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
751 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
752 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
753 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,
757 {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700758 ASSERT_GE(storageId, 0);
759 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800760 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700761 mDataLoaderManager->setDataLoaderStatusStarted();
762}
763
764TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700765 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700766 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
767 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700768 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700769 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
770 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
771 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
772 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700773 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
774 IncrementalService::CreateOptions::CreateNew,
775 {}, {}, {});
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700776 ASSERT_GE(storageId, 0);
777 ASSERT_TRUE(mIncrementalService->startLoading(storageId));
778 mDataLoaderManager->setDataLoaderStatusCreated();
Songchun Fan3c82a302019-11-29 14:23:45 -0800779}
780
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700781TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700782 mDataLoader->initializeCreateOkNoStatus();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700783 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
784 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
785 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
786 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
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,
792 {}, {}, {});
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700793 ASSERT_GE(storageId, 0);
794 mDataLoaderManager->setDataLoaderStatusUnavailable();
795}
796
797TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700798 mIncFs->waitForPendingReadsSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700799 mIncFs->openMountSuccess();
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700800 mDataLoader->initializeCreateOkNoStatus();
Songchun Fan374f7652020-08-20 08:40:29 -0700801
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700802 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700803 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700804 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
805 EXPECT_CALL(*mDataLoader, start(_)).Times(0);
Alex Buynytskyy4dbc0602020-05-12 11:24:14 -0700806 EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700807 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
808 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
809 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
810 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700811 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
812 IncrementalService::CreateOptions::CreateNew,
813 {}, {}, {});
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700814 ASSERT_GE(storageId, 0);
815 mDataLoaderManager->setDataLoaderStatusUnavailable();
816 ASSERT_NE(nullptr, mLooper->mCallback);
817 ASSERT_NE(nullptr, mLooper->mCallbackData);
818 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
819}
820
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700821TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700822 mIncFs->openMountSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700823
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700824 EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
825 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
826 EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
827 EXPECT_CALL(*mDataLoader, start(_)).Times(1);
828 EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
829 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
830 EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
831 EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
832 EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
833
834 sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
835 NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
836 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
837 .Times(2);
838 EXPECT_CALL(*listenerMock,
839 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
840 .Times(1);
841 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
842 .Times(1);
843 EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
844 .Times(2);
845
846 StorageHealthCheckParams params;
847 params.blockedTimeoutMs = 10000;
848 params.unhealthyTimeoutMs = 20000;
849 params.unhealthyMonitoringMs = 30000;
850
851 using MS = std::chrono::milliseconds;
852 using MCS = std::chrono::microseconds;
853
854 const auto blockedTimeout = MS(params.blockedTimeoutMs);
855 const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
856 const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
857
858 const uint64_t kFirstTimestampUs = 1000000000ll;
859 const uint64_t kBlockedTimestampUs =
860 kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
861 const uint64_t kUnhealthyTimestampUs =
862 kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
863
864 TemporaryDir tempDir;
865 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
866 IncrementalService::CreateOptions::CreateNew,
867 {}, std::move(params), listener);
868 ASSERT_GE(storageId, 0);
869
870 // Healthy state, registered for pending reads.
871 ASSERT_NE(nullptr, mLooper->mCallback);
872 ASSERT_NE(nullptr, mLooper->mCallbackData);
873 ASSERT_EQ(storageId, listener->mStorageId);
874 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
875
876 // Looper/epoll callback.
877 mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
878 mLooper->mCallback(-1, -1, mLooper->mCallbackData);
879
880 // Unregister from pending reads and wait.
881 ASSERT_EQ(nullptr, mLooper->mCallback);
882 ASSERT_EQ(nullptr, mLooper->mCallbackData);
883 ASSERT_EQ(storageId, listener->mStorageId);
884 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
885 // Timed callback present.
886 ASSERT_EQ(storageId, mTimedQueue->mId);
887 ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
888 auto timedCallback = mTimedQueue->mWhat;
889 mTimedQueue->clearJob(storageId);
890
891 // Timed job callback for blocked.
892 mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
893 timedCallback();
894
895 // Still not registered, and blocked.
896 ASSERT_EQ(nullptr, mLooper->mCallback);
897 ASSERT_EQ(nullptr, mLooper->mCallbackData);
898 ASSERT_EQ(storageId, listener->mStorageId);
899 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
900 // Timed callback present.
901 ASSERT_EQ(storageId, mTimedQueue->mId);
902 ASSERT_GE(mTimedQueue->mAfter, 1000ms);
903 timedCallback = mTimedQueue->mWhat;
904 mTimedQueue->clearJob(storageId);
905
906 // Timed job callback for unhealthy.
907 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
908 timedCallback();
909
910 // Still not registered, and blocked.
911 ASSERT_EQ(nullptr, mLooper->mCallback);
912 ASSERT_EQ(nullptr, mLooper->mCallbackData);
913 ASSERT_EQ(storageId, listener->mStorageId);
914 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
915 // Timed callback present.
916 ASSERT_EQ(storageId, mTimedQueue->mId);
917 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
918 timedCallback = mTimedQueue->mWhat;
919 mTimedQueue->clearJob(storageId);
920
921 // One more unhealthy.
922 mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
923 timedCallback();
924
925 // Still not registered, and blocked.
926 ASSERT_EQ(nullptr, mLooper->mCallback);
927 ASSERT_EQ(nullptr, mLooper->mCallbackData);
928 ASSERT_EQ(storageId, listener->mStorageId);
929 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
930 // Timed callback present.
931 ASSERT_EQ(storageId, mTimedQueue->mId);
932 ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
933 timedCallback = mTimedQueue->mWhat;
934 mTimedQueue->clearJob(storageId);
935
936 // And now healthy.
937 mIncFs->waitForPendingReadsTimeout();
938 timedCallback();
939
940 // Healthy state, registered for pending reads.
941 ASSERT_NE(nullptr, mLooper->mCallback);
942 ASSERT_NE(nullptr, mLooper->mCallbackData);
943 ASSERT_EQ(storageId, listener->mStorageId);
944 ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
945}
946
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700947TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700948 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700949 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700950
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700951 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700952 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700953 // We are calling setIncFsMountOptions(true).
954 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
955 // After setIncFsMountOptions succeeded expecting to start watching.
956 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
957 // Not expecting callback removal.
958 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700959 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700960 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
961 IncrementalService::CreateOptions::CreateNew,
962 {}, {}, {});
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700963 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700964 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700965}
966
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700967TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700968 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700969 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -0700970
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700971 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
972 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
973 // Enabling and then disabling readlogs.
974 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
975 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
976 // After setIncFsMountOptions succeeded expecting to start watching.
977 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
978 // Not expecting callback removal.
979 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
980 TemporaryDir tempDir;
981 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
982 IncrementalService::CreateOptions::CreateNew,
983 {}, {}, {});
984 ASSERT_GE(storageId, 0);
985 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
986 // Now disable.
987 mIncrementalService->disableReadLogs(storageId);
988 ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
989}
990
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700991TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700992 mVold->setIncFsMountOptionsSuccess();
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700993 mAppOpsManager->checkPermissionSuccess();
994 mAppOpsManager->initializeStartWatchingMode();
Songchun Fan374f7652020-08-20 08:40:29 -0700995
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700996 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700997 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
998 // We are calling setIncFsMountOptions(true).
999 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1000 // setIncFsMountOptions(false) is called on the callback.
1001 EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
1002 // After setIncFsMountOptions succeeded expecting to start watching.
1003 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
1004 // After callback is called, disable read logs and remove callback.
1005 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
1006 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001007 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1008 IncrementalService::CreateOptions::CreateNew,
1009 {}, {}, {});
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001010 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001011 ASSERT_GE(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001012 ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
1013 mAppOpsManager->mStoredCallback->opChanged(0, {});
1014}
1015
1016TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001017 mAppOpsManager->checkPermissionFails();
Songchun Fan374f7652020-08-20 08:40:29 -07001018
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001019 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001020 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1021 // checkPermission fails, no calls to set opitions, start or stop WatchingMode.
1022 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1023 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1024 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1025 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001026 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1027 IncrementalService::CreateOptions::CreateNew,
1028 {}, {}, {});
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001029 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001030 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001031}
1032
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001033TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001034 mVold->setIncFsMountOptionsFails();
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001035 mAppOpsManager->checkPermissionSuccess();
Songchun Fan374f7652020-08-20 08:40:29 -07001036
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001037 EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001038 EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
Alex Buynytskyy1d892162020-04-03 23:00:19 -07001039 // We are calling setIncFsMountOptions.
1040 EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1041 // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1042 EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1043 EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001044 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001045 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1046 IncrementalService::CreateOptions::CreateNew,
1047 {}, {}, {});
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001048 ASSERT_GE(storageId, 0);
Alex Buynytskyyea1390f2020-04-22 16:08:50 -07001049 ASSERT_LT(mDataLoader->setStorageParams(true), 0);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -07001050}
1051
Songchun Fan3c82a302019-11-29 14:23:45 -08001052TEST_F(IncrementalServiceTest, testMakeDirectory) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001053 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001054 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1055 IncrementalService::CreateOptions::CreateNew,
1056 {}, {}, {});
Songchun Fan103ba1d2020-02-03 17:32:32 -08001057 std::string dir_path("test");
Songchun Fan3c82a302019-11-29 14:23:45 -08001058
Songchun Fan103ba1d2020-02-03 17:32:32 -08001059 // Expecting incfs to call makeDir on a path like:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001060 // <root>/*/mount/<storage>/test
1061 EXPECT_CALL(*mIncFs,
1062 makeDir(_, Truly([&](std::string_view arg) {
1063 return arg.starts_with(mRootDir.path) &&
1064 arg.ends_with("/mount/st_1_0/" + dir_path);
1065 }),
1066 _));
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001067 auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1068 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001069}
1070
1071TEST_F(IncrementalServiceTest, testMakeDirectories) {
Songchun Fan3c82a302019-11-29 14:23:45 -08001072 TemporaryDir tempDir;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -07001073 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1074 IncrementalService::CreateOptions::CreateNew,
1075 {}, {}, {});
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001076 auto first = "first"sv;
1077 auto second = "second"sv;
1078 auto third = "third"sv;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001079 auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
Songchun Fan103ba1d2020-02-03 17:32:32 -08001080
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -07001081 EXPECT_CALL(*mIncFs,
1082 makeDirs(_, Truly([&](std::string_view arg) {
1083 return arg.starts_with(mRootDir.path) &&
1084 arg.ends_with("/mount/st_1_0/" + dir_path);
1085 }),
1086 _));
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -07001087 auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -08001088 ASSERT_EQ(res, 0);
Songchun Fan3c82a302019-11-29 14:23:45 -08001089}
Songchun Fan374f7652020-08-20 08:40:29 -07001090
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -07001091TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) {
1092 mIncFs->countFilledBlocksFails();
1093 mFs->hasNoFile();
1094
1095 TemporaryDir tempDir;
1096 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1097 IncrementalService::CreateOptions::CreateNew,
1098 {}, {}, {});
1099 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1100}
1101
1102TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) {
1103 mIncFs->countFilledBlocksFails();
1104 mFs->hasFiles();
1105
1106 TemporaryDir tempDir;
1107 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1108 IncrementalService::CreateOptions::CreateNew,
1109 {}, {}, {});
1110 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1111 ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1112}
1113
1114TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) {
1115 mIncFs->countFilledBlocksEmpty();
1116 mFs->hasFiles();
1117
1118 TemporaryDir tempDir;
1119 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1120 IncrementalService::CreateOptions::CreateNew,
1121 {}, {}, {});
1122 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1123 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1124}
1125
1126TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
1127 mIncFs->countFilledBlocksFullyLoaded();
1128 mFs->hasFiles();
1129
1130 TemporaryDir tempDir;
1131 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1132 IncrementalService::CreateOptions::CreateNew,
1133 {}, {}, {});
1134 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1135 ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
1136}
1137
Songchun Fan425862f2020-08-25 13:12:16 -07001138TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
Songchun Fan374f7652020-08-20 08:40:29 -07001139 mIncFs->countFilledBlocksSuccess();
1140 mFs->hasNoFile();
1141
1142 TemporaryDir tempDir;
1143 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1144 IncrementalService::CreateOptions::CreateNew,
1145 {}, {}, {});
Songchun Fan425862f2020-08-25 13:12:16 -07001146 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId));
Songchun Fan374f7652020-08-20 08:40:29 -07001147}
1148
1149TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
1150 mIncFs->countFilledBlocksFails();
1151 mFs->hasFiles();
1152
1153 TemporaryDir tempDir;
1154 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1155 IncrementalService::CreateOptions::CreateNew,
1156 {}, {}, {});
1157 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
1158 ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId));
1159}
1160
Songchun Fan425862f2020-08-25 13:12:16 -07001161TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
Songchun Fan374f7652020-08-20 08:40:29 -07001162 mIncFs->countFilledBlocksEmpty();
1163 mFs->hasFiles();
1164
1165 TemporaryDir tempDir;
1166 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1167 IncrementalService::CreateOptions::CreateNew,
1168 {}, {}, {});
1169 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
Songchun Fan425862f2020-08-25 13:12:16 -07001170 ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId));
Songchun Fan374f7652020-08-20 08:40:29 -07001171}
1172
1173TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
1174 mIncFs->countFilledBlocksSuccess();
1175 mFs->hasFiles();
1176
1177 TemporaryDir tempDir;
1178 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1179 IncrementalService::CreateOptions::CreateNew,
1180 {}, {}, {});
1181 EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
1182 ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId));
1183}
Songchun Fana7098592020-09-03 11:45:53 -07001184
1185TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
1186 mIncFs->countFilledBlocksSuccess();
1187 mFs->hasFiles();
1188
1189 TemporaryDir tempDir;
1190 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1191 IncrementalService::CreateOptions::CreateNew,
1192 {}, {}, {});
1193 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1194 new NiceMock<MockStorageLoadingProgressListener>};
1195 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1196 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
1197 EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
1198 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1199 // Timed callback present.
1200 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1201 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1202 auto timedCallback = mProgressUpdateJobQueue->mWhat;
1203 timedCallback();
1204 ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
1205 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
1206 mIncrementalService->unregisterLoadingProgressListener(storageId);
1207 ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
1208}
1209
1210TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
1211 mIncFs->countFilledBlocksFails();
1212 mFs->hasFiles();
1213
1214 TemporaryDir tempDir;
1215 int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1216 IncrementalService::CreateOptions::CreateNew,
1217 {}, {}, {});
1218 sp<NiceMock<MockStorageLoadingProgressListener>> listener{
1219 new NiceMock<MockStorageLoadingProgressListener>};
1220 NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
1221 EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
1222 mIncrementalService->registerLoadingProgressListener(storageId, listener);
1223}
Songchun Fan3c82a302019-11-29 14:23:45 -08001224} // namespace android::os::incremental