mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Add retry in setProp test.
Set property operation is async so getting the property value immediately after setting the property might not return the new value. This CL adds the logic to retry when we do not get the expected values back. This CL also skips the test case if getting property or setting property returns unavailable. Test: atest VtsHalAutomotiveVehicle_TargetTest Bug: 322070490 Change-Id: If9349a097a92c51101c7b5f4bf807b610ab2cb0b Merged-In: If9349a097a92c51101c7b5f4bf807b610ab2cb0b
This commit is contained in:
@@ -34,20 +34,22 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using ::aidl::android::hardware::automotive::vehicle::IVehicle;
|
using ::aidl::android::hardware::automotive::vehicle::IVehicle;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
|
|
||||||
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
|
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
|
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
|
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
|
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
|
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
|
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
|
||||||
|
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
|
||||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
|
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
|
||||||
using ::android::getAidlHalInstanceNames;
|
using ::android::getAidlHalInstanceNames;
|
||||||
|
using ::android::uptimeMillis;
|
||||||
using ::android::base::ScopedLockAssertion;
|
using ::android::base::ScopedLockAssertion;
|
||||||
using ::android::base::StringPrintf;
|
using ::android::base::StringPrintf;
|
||||||
using ::android::frameworks::automotive::vhal::ErrorCode;
|
using ::android::frameworks::automotive::vhal::ErrorCode;
|
||||||
@@ -56,11 +58,14 @@ using ::android::frameworks::automotive::vhal::IHalPropConfig;
|
|||||||
using ::android::frameworks::automotive::vhal::IHalPropValue;
|
using ::android::frameworks::automotive::vhal::IHalPropValue;
|
||||||
using ::android::frameworks::automotive::vhal::ISubscriptionCallback;
|
using ::android::frameworks::automotive::vhal::ISubscriptionCallback;
|
||||||
using ::android::frameworks::automotive::vhal::IVhalClient;
|
using ::android::frameworks::automotive::vhal::IVhalClient;
|
||||||
|
using ::android::frameworks::automotive::vhal::VhalClientResult;
|
||||||
using ::android::hardware::getAllHalInstanceNames;
|
using ::android::hardware::getAllHalInstanceNames;
|
||||||
using ::android::hardware::Sanitize;
|
using ::android::hardware::Sanitize;
|
||||||
using ::android::hardware::automotive::vehicle::toInt;
|
using ::android::hardware::automotive::vehicle::toInt;
|
||||||
|
|
||||||
constexpr int32_t kInvalidProp = 0x31600207;
|
constexpr int32_t kInvalidProp = 0x31600207;
|
||||||
|
// The timeout for retrying getting prop value after setting prop value.
|
||||||
|
constexpr int64_t kRetryGetPropAfterSetPropTimeoutMillis = 10'000;
|
||||||
|
|
||||||
struct ServiceDescriptor {
|
struct ServiceDescriptor {
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -117,6 +122,10 @@ class VtsVehicleCallback final : public ISubscriptionCallback {
|
|||||||
class VtsHalAutomotiveVehicleTargetTest : public testing::TestWithParam<ServiceDescriptor> {
|
class VtsHalAutomotiveVehicleTargetTest : public testing::TestWithParam<ServiceDescriptor> {
|
||||||
protected:
|
protected:
|
||||||
bool checkIsSupported(int32_t propertyId);
|
bool checkIsSupported(int32_t propertyId);
|
||||||
|
VehiclePropertyStatus getStatus(const IHalPropValue& halPropValue);
|
||||||
|
bool isUnavailable(const VhalClientResult<std::unique_ptr<IHalPropValue>>& result);
|
||||||
|
bool isResultOkayWithValue(const VhalClientResult<std::unique_ptr<IHalPropValue>>& result,
|
||||||
|
int32_t value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void verifyProperty(VehicleProperty propId, VehiclePropertyAccess access,
|
void verifyProperty(VehicleProperty propId, VehiclePropertyAccess access,
|
||||||
@@ -230,6 +239,41 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, getInvalidProp) {
|
|||||||
"Expect failure to get property for invalid prop: %" PRId32, kInvalidProp);
|
"Expect failure to get property for invalid prop: %" PRId32, kInvalidProp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VehiclePropertyStatus VtsHalAutomotiveVehicleTargetTest::getStatus(
|
||||||
|
const IHalPropValue& halPropValue) {
|
||||||
|
if (mVhalClient->isAidlVhal()) {
|
||||||
|
return reinterpret_cast<
|
||||||
|
const aidl::android::hardware::automotive::vehicle::VehiclePropValue*>(
|
||||||
|
halPropValue.toVehiclePropValue())
|
||||||
|
->status;
|
||||||
|
}
|
||||||
|
return static_cast<VehiclePropertyStatus>(
|
||||||
|
reinterpret_cast<const android::hardware::automotive::vehicle::V2_0::VehiclePropValue*>(
|
||||||
|
halPropValue.toVehiclePropValue())
|
||||||
|
->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VtsHalAutomotiveVehicleTargetTest::isResultOkayWithValue(
|
||||||
|
const VhalClientResult<std::unique_ptr<IHalPropValue>>& result, int32_t value) {
|
||||||
|
return result.ok() && result.value() != nullptr &&
|
||||||
|
getStatus(*(result.value())) == VehiclePropertyStatus::AVAILABLE &&
|
||||||
|
result.value()->getInt32Values().size() == 1 &&
|
||||||
|
result.value()->getInt32Values()[0] == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VtsHalAutomotiveVehicleTargetTest::isUnavailable(
|
||||||
|
const VhalClientResult<std::unique_ptr<IHalPropValue>>& result) {
|
||||||
|
if (!result.ok()) {
|
||||||
|
return result.error().code() == ErrorCode::NOT_AVAILABLE_FROM_VHAL;
|
||||||
|
}
|
||||||
|
if (result.value() != nullptr &&
|
||||||
|
getStatus(*(result.value())) == VehiclePropertyStatus::UNAVAILABLE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Test set() on read_write properties.
|
// Test set() on read_write properties.
|
||||||
TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
|
TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
|
||||||
ALOGD("VtsHalAutomotiveVehicleTargetTest::setProp");
|
ALOGD("VtsHalAutomotiveVehicleTargetTest::setProp");
|
||||||
@@ -257,6 +301,14 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
|
|||||||
auto propToGet = mVhalClient->createHalPropValue(propId);
|
auto propToGet = mVhalClient->createHalPropValue(propId);
|
||||||
auto getValueResult = mVhalClient->getValueSync(*propToGet);
|
auto getValueResult = mVhalClient->getValueSync(*propToGet);
|
||||||
|
|
||||||
|
if (isUnavailable(getValueResult)) {
|
||||||
|
ALOGW("getProperty for %" PRId32
|
||||||
|
" returns NOT_AVAILABLE, "
|
||||||
|
"skip testing setProp",
|
||||||
|
propId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT_TRUE(getValueResult.ok())
|
ASSERT_TRUE(getValueResult.ok())
|
||||||
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
|
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
|
||||||
propId, getValueResult.error().message().c_str());
|
propId, getValueResult.error().message().c_str());
|
||||||
@@ -269,17 +321,48 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
|
|||||||
"Expect exactly 1 int value for boolean property: %" PRId32 ", got %zu", propId,
|
"Expect exactly 1 int value for boolean property: %" PRId32 ", got %zu", propId,
|
||||||
intValueSize);
|
intValueSize);
|
||||||
|
|
||||||
int setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
|
int32_t setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
|
||||||
auto propToSet = mVhalClient->createHalPropValue(propId);
|
auto propToSet = mVhalClient->createHalPropValue(propId);
|
||||||
propToSet->setInt32Values({setValue});
|
propToSet->setInt32Values({setValue});
|
||||||
auto setValueResult = mVhalClient->setValueSync(*propToSet);
|
auto setValueResult = mVhalClient->setValueSync(*propToSet);
|
||||||
|
|
||||||
|
if (!setValueResult.ok() &&
|
||||||
|
setValueResult.error().code() == ErrorCode::NOT_AVAILABLE_FROM_VHAL) {
|
||||||
|
ALOGW("setProperty for %" PRId32
|
||||||
|
" returns NOT_AVAILABLE, "
|
||||||
|
"skip verifying getProperty returns the same value",
|
||||||
|
propId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT_TRUE(setValueResult.ok())
|
ASSERT_TRUE(setValueResult.ok())
|
||||||
<< StringPrintf("Failed to set value for property: %" PRId32 ", error: %s",
|
<< StringPrintf("Failed to set value for property: %" PRId32 ", error: %s",
|
||||||
propId, setValueResult.error().message().c_str());
|
propId, setValueResult.error().message().c_str());
|
||||||
|
// Retry getting the value until we pass the timeout. getValue might not return
|
||||||
|
// the expected value immediately since setValue is async.
|
||||||
|
auto timeoutMillis = uptimeMillis() + kRetryGetPropAfterSetPropTimeoutMillis;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
getValueResult = mVhalClient->getValueSync(*propToGet);
|
||||||
|
if (isResultOkayWithValue(getValueResult, setValue)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (uptimeMillis() >= timeoutMillis) {
|
||||||
|
// Reach timeout, the following assert should fail.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Sleep for 100ms between each getValueSync retry.
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUnavailable(getValueResult)) {
|
||||||
|
ALOGW("getProperty for %" PRId32
|
||||||
|
" returns NOT_AVAILABLE, "
|
||||||
|
"skip verifying the return value",
|
||||||
|
propId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check set success
|
|
||||||
getValueResult = mVhalClient->getValueSync(*propToGet);
|
|
||||||
ASSERT_TRUE(getValueResult.ok())
|
ASSERT_TRUE(getValueResult.ok())
|
||||||
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
|
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
|
||||||
propId, getValueResult.error().message().c_str());
|
propId, getValueResult.error().message().c_str());
|
||||||
|
|||||||
Reference in New Issue
Block a user