Loading automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp +100 −6 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <hidl/ServiceManagement.h> #include <inttypes.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <chrono> #include <mutex> Loading Loading @@ -67,6 +68,7 @@ class VtsVehicleCallback final : public ISubscriptionCallback { private: std::mutex mLock; std::unordered_map<int32_t, size_t> mEventsCount GUARDED_BY(mLock); std::unordered_map<int32_t, std::vector<int64_t>> mEventTimestamps GUARDED_BY(mLock); std::condition_variable mEventCond; public: Loading @@ -74,7 +76,9 @@ class VtsVehicleCallback final : public ISubscriptionCallback { { std::lock_guard<std::mutex> 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(); Loading @@ -94,6 +98,13 @@ class VtsVehicleCallback final : public ISubscriptionCallback { }); } std::vector<int64_t> getEventTimestamps(int32_t propId) { { std::lock_guard<std::mutex> lockGuard(mLock); return mEventTimestamps[propId]; } } void reset() { std::lock_guard<std::mutex> lockGuard(mLock); mEventsCount.clear(); Loading Loading @@ -285,19 +296,59 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, subscribeAndUnsubscribe) { int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED); std::vector<SubscribeOptions> 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<int64_t> 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 Loading Loading @@ -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<ServiceDescriptor> getDescriptors() { std::vector<ServiceDescriptor> descriptors; for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) { Loading Loading
automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp +100 −6 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <hidl/ServiceManagement.h> #include <inttypes.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <chrono> #include <mutex> Loading Loading @@ -67,6 +68,7 @@ class VtsVehicleCallback final : public ISubscriptionCallback { private: std::mutex mLock; std::unordered_map<int32_t, size_t> mEventsCount GUARDED_BY(mLock); std::unordered_map<int32_t, std::vector<int64_t>> mEventTimestamps GUARDED_BY(mLock); std::condition_variable mEventCond; public: Loading @@ -74,7 +76,9 @@ class VtsVehicleCallback final : public ISubscriptionCallback { { std::lock_guard<std::mutex> 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(); Loading @@ -94,6 +98,13 @@ class VtsVehicleCallback final : public ISubscriptionCallback { }); } std::vector<int64_t> getEventTimestamps(int32_t propId) { { std::lock_guard<std::mutex> lockGuard(mLock); return mEventTimestamps[propId]; } } void reset() { std::lock_guard<std::mutex> lockGuard(mLock); mEventsCount.clear(); Loading Loading @@ -285,19 +296,59 @@ TEST_P(VtsHalAutomotiveVehicleTargetTest, subscribeAndUnsubscribe) { int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED); std::vector<SubscribeOptions> 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<int64_t> 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 Loading Loading @@ -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<ServiceDescriptor> getDescriptors() { std::vector<ServiceDescriptor> descriptors; for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) { Loading