Add retry in setProp test. am: 62fe882688 am: 4381d2445c
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2927410
Change-Id: I1bd90fabca970d7d2af989f779c38adb85a45338
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index f8ef8cb..c45c000 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -35,6 +35,7 @@
#include <chrono>
#include <mutex>
+#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -45,8 +46,10 @@
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::android::getAidlHalInstanceNames;
+using ::android::uptimeMillis;
using ::android::base::ScopedLockAssertion;
using ::android::base::StringPrintf;
using ::android::frameworks::automotive::vhal::HalPropError;
@@ -57,8 +60,11 @@
using ::android::hardware::getAllHalInstanceNames;
using ::android::hardware::Sanitize;
using ::android::hardware::automotive::vehicle::toInt;
+using ::android::hardware::automotive::vehicle::VhalResult;
constexpr int32_t kInvalidProp = 0x31600207;
+// The timeout for retrying getting prop value after setting prop value.
+constexpr int64_t kRetryGetPropAfterSetPropTimeoutMillis = 10'000;
struct ServiceDescriptor {
std::string name;
@@ -115,6 +121,10 @@
class VtsHalAutomotiveVehicleTargetTest : public testing::TestWithParam<ServiceDescriptor> {
protected:
bool checkIsSupported(int32_t propertyId);
+ VehiclePropertyStatus getStatus(const IHalPropValue& halPropValue);
+ bool isUnavailable(const VhalResult<std::unique_ptr<IHalPropValue>>& result);
+ bool isResultOkayWithValue(const VhalResult<std::unique_ptr<IHalPropValue>>& result,
+ int32_t value);
public:
virtual void SetUp() override {
@@ -225,6 +235,41 @@
"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 VhalResult<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 VhalResult<std::unique_ptr<IHalPropValue>>& result) {
+ if (!result.ok()) {
+ return result.error().code() == StatusCode::NOT_AVAILABLE;
+ }
+ if (result.value() != nullptr &&
+ getStatus(*(result.value())) == VehiclePropertyStatus::UNAVAILABLE) {
+ return true;
+ }
+
+ return false;
+}
+
// Test set() on read_write properties.
TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
ALOGD("VtsHalAutomotiveVehicleTargetTest::setProp");
@@ -252,6 +297,14 @@
auto propToGet = mVhalClient->createHalPropValue(propId);
auto getValueResult = mVhalClient->getValueSync(*propToGet);
+ if (isUnavailable(getValueResult)) {
+ ALOGW("getProperty for %" PRId32
+ " returns NOT_AVAILABLE, "
+ "skip testing setProp",
+ propId);
+ return;
+ }
+
ASSERT_TRUE(getValueResult.ok())
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
propId, getValueResult.error().message().c_str());
@@ -264,17 +317,48 @@
"Expect exactly 1 int value for boolean property: %" PRId32 ", got %zu", propId,
intValueSize);
- int setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
+ int32_t setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
auto propToSet = mVhalClient->createHalPropValue(propId);
propToSet->setInt32Values({setValue});
auto setValueResult = mVhalClient->setValueSync(*propToSet);
+ if (!setValueResult.ok() &&
+ setValueResult.error().code() == StatusCode::NOT_AVAILABLE) {
+ ALOGW("setProperty for %" PRId32
+ " returns NOT_AVAILABLE, "
+ "skip verifying getProperty returns the same value",
+ propId);
+ return;
+ }
+
ASSERT_TRUE(setValueResult.ok())
<< StringPrintf("Failed to set value for property: %" PRId32 ", error: %s",
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;
- // check set success
- getValueResult = mVhalClient->getValueSync(*propToGet);
+ 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;
+ }
+
ASSERT_TRUE(getValueResult.ok())
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
propId, getValueResult.error().message().c_str());