1 /*
2 * Copyright (C) 2018 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 <unistd.h>
18
19 #include <thread>
20
21 #include <android-base/logging.h>
22 #include <android/hardware/health/storage/1.0/IStorage.h>
23 #include <gtest/gtest.h>
24 #include <health-storage-test/common.h>
25 #include <hidl/GtestPrinter.h>
26 #include <hidl/HidlTransportSupport.h>
27 #include <hidl/ServiceManagement.h>
28
29 namespace android {
30 namespace hardware {
31 namespace health {
32 namespace storage {
33 namespace V1_0 {
34
35 using namespace ::android::hardware::health::storage::test;
36 using ::std::literals::chrono_literals::operator""ms;
37
38 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) << ret.description()
39
40 class GcCallback : public IGarbageCollectCallback, public Flag {
41 public:
onFinish(Result result)42 Return<void> onFinish(Result result) override {
43 std::unique_lock<std::mutex> lock(mutex_);
44 result_ = result;
45 Flag::OnFinishLocked(&lock);
46 return Void();
47 }
48
49 /**
50 * Wait for a specific "timeout". If GC has finished, test that the result
51 * is equal to the "expected" value.
52 */
53 template <typename R, typename P>
waitForResult(std::chrono::duration<R,P> timeout,Result expected)54 void waitForResult(std::chrono::duration<R, P> timeout, Result expected) {
55 std::unique_lock<std::mutex> lock(mutex_);
56 ASSERT_TRUE(WaitLocked(&lock, timeout)) << "timeout after " << to_string(timeout);
57 EXPECT_EQ(expected, result_);
58 }
59
60 private:
61 Result result_{Result::UNKNOWN_ERROR};
62 };
63
64 class HealthStorageHidlTest : public ::testing::TestWithParam<std::string> {
65 public:
SetUp()66 virtual void SetUp() override {
67 fs = IStorage::getService(GetParam());
68
69 ASSERT_NE(fs, nullptr);
70 LOG(INFO) << "Service is remote " << fs->isRemote();
71 }
72
TearDown()73 virtual void TearDown() override {
74 EXPECT_TRUE(ping(kRpcTime))
75 << "Service is not responsive; expect subsequent tests to fail.";
76 }
77
78 /**
79 * Ping the service and expect it to return after "timeout". Return true
80 * iff the service is responsive within "timeout".
81 */
82 template <typename R, typename P>
ping(std::chrono::duration<R,P> timeout)83 bool ping(std::chrono::duration<R, P> timeout) {
84 // Ensure the service is responsive after the test.
85 sp<IStorage> service = fs;
86 auto pingFlag = std::make_shared<Flag>();
87 std::thread([service, pingFlag] {
88 service->ping();
89 pingFlag->OnFinish();
90 })
91 .detach();
92 return pingFlag->Wait(timeout);
93 }
94
95 sp<IStorage> fs;
96 };
97
98 /**
99 * Ensure garbage collection works on null callback.
100 */
TEST_P(HealthStorageHidlTest,GcNullCallback)101 TEST_P(HealthStorageHidlTest, GcNullCallback) {
102 auto ret = fs->garbageCollect(kDevGcTimeoutSec, nullptr);
103
104 ASSERT_OK(ret);
105
106 // Hold test process because HAL can be single-threaded and doing GC.
107 ASSERT_TRUE(ping(kDevGcTimeout + kDevGcTolerance + kRpcTime))
108 << "Service must be available after "
109 << to_string(kDevGcTimeout + kDevGcTolerance + kRpcTime);
110 }
111
112 /**
113 * Ensure garbage collection works on non-null callback.
114 */
TEST_P(HealthStorageHidlTest,GcNonNullCallback)115 TEST_P(HealthStorageHidlTest, GcNonNullCallback) {
116 sp<GcCallback> cb = new GcCallback();
117 auto ret = fs->garbageCollect(kDevGcTimeoutSec, cb);
118 ASSERT_OK(ret);
119 cb->waitForResult(kDevGcTimeout + kDevGcTolerance + kRpcTime, Result::SUCCESS);
120 }
121
122 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HealthStorageHidlTest);
123 INSTANTIATE_TEST_SUITE_P(
124 PerInstance, HealthStorageHidlTest,
125 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IStorage::descriptor)),
126 android::hardware::PrintInstanceNameToString);
127
128 } // namespace V1_0
129 } // namespace storage
130 } // namespace health
131 } // namespace hardware
132 } // namespace android
133