diff options
Diffstat (limited to 'services/incremental/test/IncrementalServiceTest.cpp')
-rw-r--r-- | services/incremental/test/IncrementalServiceTest.cpp | 175 |
1 files changed, 157 insertions, 18 deletions
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp index 6a3d953f74aa..68586a89ff07 100644 --- a/services/incremental/test/IncrementalServiceTest.cpp +++ b/services/incremental/test/IncrementalServiceTest.cpp @@ -126,7 +126,7 @@ private: class MockDataLoader : public IDataLoader { public: MockDataLoader() { - ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk)); + initializeCreateOk(); ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk)); ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk)); ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk)); @@ -145,6 +145,10 @@ public: binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles, const std::vector<std::string>& removedFiles)); + void initializeCreateOk() { + ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk)); + } + void initializeCreateOkNoStatus() { ON_CALL(*this, create(_, _, _, _)) .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus)); @@ -275,6 +279,14 @@ public: } return binder::Status::ok(); } + binder::Status bindToDataLoaderOkWithNoDelay(int32_t mountId, + const DataLoaderParamsParcel& params, + int bindDelayMs, + const sp<IDataLoaderStatusListener>& listener, + bool* _aidl_return) { + CHECK(bindDelayMs == 0) << bindDelayMs; + return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return); + } binder::Status bindToDataLoaderOkWith1sDelay(int32_t mountId, const DataLoaderParamsParcel& params, int bindDelayMs, @@ -338,14 +350,13 @@ public: mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE); } binder::Status unbindFromDataLoaderOk(int32_t id) { + mBindDelayMs = -1; if (mDataLoader) { if (auto status = mDataLoader->destroy(id); !status.isOk()) { return status; } mDataLoader = nullptr; - } - mBindDelayMs = -1; - if (mListener) { + } else if (mListener) { mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED); } return binder::Status::ok(); @@ -775,16 +786,53 @@ public: mDataLoaderManager->getDataLoaderSuccess(); } - void checkMillisSinceOldestPendingRead(int storageId, long expected) { + void checkHealthMetrics(int storageId, long expectedMillisSinceOldestPendingRead, + int expectedStorageHealthStatusCode) { android::os::PersistableBundle result{}; mIncrementalService->getMetrics(storageId, &result); - int64_t value = -1; + ASSERT_EQ(6, (int)result.size()); + int64_t millisSinceOldestPendingRead = -1; ASSERT_TRUE(result.getLong(String16(BnIncrementalService:: METRICS_MILLIS_SINCE_OLDEST_PENDING_READ() .c_str()), - &value)); - ASSERT_EQ(expected, value); - ASSERT_EQ(1, (int)result.size()); + &millisSinceOldestPendingRead)); + ASSERT_EQ(expectedMillisSinceOldestPendingRead, millisSinceOldestPendingRead); + int storageHealthStatusCode = -1; + ASSERT_TRUE( + result.getInt(String16(BnIncrementalService::METRICS_STORAGE_HEALTH_STATUS_CODE() + .c_str()), + &storageHealthStatusCode)); + ASSERT_EQ(expectedStorageHealthStatusCode, storageHealthStatusCode); + int dataLoaderStatusCode = -1; + ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_DATA_LOADER_STATUS_CODE() + .c_str()), + &dataLoaderStatusCode)); + ASSERT_EQ(IDataLoaderStatusListener::DATA_LOADER_STARTED, dataLoaderStatusCode); + } + + void checkBindingMetrics(int storageId, int64_t expectedMillisSinceLastDataLoaderBind, + int64_t expectedDataLoaderBindDelayMillis) { + android::os::PersistableBundle result{}; + mIncrementalService->getMetrics(storageId, &result); + ASSERT_EQ(6, (int)result.size()); + int dataLoaderStatus = -1; + ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_DATA_LOADER_STATUS_CODE() + .c_str()), + &dataLoaderStatus)); + ASSERT_EQ(IDataLoaderStatusListener::DATA_LOADER_STARTED, dataLoaderStatus); + int64_t millisSinceLastDataLoaderBind = -1; + ASSERT_TRUE(result.getLong(String16(BnIncrementalService:: + METRICS_MILLIS_SINCE_LAST_DATA_LOADER_BIND() + .c_str()), + &millisSinceLastDataLoaderBind)); + ASSERT_EQ(expectedMillisSinceLastDataLoaderBind, millisSinceLastDataLoaderBind); + int64_t dataLoaderBindDelayMillis = -1; + ASSERT_TRUE( + result.getLong(String16( + BnIncrementalService::METRICS_DATA_LOADER_BIND_DELAY_MILLIS() + .c_str()), + &dataLoaderBindDelayMillis)); + ASSERT_EQ(expectedDataLoaderBindDelayMillis, dataLoaderBindDelayMillis); } protected: @@ -904,38 +952,55 @@ TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) { ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay)); + checkBindingMetrics(storageId, 0, 0); mClock->advanceMs(mDataLoaderManager->bindDelayMs()); + checkBindingMetrics(storageId, 0, 0); mDataLoaderManager->setDataLoaderStatusDestroyed(); ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay)); + checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs()); mClock->advanceMs(mDataLoaderManager->bindDelayMs()); + checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(), + mDataLoaderManager->bindDelayMs()); mDataLoaderManager->setDataLoaderStatusDestroyed(); ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay)); + checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs()); mClock->advanceMs(mDataLoaderManager->bindDelayMs()); + checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(), + mDataLoaderManager->bindDelayMs()); mDataLoaderManager->setDataLoaderStatusDestroyed(); ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay)); + checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs()); mClock->advanceMs(mDataLoaderManager->bindDelayMs()); + checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(), + mDataLoaderManager->bindDelayMs()); mDataLoaderManager->setDataLoaderStatusDestroyed(); ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay)); + checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs()); // Try the reduced delay, just in case. mClock->advanceMs(mDataLoaderManager->bindDelayMs() / 2); + checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs() / 2, + mDataLoaderManager->bindDelayMs()); mDataLoaderManager->setDataLoaderStatusDestroyed(); ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay)); + checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs()); mClock->advanceMs(mDataLoaderManager->bindDelayMs()); + checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(), + mDataLoaderManager->bindDelayMs()); mDataLoaderManager->setDataLoaderStatusDestroyed(); } @@ -1156,12 +1221,81 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) { ASSERT_GE(storageId, 0); ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); - mDataLoaderManager->setDataLoaderStatusUnavailable(); + mDataLoaderManager->setDataLoaderStatusUnrecoverable(); + + // Timed callback present. + ASSERT_EQ(storageId, mTimedQueue->mId); + ASSERT_GE(mTimedQueue->mAfter, 10ms); + auto timedCallback = mTimedQueue->mWhat; + mTimedQueue->clearJob(storageId); + + // First callback call to propagate unrecoverable. + timedCallback(); + + // And second call to trigger recreation. ASSERT_NE(nullptr, mLooper->mCallback); ASSERT_NE(nullptr, mLooper->mCallbackData); mLooper->mCallback(-1, -1, mLooper->mCallbackData); } +TEST_F(IncrementalServiceTest, testStartDataLoaderUnavailable) { + mIncFs->openMountSuccess(); + mDataLoader->initializeCreateOkNoStatus(); + + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(3); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(3); + EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(3); + EXPECT_CALL(*mDataLoader, start(_)).Times(1); + EXPECT_CALL(*mDataLoader, destroy(_)).Times(2); + EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); + EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1); + EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1); + TemporaryDir tempDir; + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); + ASSERT_GE(storageId, 0); + + ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) + .WillByDefault(Invoke(mDataLoaderManager, + &MockDataLoaderManager::bindToDataLoaderOkWithNoDelay)); + + ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, + {}, {})); + + // Unavailable. + mDataLoaderManager->setDataLoaderStatusUnavailable(); + + // Timed callback present. + ASSERT_EQ(storageId, mTimedQueue->mId); + ASSERT_GE(mTimedQueue->mAfter, 10ms); + auto timedCallback = mTimedQueue->mWhat; + mTimedQueue->clearJob(storageId); + + // Propagating unavailable and expecting it to trigger rebind with 1s retry delay. + ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) + .WillByDefault(Invoke(mDataLoaderManager, + &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay)); + timedCallback(); + + // Unavailable #2. + mDataLoaderManager->setDataLoaderStatusUnavailable(); + + // Timed callback present. + ASSERT_EQ(storageId, mTimedQueue->mId); + ASSERT_GE(mTimedQueue->mAfter, 10ms); + timedCallback = mTimedQueue->mWhat; + mTimedQueue->clearJob(storageId); + + // Propagating unavailable and expecting it to trigger rebind with 10s retry delay. + // This time succeed. + mDataLoader->initializeCreateOk(); + ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)) + .WillByDefault(Invoke(mDataLoaderManager, + &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay)); + timedCallback(); +} + TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { mIncFs->openMountSuccess(); @@ -1218,7 +1352,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { ASSERT_NE(nullptr, mLooper->mCallbackData); ASSERT_EQ(storageId, listener->mStorageId); ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus); - checkMillisSinceOldestPendingRead(storageId, 0); + checkHealthMetrics(storageId, 0, listener->mStatus); // Looper/epoll callback. mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs); @@ -1244,7 +1378,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { ASSERT_EQ(nullptr, mLooper->mCallbackData); ASSERT_EQ(storageId, listener->mStorageId); ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus); - checkMillisSinceOldestPendingRead(storageId, params.blockedTimeoutMs); + checkHealthMetrics(storageId, params.blockedTimeoutMs, listener->mStatus); // Timed callback present. ASSERT_EQ(storageId, mTimedQueue->mId); @@ -1261,7 +1395,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { ASSERT_EQ(nullptr, mLooper->mCallbackData); ASSERT_EQ(storageId, listener->mStorageId); ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus); - checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs); + checkHealthMetrics(storageId, params.unhealthyTimeoutMs, listener->mStatus); // Timed callback present. ASSERT_EQ(storageId, mTimedQueue->mId); @@ -1278,7 +1412,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { ASSERT_EQ(nullptr, mLooper->mCallbackData); ASSERT_EQ(storageId, listener->mStorageId); ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus); - checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs); + checkHealthMetrics(storageId, params.unhealthyTimeoutMs, listener->mStatus); // Timed callback present. ASSERT_EQ(storageId, mTimedQueue->mId); @@ -1295,7 +1429,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { ASSERT_NE(nullptr, mLooper->mCallbackData); ASSERT_EQ(storageId, listener->mStorageId); ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus); - checkMillisSinceOldestPendingRead(storageId, 0); + checkHealthMetrics(storageId, 0, listener->mStatus); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) { @@ -2025,7 +2159,7 @@ TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) { ASSERT_TRUE(result.empty()); } -TEST_F(IncrementalServiceTest, testNoMetrics) { +TEST_F(IncrementalServiceTest, testNoDataLoaderMetrics) { mVold->setIncFsMountOptionsSuccess(); TemporaryDir tempDir; int storageId = @@ -2040,7 +2174,12 @@ TEST_F(IncrementalServiceTest, testNoMetrics) { .c_str()), &value)); ASSERT_EQ(expected, value); - ASSERT_EQ(0, (int)result.size()); + ASSERT_EQ(1, (int)result.size()); + bool expectedReadLogsEnabled = false; + ASSERT_TRUE( + result.getBoolean(String16(BnIncrementalService::METRICS_READ_LOGS_ENABLED().c_str()), + &expectedReadLogsEnabled)); + ASSERT_EQ(mVold->readLogsEnabled(), expectedReadLogsEnabled); } TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) { @@ -2057,7 +2196,7 @@ TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) { int64_t expected = -1, value = -1; ASSERT_FALSE(result.getLong(String16("invalid"), &value)); ASSERT_EQ(expected, value); - ASSERT_EQ(1, (int)result.size()); + ASSERT_EQ(6, (int)result.size()); } } // namespace android::os::incremental |