health storage: refactor common code for test

Test: pass
Bug: 177470478
Change-Id: I7be46664df08fd600143ca018885c64030e8d6a1
This commit is contained in:
Yifan Hong 2021-01-15 17:24:27 -08:00
parent feed84d11d
commit 571f926977
4 changed files with 110 additions and 59 deletions

View file

@ -19,6 +19,9 @@ cc_test {
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalHealthStorageV1_0TargetTest.cpp"],
static_libs: ["android.hardware.health.storage@1.0"],
header_libs: [
"libhealth_storage_test_common_headers",
],
shared_libs: [
"libhidlbase",
],

View file

@ -14,14 +14,17 @@
* limitations under the License.
*/
#include <unistd.h>
#include <thread>
#include <android-base/logging.h>
#include <android/hardware/health/storage/1.0/IStorage.h>
#include <gtest/gtest.h>
#include <health-storage-test/common.h>
#include <hidl/GtestPrinter.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/ServiceManagement.h>
#include <unistd.h>
#include <thread>
namespace android {
namespace hardware {
@ -29,61 +32,17 @@ 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()
// Dev GC timeout. This is the timeout used by vold.
const uint64_t kDevGcTimeoutSec = 120;
const std::chrono::seconds kDevGcTimeout{kDevGcTimeoutSec};
// Dev GC timeout tolerance. The HAL may not immediately return after the
// timeout, so include an acceptable tolerance.
const std::chrono::seconds kDevGcTolerance{3};
// Time accounted for RPC calls.
const std::chrono::milliseconds kRpcTime{1000};
template <typename R>
std::string toString(std::chrono::duration<R, std::milli> time) {
return std::to_string(time.count()) + "ms";
}
/** An atomic boolean flag that indicates whether a task has finished. */
class Flag {
public:
void onFinish() {
std::unique_lock<std::mutex> lock(mMutex);
onFinishLocked(&lock);
}
template <typename R, typename P>
bool wait(std::chrono::duration<R, P> duration) {
std::unique_lock<std::mutex> lock(mMutex);
return waitLocked(&lock, duration);
}
protected:
/** Will unlock. */
void onFinishLocked(std::unique_lock<std::mutex>* lock) {
mFinished = true;
lock->unlock();
mCv.notify_all();
}
template <typename R, typename P>
bool waitLocked(std::unique_lock<std::mutex>* lock, std::chrono::duration<R, P> duration) {
mCv.wait_for(*lock, duration, [this] { return mFinished; });
return mFinished;
}
bool mFinished{false};
std::mutex mMutex;
std::condition_variable mCv;
};
class GcCallback : public IGarbageCollectCallback, public Flag {
public:
public:
Return<void> onFinish(Result result) override {
std::unique_lock<std::mutex> lock(mMutex);
mResult = result;
Flag::onFinishLocked(&lock);
std::unique_lock<std::mutex> lock(mutex_);
result_ = result;
Flag::OnFinishLocked(&lock);
return Void();
}
@ -93,13 +52,13 @@ class GcCallback : public IGarbageCollectCallback, public Flag {
*/
template <typename R, typename P>
void waitForResult(std::chrono::duration<R, P> timeout, Result expected) {
std::unique_lock<std::mutex> lock(mMutex);
ASSERT_TRUE(waitLocked(&lock, timeout)) << "timeout after " << toString(timeout);
EXPECT_EQ(expected, mResult);
std::unique_lock<std::mutex> lock(mutex_);
ASSERT_TRUE(WaitLocked(&lock, timeout)) << "timeout after " << to_string(timeout);
EXPECT_EQ(expected, result_);
}
private:
Result mResult{Result::UNKNOWN_ERROR};
private:
Result result_{Result::UNKNOWN_ERROR};
};
class HealthStorageHidlTest : public ::testing::TestWithParam<std::string> {
@ -127,10 +86,10 @@ class HealthStorageHidlTest : public ::testing::TestWithParam<std::string> {
auto pingFlag = std::make_shared<Flag>();
std::thread([service, pingFlag] {
service->ping();
pingFlag->onFinish();
pingFlag->OnFinish();
})
.detach();
return pingFlag->wait(timeout);
return pingFlag->Wait(timeout);
}
sp<IStorage> fs;
@ -147,7 +106,7 @@ TEST_P(HealthStorageHidlTest, GcNullCallback) {
// Hold test process because HAL can be single-threaded and doing GC.
ASSERT_TRUE(ping(kDevGcTimeout + kDevGcTolerance + kRpcTime))
<< "Service must be available after "
<< toString(kDevGcTimeout + kDevGcTolerance + kRpcTime);
<< to_string(kDevGcTimeout + kDevGcTolerance + kRpcTime);
}
/**

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) 2021 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.
*/
cc_library_headers {
name: "libhealth_storage_test_common_headers",
export_include_dirs: ["include"],
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2021 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.
*/
#pragma once
#include <chrono>
#include <string>
namespace android::hardware::health::storage::test {
// Dev GC timeout. This is the timeout used by vold.
const uint64_t kDevGcTimeoutSec = 120;
const std::chrono::seconds kDevGcTimeout{kDevGcTimeoutSec};
// Dev GC timeout tolerance. The HAL may not immediately return after the
// timeout, so include an acceptable tolerance.
const std::chrono::seconds kDevGcTolerance{3};
// Time accounted for RPC calls.
const std::chrono::milliseconds kRpcTime{1000};
template <typename R>
std::string to_string(std::chrono::duration<R, std::milli> time) {
return std::to_string(time.count()) + "ms";
}
/** An atomic boolean flag that indicates whether a task has finished. */
class Flag {
public:
void OnFinish() {
std::unique_lock<std::mutex> lock(mutex_);
OnFinishLocked(&lock);
}
template <typename R, typename P>
bool Wait(std::chrono::duration<R, P> duration) {
std::unique_lock<std::mutex> lock(mutex_);
return WaitLocked(&lock, duration);
}
protected:
/** Will unlock. */
void OnFinishLocked(std::unique_lock<std::mutex>* lock) {
finished_ = true;
lock->unlock();
cv_.notify_all();
}
template <typename R, typename P>
bool WaitLocked(std::unique_lock<std::mutex>* lock, std::chrono::duration<R, P> duration) {
cv_.wait_for(*lock, duration, [this] { return finished_; });
return finished_;
}
bool finished_{false};
std::mutex mutex_;
std::condition_variable cv_;
};
} // namespace android::hardware::health::storage::test