From 4569ef55427c97c96d6fb333e64feccd458d5063 Mon Sep 17 00:00:00 2001 From: Yu Shan Date: Fri, 18 Mar 2022 14:34:25 -0700 Subject: [PATCH] Add VTS test for timestamp for AIDL backend. The expected behavior for timestamp was not clearly defined in HIDL. In AIDL, we add clearer definition based on the existing HIDL ref impl's behavior. This CL add VTS test to enforce these behavior for AIDL backend. Test: atest VtsHalAutomotiveVehicle_TargetTest Bug: 225191802 Change-Id: Ic208d6ac20cb7b820249c9b545c7b3a83528a1dd --- .../VtsHalAutomotiveVehicle_TargetTest.cpp | 106 +++++++++++++++++- 1 file changed, 100 insertions(+), 6 deletions(-) diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp index c33f3e91d3..c431d85eef 100644 --- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp +++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,7 @@ class VtsVehicleCallback final : public ISubscriptionCallback { private: std::mutex mLock; std::unordered_map mEventsCount GUARDED_BY(mLock); + std::unordered_map> mEventTimestamps GUARDED_BY(mLock); std::condition_variable mEventCond; public: @@ -74,7 +76,9 @@ class VtsVehicleCallback final : public ISubscriptionCallback { { std::lock_guard lockGuard(mLock); for (auto& value : values) { - mEventsCount[value->getPropId()] += 1; + int32_t propId = value->getPropId(); + mEventsCount[propId] += 1; + mEventTimestamps[propId].push_back(value->getTimestamp()); } } mEventCond.notify_one(); @@ -94,6 +98,13 @@ class VtsVehicleCallback final : public ISubscriptionCallback { }); } + std::vector getEventTimestamps(int32_t propId) { + { + std::lock_guard lockGuard(mLock); + return mEventTimestamps[propId]; + } + } + void reset() { std::lock_guard lockGuard(mLock); mEventsCount.clear(); @@ -285,19 +296,59 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, subscribeAndUnsubscribe) { int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED); - std::vector options = { - SubscribeOptions{.propId = propId, .sampleRate = 10.0}}; + auto propConfigsResult = mVhalClient->getPropConfigs({propId}); + + ASSERT_TRUE(propConfigsResult.ok()) << "Failed to get property config for PERF_VEHICLE_SPEED: " + << "error: " << propConfigsResult.error().message(); + ASSERT_EQ(propConfigsResult.value().size(), 1u) + << "Expect to return 1 config for PERF_VEHICLE_SPEED"; + auto& propConfig = propConfigsResult.value()[0]; + float minSampleRate = propConfig->getMinSampleRate(); + float maxSampleRate = propConfig->getMaxSampleRate(); + + if (minSampleRate < 1) { + GTEST_SKIP() << "Sample rate for vehicle speed < 1 times/sec, skip test since it would " + "take too long"; + } auto client = mVhalClient->getSubscriptionClient(mCallback); ASSERT_NE(client, nullptr) << "Failed to get subscription client"; - auto result = client->subscribe(options); + auto result = client->subscribe({{.propId = propId, .sampleRate = minSampleRate}}); ASSERT_TRUE(result.ok()) << StringPrintf("Failed to subscribe to property: %" PRId32 ", error: %s", propId, result.error().message().c_str()); - ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, 10, std::chrono::seconds(10))) - << "Didn't get enough events for subscription"; + + if (mVhalClient->isAidlVhal()) { + // Skip checking timestamp for HIDL because the behavior for sample rate and timestamp is + // only specified clearly for AIDL. + + // Timeout is 2 seconds, which gives a 1 second buffer. + ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, std::floor(minSampleRate), + std::chrono::seconds(2))) + << "Didn't get enough events for subscribing to minSampleRate"; + } + + result = client->subscribe({{.propId = propId, .sampleRate = maxSampleRate}}); + + ASSERT_TRUE(result.ok()) << StringPrintf("Failed to subscribe to property: %" PRId32 + ", error: %s", + propId, result.error().message().c_str()); + + if (mVhalClient->isAidlVhal()) { + ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, std::floor(maxSampleRate), + std::chrono::seconds(2))) + << "Didn't get enough events for subscribing to maxSampleRate"; + + std::unordered_set timestamps; + // Event event should have a different timestamp. + for (const int64_t& eventTimestamp : mCallback->getEventTimestamps(propId)) { + ASSERT_TRUE(timestamps.find(eventTimestamp) == timestamps.end()) + << "two events for the same property must not have the same timestamp"; + timestamps.insert(eventTimestamp); + } + } result = client->unsubscribe({propId}); ASSERT_TRUE(result.ok()) << StringPrintf("Failed to unsubscribe to property: %" PRId32 @@ -325,6 +376,49 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, subscribeInvalidProp) { kInvalidProp); } +// Test the timestamp returned in GetValues results is the timestamp when the value is retrieved. +TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetValuesTimestampAIDL) { + if (!mVhalClient->isAidlVhal()) { + GTEST_SKIP() << "Skip checking timestamp for HIDL because the behavior is only specified " + "for AIDL"; + } + + int32_t propId = toInt(VehicleProperty::PARKING_BRAKE_ON); + auto prop = mVhalClient->createHalPropValue(propId); + + auto result = mVhalClient->getValueSync(*prop); + + ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32 + ", error: %s", + propId, result.error().message().c_str()); + ASSERT_NE(result.value(), nullptr) << "Result value must not be null"; + ASSERT_EQ(result.value()->getInt32Values().size(), 1u) << "Result must contain 1 int value"; + + bool parkBrakeOnValue1 = (result.value()->getInt32Values()[0] == 1); + int64_t timestampValue1 = result.value()->getTimestamp(); + + result = mVhalClient->getValueSync(*prop); + + ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32 + ", error: %s", + propId, result.error().message().c_str()); + ASSERT_NE(result.value(), nullptr) << "Result value must not be null"; + ASSERT_EQ(result.value()->getInt32Values().size(), 1u) << "Result must contain 1 int value"; + + bool parkBarkeOnValue2 = (result.value()->getInt32Values()[0] == 1); + int64_t timestampValue2 = result.value()->getTimestamp(); + + if (parkBarkeOnValue2 == parkBrakeOnValue1) { + ASSERT_EQ(timestampValue2, timestampValue1) + << "getValue result must contain a timestamp updated when the value was updated, if" + "the value does not change, expect the same timestamp"; + } else { + ASSERT_GT(timestampValue2, timestampValue1) + << "getValue result must contain a timestamp updated when the value was updated, if" + "the value changes, expect the newer value has a larger timestamp"; + } +} + std::vector getDescriptors() { std::vector descriptors; for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) {