Add config check for require_min_max_value.
Add property config check for property IDs who require min and
max supported value to be set.
Flag: EXEMPT the test will skip the check if
getHasSupportedValueInfo returns nullopt.
Test: atest VtsHalAutomotiveVehicle_TargetTest
Bug: 381123190
Change-Id: Iebbc494dc89dab9116a0137faa4f0a4f52544b5d
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 4c97544..77671ed 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "VtsHalAutomotiveVehicle"
#include <AccessForVehicleProperty.h>
+#include <AnnotationsForVehicleProperty.h>
#include <ChangeModeForVehicleProperty.h>
#include <IVhalClient.h>
#include <VehicleHalTypes.h>
@@ -24,6 +25,7 @@
#include <VersionForVehicleProperty.h>
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
+#include <aidl/android/hardware/automotive/vehicle/HasSupportedValueInfo.h>
#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
@@ -45,7 +47,9 @@
#include <vector>
using ::aidl::android::hardware::automotive::vehicle::AllowedAccessForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::AnnotationsForVehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::HasSupportedValueInfo;
using ::aidl::android::hardware::automotive::vehicle::IVehicle;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
@@ -81,6 +85,7 @@
constexpr int32_t kInvalidProp = 0x31600207;
// The timeout for retrying getting prop value after setting prop value.
constexpr int64_t kRetryGetPropAfterSetPropTimeoutMillis = 10'000;
+static constexpr char ANNOTATION_REQUIRE_MIN_MAX_VALUE[] = "require_min_max_supported_value";
struct ServiceDescriptor {
std::string name;
@@ -275,65 +280,6 @@
maximalAreaAccessSubset, propertyLevelAccess);
}
-// Helper function to compare actual vs expected property config
-void VtsHalAutomotiveTest::verifyProperty(VehicleProperty propId,
- std::vector<VehiclePropertyAccess> accessModes,
- VehiclePropertyChangeMode changeMode) {
- int expectedPropId = toInt(propId);
- int expectedChangeMode = toInt(changeMode);
-
- auto result = mVhalClient->getAllPropConfigs();
- ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
- << result.error().message();
-
- // Check if property is implemented by getting all configs and looking to see if the expected
- // property id is in that list.
- bool isExpectedPropIdImplemented = false;
- for (const auto& cfgPtr : result.value()) {
- const IHalPropConfig& cfg = *cfgPtr;
- if (expectedPropId == cfg.getPropId()) {
- isExpectedPropIdImplemented = true;
- break;
- }
- }
-
- if (!isExpectedPropIdImplemented) {
- GTEST_SKIP() << StringPrintf("Property %" PRId32 " has not been implemented",
- expectedPropId);
- }
-
- result = mVhalClient->getPropConfigs({expectedPropId});
- ASSERT_TRUE(result.ok()) << "Failed to get required property config, error: "
- << result.error().message();
-
- ASSERT_EQ(result.value().size(), 1u)
- << StringPrintf("Expect to get exactly 1 config, got %zu", result.value().size());
-
- const auto& config = result.value().at(0);
- int actualPropId = config->getPropId();
- int actualChangeMode = config->getChangeMode();
-
- ASSERT_EQ(actualPropId, expectedPropId)
- << StringPrintf("Expect to get property ID: %i, got %i", expectedPropId, actualPropId);
-
- int globalAccess = config->getAccess();
- if (config->getAreaConfigSize() == 0) {
- verifyAccessMode(globalAccess, accessModes);
- } else {
- for (const auto& areaConfig : config->getAreaConfigs()) {
- int areaConfigAccess = areaConfig->getAccess();
- int actualAccess = (areaConfigAccess != toInt(VehiclePropertyAccess::NONE))
- ? areaConfigAccess
- : globalAccess;
- verifyAccessMode(actualAccess, accessModes);
- }
- }
-
- EXPECT_EQ(actualChangeMode, expectedChangeMode)
- << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
- expectedChangeMode, actualChangeMode);
-}
-
class VtsHalAutomotiveVehicleTargetTest : public VtsHalAutomotiveTest,
public testing::WithParamInterface<ServiceDescriptor> {
virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(connectToVhal(GetParam())); }
@@ -852,9 +798,108 @@
}
}
+/**
+ * Verifies that each property's property config is consistent with the requirement
+ * documented in VehicleProperty.aidl.
+ */
TEST_P(VtsHalAutomotivePropertyConfigTest, verifyPropertyConfig) {
const PropertyConfigTestParam& param = std::get<0>(GetParam());
- verifyProperty(param.propId, param.accessModes, param.changeMode);
+ int expectedPropId = toInt(param.propId);
+ int expectedChangeMode = toInt(param.changeMode);
+
+ auto result = mVhalClient->getAllPropConfigs();
+ ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
+ << result.error().message();
+
+ // Check if property is implemented by getting all configs and looking to see if the expected
+ // property id is in that list.
+ bool isExpectedPropIdImplemented = false;
+ for (const auto& cfgPtr : result.value()) {
+ const IHalPropConfig& cfg = *cfgPtr;
+ if (expectedPropId == cfg.getPropId()) {
+ isExpectedPropIdImplemented = true;
+ break;
+ }
+ }
+
+ if (!isExpectedPropIdImplemented) {
+ GTEST_SKIP() << StringPrintf("Property %" PRId32 " has not been implemented",
+ expectedPropId);
+ }
+
+ result = mVhalClient->getPropConfigs({expectedPropId});
+ ASSERT_TRUE(result.ok()) << "Failed to get required property config, error: "
+ << result.error().message();
+
+ ASSERT_EQ(result.value().size(), 1u)
+ << StringPrintf("Expect to get exactly 1 config, got %zu", result.value().size());
+
+ const auto& config = result.value().at(0);
+ int actualPropId = config->getPropId();
+ int actualChangeMode = config->getChangeMode();
+
+ ASSERT_EQ(actualPropId, expectedPropId)
+ << StringPrintf("Expect to get property ID: %i, got %i", expectedPropId, actualPropId);
+
+ int globalAccess = config->getAccess();
+ if (config->getAreaConfigSize() == 0) {
+ verifyAccessMode(globalAccess, param.accessModes);
+ } else {
+ for (const auto& areaConfig : config->getAreaConfigs()) {
+ int areaConfigAccess = areaConfig->getAccess();
+ int actualAccess = (areaConfigAccess != toInt(VehiclePropertyAccess::NONE))
+ ? areaConfigAccess
+ : globalAccess;
+ verifyAccessMode(actualAccess, param.accessModes);
+ }
+ }
+
+ EXPECT_EQ(actualChangeMode, expectedChangeMode)
+ << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
+ expectedChangeMode, actualChangeMode);
+
+ std::unordered_set<std::string> annotations;
+ auto it = AnnotationsForVehicleProperty.find(param.propId);
+ if (it != AnnotationsForVehicleProperty.end()) {
+ annotations = it->second;
+ }
+
+ int propertyType = expectedPropId & toInt(VehiclePropertyType::MASK);
+ if (annotations.find(ANNOTATION_REQUIRE_MIN_MAX_VALUE) != annotations.end()) {
+ for (const auto& areaConfig : config->getAreaConfigs()) {
+ switch (propertyType) {
+ case toInt(VehiclePropertyType::INT32):
+ EXPECT_FALSE(areaConfig->getMinInt32Value() == 0 &&
+ areaConfig->getMaxInt32Value() == 0)
+ << "minInt32Value and maxInt32Value must not both be 0 because "
+ "min and max value is required for this property";
+ break;
+ case toInt(VehiclePropertyType::FLOAT):
+ EXPECT_FALSE(areaConfig->getMinFloatValue() == 0 &&
+ areaConfig->getMaxFloatValue() == 0)
+ << "minFloatValue and maxFloatValue must not both be 0 because "
+ "min and max value is required for this property";
+ break;
+ case toInt(VehiclePropertyType::INT64):
+ EXPECT_FALSE(areaConfig->getMinInt64Value() == 0 &&
+ areaConfig->getMaxInt64Value() == 0)
+ << "minInt64Value and maxInt64Value must not both be 0 because "
+ "min and max value is required for this property";
+ break;
+ }
+
+ std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
+ areaConfig->getHasSupportedValueInfo();
+ if (maybeHasSupportedValueInfo.has_value()) {
+ EXPECT_TRUE(maybeHasSupportedValueInfo->hasMinSupportedValue)
+ << "HasSupportedValueInfo.hasMinSupportedValue must be true because"
+ "min and max value is required for this property";
+ EXPECT_TRUE(maybeHasSupportedValueInfo->hasMaxSupportedValue)
+ << "HasSupportedValueInfo.hasMaxSupportedValue must be true because"
+ "min and max value is required for this property";
+ }
+ }
+ }
}
std::vector<ServiceDescriptor> getDescriptors() {