/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include namespace android { namespace hardware { namespace health { namespace storage { namespace V1_0 { using namespace ::android::hardware::health::storage::test; using ::std::literals::chrono_literals::operator""ms; #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) << ret.description() class GcCallback : public IGarbageCollectCallback, public Flag { public: Return onFinish(Result result) override { std::unique_lock lock(mutex_); result_ = result; Flag::OnFinishLocked(&lock); return Void(); } /** * Wait for a specific "timeout". If GC has finished, test that the result * is equal to the "expected" value. */ template void waitForResult(std::chrono::duration timeout, Result expected) { std::unique_lock lock(mutex_); ASSERT_TRUE(WaitLocked(&lock, timeout)) << "timeout after " << to_string(timeout); EXPECT_EQ(expected, result_); } private: Result result_{Result::UNKNOWN_ERROR}; }; class HealthStorageHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { fs = IStorage::getService(GetParam()); ASSERT_NE(fs, nullptr); LOG(INFO) << "Service is remote " << fs->isRemote(); } virtual void TearDown() override { EXPECT_TRUE(ping(kRpcTime)) << "Service is not responsive; expect subsequent tests to fail."; } /** * Ping the service and expect it to return after "timeout". Return true * iff the service is responsive within "timeout". */ template bool ping(std::chrono::duration timeout) { // Ensure the service is responsive after the test. sp service = fs; auto pingFlag = std::make_shared(); std::thread([service, pingFlag] { service->ping(); pingFlag->OnFinish(); }) .detach(); return pingFlag->Wait(timeout); } sp fs; }; /** * Ensure garbage collection works on null callback. */ TEST_P(HealthStorageHidlTest, GcNullCallback) { auto ret = fs->garbageCollect(kDevGcTimeoutSec, nullptr); ASSERT_OK(ret); // Hold test process because HAL can be single-threaded and doing GC. ASSERT_TRUE(ping(kDevGcTimeout + kDevGcTolerance + kRpcTime)) << "Service must be available after " << to_string(kDevGcTimeout + kDevGcTolerance + kRpcTime); } /** * Ensure garbage collection works on non-null callback. */ TEST_P(HealthStorageHidlTest, GcNonNullCallback) { sp cb = new GcCallback(); auto ret = fs->garbageCollect(kDevGcTimeoutSec, cb); ASSERT_OK(ret); cb->waitForResult(kDevGcTimeout + kDevGcTolerance + kRpcTime, Result::SUCCESS); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HealthStorageHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, HealthStorageHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IStorage::descriptor)), android::hardware::PrintInstanceNameToString); } // namespace V1_0 } // namespace storage } // namespace health } // namespace hardware } // namespace android