Loading automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp +7 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,12 @@ cc_library { "VehicleHalDefaultConfig", ], export_header_lib_headers: ["IVehicleHardware"], static_libs: ["VehicleHalUtils"], static_libs: [ "VehicleHalUtils", "FakeVehicleHalValueGenerators", ], shared_libs: [ "libjsoncpp", ], export_static_lib_headers: ["VehicleHalUtils"], } automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h +14 −4 Original line number Diff line number Diff line Loading @@ -82,10 +82,8 @@ class FakeVehicleHardware final : public IVehicleHardware { void registerOnPropertySetErrorEvent(OnPropertySetErrorCallback&& callback) override; private: void storePropInitialValue(const defaultconfig::ConfigDeclaration& config); void init(std::shared_ptr<VehiclePropValuePool> valuePool); void onValueChangeCallback( const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); // Expose private methods to unit test. friend class FakeVehicleHardwareTestHelper; std::unique_ptr<VehiclePropertyStore> mServerSidePropStore; // mValuePool is also used in mServerSidePropStore. Loading @@ -93,6 +91,18 @@ class FakeVehicleHardware final : public IVehicleHardware { std::mutex mCallbackLock; OnPropertyChangeCallback mOnPropertyChangeCallback GUARDED_BY(mCallbackLock); OnPropertySetErrorCallback mOnPropertySetErrorCallback GUARDED_BY(mCallbackLock); void init(std::shared_ptr<VehiclePropValuePool> valuePool); // Stores the initial value to property store. void storePropInitialValue(const defaultconfig::ConfigDeclaration& config); // The callback that would be called when a vehicle property value change happens. void onValueChangeCallback( const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); // If property "persist.vendor.vhal_init_value_override" is set to true, override the properties // using config files in 'overrideDir'. void maybeOverrideProperties(const char* overrideDir); // Override the properties using config files in 'overrideDir'. void overrideProperties(const char* overrideDir); }; } // namespace fake Loading automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,17 @@ #include "FakeVehicleHardware.h" #include <DefaultConfig.h> #include <JsonFakeValueGenerator.h> #include <VehicleHalTypes.h> #include <VehicleUtils.h> #include <android-base/properties.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <dirent.h> #include <sys/types.h> #include <fstream> #include <regex> #include <vector> namespace android { Loading @@ -30,6 +36,8 @@ namespace automotive { namespace vehicle { namespace fake { namespace { using ::aidl::android::hardware::automotive::vehicle::GetValueRequest; using ::aidl::android::hardware::automotive::vehicle::GetValueResult; using ::aidl::android::hardware::automotive::vehicle::RawPropValues; Loading @@ -40,6 +48,11 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/"; const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override"; } // namespace void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) { const VehiclePropConfig& vehiclePropConfig = config.config; int propId = vehiclePropConfig.prop; Loading Loading @@ -99,6 +112,8 @@ void FakeVehicleHardware::init(std::shared_ptr<VehiclePropValuePool> valuePool) storePropInitialValue(it); } maybeOverrideProperties(VENDOR_OVERRIDE_DIR); mServerSidePropStore->setOnValueChangeCallback( [this](const VehiclePropValue& value) { return onValueChangeCallback(value); }); } Loading Loading @@ -201,6 +216,39 @@ void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) { } } void FakeVehicleHardware::maybeOverrideProperties(const char* overrideDir) { if (android::base::GetBoolProperty(OVERRIDE_PROPERTY, false)) { overrideProperties(overrideDir); } } void FakeVehicleHardware::overrideProperties(const char* overrideDir) { ALOGI("loading vendor override properties from %s", overrideDir); if (auto dir = opendir(overrideDir); dir != NULL) { std::regex regJson(".*[.]json", std::regex::icase); while (auto f = readdir(dir)) { if (!std::regex_match(f->d_name, regJson)) { continue; } std::string file = overrideDir + std::string(f->d_name); JsonFakeValueGenerator tmpGenerator(file); std::vector<VehiclePropValue> propValues = tmpGenerator.getAllEvents(); for (const VehiclePropValue& prop : propValues) { auto propToStore = mValuePool->obtain(prop); propToStore->timestamp = elapsedRealtimeNano(); if (auto result = mServerSidePropStore->writeValue(std::move(propToStore), /*updateStatus=*/true); !result.ok()) { ALOGW("failed to write vendor override properties: %d, error: %s", prop.prop, result.error().message().c_str()); } } } closedir(dir); } } } // namespace fake } // namespace vehicle } // namespace automotive Loading automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp +12 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,21 @@ cc_test { static_libs: [ "VehicleHalUtils", "FakeVehicleHardware", "FakeVehicleHalValueGenerators", "libgtest", "libgmock", ], shared_libs: [ "libjsoncpp", ], data: [ ":FakeVehicleHardwareTestOverrideJson", ], defaults: ["VehicleHalDefaults"], test_suites: ["device-tests"], } filegroup { name: "FakeVehicleHardwareTestOverrideJson", srcs: ["override/*"], } automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +156 −1 Original line number Diff line number Diff line Loading @@ -16,16 +16,21 @@ #include <DefaultConfig.h> #include <FakeVehicleHardware.h> #include <android-base/expected.h> #include <android-base/file.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <inttypes.h> namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace fake { namespace { using ::aidl::android::hardware::automotive::vehicle::GetValueRequest; Loading @@ -38,6 +43,8 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; using ::android::base::expected; using ::android::base::unexpected; using ::testing::ContainerEq; using ::testing::Eq; using ::testing::WhenSortedBy; Loading @@ -46,6 +53,17 @@ constexpr int INVALID_PROP_ID = 0; } // namespace // A helper class to access private methods for FakeVehicleHardware. class FakeVehicleHardwareTestHelper { public: FakeVehicleHardwareTestHelper(FakeVehicleHardware* hardware) { mHardware = hardware; } void overrideProperties(const char* overrideDir) { mHardware->overrideProperties(overrideDir); } private: FakeVehicleHardware* mHardware; }; class FakeVehicleHardwareTest : public ::testing::Test { protected: void SetUp() override {} Loading @@ -64,6 +82,63 @@ class FakeVehicleHardwareTest : public ::testing::Test { requests); } StatusCode setValue(const VehiclePropValue& value) { std::vector<SetValueRequest> requests = { SetValueRequest{ .requestId = 0, .value = value, }, }; if (StatusCode status = setValues(requests); status != StatusCode::OK) { return status; } const SetValueResult& result = getSetValueResults().back(); if (result.requestId != 0) { ALOGE("request ID mismatch, got %" PRId64 ", expect 0", result.requestId); return StatusCode::INTERNAL_ERROR; } return result.status; } expected<VehiclePropValue, StatusCode> getValue(const VehiclePropValue& value) { std::vector<GetValueRequest> requests = { GetValueRequest{ .requestId = 0, .prop = value, }, }; if (StatusCode status = getValues(requests); status != StatusCode::OK) { return unexpected(status); } const GetValueResult& result = getGetValueResults().back(); if (result.requestId != 0) { ALOGE("request ID mismatch, got %" PRId64 ", expect 0", result.requestId); return unexpected(StatusCode::INTERNAL_ERROR); } if (result.status != StatusCode::OK) { return unexpected(result.status); } if (!result.prop.has_value()) { ALOGE("%s", "result property is empty"); return unexpected(StatusCode::INTERNAL_ERROR); } return result.prop.value(); } template <class T> int getStatus(expected<T, StatusCode> result) { return toInt(result.error()); } void onSetValues(const std::vector<SetValueResult> results) { for (auto& result : results) { mSetValueResults.push_back(result); Loading Loading @@ -424,6 +499,86 @@ TEST_F(FakeVehicleHardwareTest, testSetStatusMustIgnore) { ASSERT_EQ(getGetValueResults()[1].prop->status, VehiclePropertyStatus::AVAILABLE); } TEST_F(FakeVehicleHardwareTest, testVendorOverrideProperties) { std::string overrideDir = android::base::GetExecutableDirectory() + "/override/"; // Set vendor override directory. FakeVehicleHardwareTestHelper helper(getHardware()); helper.overrideProperties(overrideDir.c_str()); // This is the same as the prop in 'gear_selection.json'. int gearProp = toInt(VehicleProperty::GEAR_SELECTION); auto result = getValue(VehiclePropValue{ .prop = gearProp, }); ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.int32Values.size()); ASSERT_EQ(8, result.value().value.int32Values[0]); // If we set the value, it should update despite the override. ASSERT_EQ(setValue(VehiclePropValue{ .prop = gearProp, .value = { .int32Values = {5}, }, .timestamp = elapsedRealtimeNano(), }), StatusCode::OK) << "expect to set the overridden property ok"; result = getValue(VehiclePropValue{ .prop = gearProp, }); ASSERT_TRUE(result.ok()) << "expect to get the overridden property after setting value ok"; ASSERT_EQ(static_cast<size_t>(1), result.value().value.int32Values.size()); ASSERT_EQ(5, result.value().value.int32Values[0]); } TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesMultipleAreas) { std::string overrideDir = android::base::GetExecutableDirectory() + "/override/"; // Set vendor override directory. FakeVehicleHardwareTestHelper helper(getHardware()); helper.overrideProperties(overrideDir.c_str()); // This is the same as the prop in 'hvac_temperature_set.json'. int hvacProp = toInt(VehicleProperty::HVAC_TEMPERATURE_SET); auto result = getValue(VehiclePropValue{ .prop = hvacProp, .areaId = HVAC_LEFT, }); ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size()); ASSERT_EQ(30.0f, result.value().value.floatValues[0]); // HVAC_RIGHT should not be affected and return the default value. result = getValue(VehiclePropValue{ .prop = hvacProp, .areaId = HVAC_RIGHT, }); ASSERT_TRUE(result.ok()) << "expect to get the default property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size()); ASSERT_EQ(20.0f, result.value().value.floatValues[0]); } TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesDirDoesNotExist) { // Set vendor override directory to a non-existing dir FakeVehicleHardwareTestHelper helper(getHardware()); helper.overrideProperties("123"); auto result = getValue(VehiclePropValue{ .prop = toInt(VehicleProperty::GEAR_SELECTION), }); ASSERT_TRUE(result.ok()) << "expect to get the default property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.int32Values.size()); ASSERT_EQ(4, result.value().value.int32Values[0]); } } // namespace fake } // namespace vehicle } // namespace automotive Loading Loading
automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp +7 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,12 @@ cc_library { "VehicleHalDefaultConfig", ], export_header_lib_headers: ["IVehicleHardware"], static_libs: ["VehicleHalUtils"], static_libs: [ "VehicleHalUtils", "FakeVehicleHalValueGenerators", ], shared_libs: [ "libjsoncpp", ], export_static_lib_headers: ["VehicleHalUtils"], }
automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h +14 −4 Original line number Diff line number Diff line Loading @@ -82,10 +82,8 @@ class FakeVehicleHardware final : public IVehicleHardware { void registerOnPropertySetErrorEvent(OnPropertySetErrorCallback&& callback) override; private: void storePropInitialValue(const defaultconfig::ConfigDeclaration& config); void init(std::shared_ptr<VehiclePropValuePool> valuePool); void onValueChangeCallback( const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); // Expose private methods to unit test. friend class FakeVehicleHardwareTestHelper; std::unique_ptr<VehiclePropertyStore> mServerSidePropStore; // mValuePool is also used in mServerSidePropStore. Loading @@ -93,6 +91,18 @@ class FakeVehicleHardware final : public IVehicleHardware { std::mutex mCallbackLock; OnPropertyChangeCallback mOnPropertyChangeCallback GUARDED_BY(mCallbackLock); OnPropertySetErrorCallback mOnPropertySetErrorCallback GUARDED_BY(mCallbackLock); void init(std::shared_ptr<VehiclePropValuePool> valuePool); // Stores the initial value to property store. void storePropInitialValue(const defaultconfig::ConfigDeclaration& config); // The callback that would be called when a vehicle property value change happens. void onValueChangeCallback( const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); // If property "persist.vendor.vhal_init_value_override" is set to true, override the properties // using config files in 'overrideDir'. void maybeOverrideProperties(const char* overrideDir); // Override the properties using config files in 'overrideDir'. void overrideProperties(const char* overrideDir); }; } // namespace fake Loading
automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,17 @@ #include "FakeVehicleHardware.h" #include <DefaultConfig.h> #include <JsonFakeValueGenerator.h> #include <VehicleHalTypes.h> #include <VehicleUtils.h> #include <android-base/properties.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <dirent.h> #include <sys/types.h> #include <fstream> #include <regex> #include <vector> namespace android { Loading @@ -30,6 +36,8 @@ namespace automotive { namespace vehicle { namespace fake { namespace { using ::aidl::android::hardware::automotive::vehicle::GetValueRequest; using ::aidl::android::hardware::automotive::vehicle::GetValueResult; using ::aidl::android::hardware::automotive::vehicle::RawPropValues; Loading @@ -40,6 +48,11 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/"; const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override"; } // namespace void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) { const VehiclePropConfig& vehiclePropConfig = config.config; int propId = vehiclePropConfig.prop; Loading Loading @@ -99,6 +112,8 @@ void FakeVehicleHardware::init(std::shared_ptr<VehiclePropValuePool> valuePool) storePropInitialValue(it); } maybeOverrideProperties(VENDOR_OVERRIDE_DIR); mServerSidePropStore->setOnValueChangeCallback( [this](const VehiclePropValue& value) { return onValueChangeCallback(value); }); } Loading Loading @@ -201,6 +216,39 @@ void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) { } } void FakeVehicleHardware::maybeOverrideProperties(const char* overrideDir) { if (android::base::GetBoolProperty(OVERRIDE_PROPERTY, false)) { overrideProperties(overrideDir); } } void FakeVehicleHardware::overrideProperties(const char* overrideDir) { ALOGI("loading vendor override properties from %s", overrideDir); if (auto dir = opendir(overrideDir); dir != NULL) { std::regex regJson(".*[.]json", std::regex::icase); while (auto f = readdir(dir)) { if (!std::regex_match(f->d_name, regJson)) { continue; } std::string file = overrideDir + std::string(f->d_name); JsonFakeValueGenerator tmpGenerator(file); std::vector<VehiclePropValue> propValues = tmpGenerator.getAllEvents(); for (const VehiclePropValue& prop : propValues) { auto propToStore = mValuePool->obtain(prop); propToStore->timestamp = elapsedRealtimeNano(); if (auto result = mServerSidePropStore->writeValue(std::move(propToStore), /*updateStatus=*/true); !result.ok()) { ALOGW("failed to write vendor override properties: %d, error: %s", prop.prop, result.error().message().c_str()); } } } closedir(dir); } } } // namespace fake } // namespace vehicle } // namespace automotive Loading
automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp +12 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,21 @@ cc_test { static_libs: [ "VehicleHalUtils", "FakeVehicleHardware", "FakeVehicleHalValueGenerators", "libgtest", "libgmock", ], shared_libs: [ "libjsoncpp", ], data: [ ":FakeVehicleHardwareTestOverrideJson", ], defaults: ["VehicleHalDefaults"], test_suites: ["device-tests"], } filegroup { name: "FakeVehicleHardwareTestOverrideJson", srcs: ["override/*"], }
automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +156 −1 Original line number Diff line number Diff line Loading @@ -16,16 +16,21 @@ #include <DefaultConfig.h> #include <FakeVehicleHardware.h> #include <android-base/expected.h> #include <android-base/file.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <inttypes.h> namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace fake { namespace { using ::aidl::android::hardware::automotive::vehicle::GetValueRequest; Loading @@ -38,6 +43,8 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; using ::android::base::expected; using ::android::base::unexpected; using ::testing::ContainerEq; using ::testing::Eq; using ::testing::WhenSortedBy; Loading @@ -46,6 +53,17 @@ constexpr int INVALID_PROP_ID = 0; } // namespace // A helper class to access private methods for FakeVehicleHardware. class FakeVehicleHardwareTestHelper { public: FakeVehicleHardwareTestHelper(FakeVehicleHardware* hardware) { mHardware = hardware; } void overrideProperties(const char* overrideDir) { mHardware->overrideProperties(overrideDir); } private: FakeVehicleHardware* mHardware; }; class FakeVehicleHardwareTest : public ::testing::Test { protected: void SetUp() override {} Loading @@ -64,6 +82,63 @@ class FakeVehicleHardwareTest : public ::testing::Test { requests); } StatusCode setValue(const VehiclePropValue& value) { std::vector<SetValueRequest> requests = { SetValueRequest{ .requestId = 0, .value = value, }, }; if (StatusCode status = setValues(requests); status != StatusCode::OK) { return status; } const SetValueResult& result = getSetValueResults().back(); if (result.requestId != 0) { ALOGE("request ID mismatch, got %" PRId64 ", expect 0", result.requestId); return StatusCode::INTERNAL_ERROR; } return result.status; } expected<VehiclePropValue, StatusCode> getValue(const VehiclePropValue& value) { std::vector<GetValueRequest> requests = { GetValueRequest{ .requestId = 0, .prop = value, }, }; if (StatusCode status = getValues(requests); status != StatusCode::OK) { return unexpected(status); } const GetValueResult& result = getGetValueResults().back(); if (result.requestId != 0) { ALOGE("request ID mismatch, got %" PRId64 ", expect 0", result.requestId); return unexpected(StatusCode::INTERNAL_ERROR); } if (result.status != StatusCode::OK) { return unexpected(result.status); } if (!result.prop.has_value()) { ALOGE("%s", "result property is empty"); return unexpected(StatusCode::INTERNAL_ERROR); } return result.prop.value(); } template <class T> int getStatus(expected<T, StatusCode> result) { return toInt(result.error()); } void onSetValues(const std::vector<SetValueResult> results) { for (auto& result : results) { mSetValueResults.push_back(result); Loading Loading @@ -424,6 +499,86 @@ TEST_F(FakeVehicleHardwareTest, testSetStatusMustIgnore) { ASSERT_EQ(getGetValueResults()[1].prop->status, VehiclePropertyStatus::AVAILABLE); } TEST_F(FakeVehicleHardwareTest, testVendorOverrideProperties) { std::string overrideDir = android::base::GetExecutableDirectory() + "/override/"; // Set vendor override directory. FakeVehicleHardwareTestHelper helper(getHardware()); helper.overrideProperties(overrideDir.c_str()); // This is the same as the prop in 'gear_selection.json'. int gearProp = toInt(VehicleProperty::GEAR_SELECTION); auto result = getValue(VehiclePropValue{ .prop = gearProp, }); ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.int32Values.size()); ASSERT_EQ(8, result.value().value.int32Values[0]); // If we set the value, it should update despite the override. ASSERT_EQ(setValue(VehiclePropValue{ .prop = gearProp, .value = { .int32Values = {5}, }, .timestamp = elapsedRealtimeNano(), }), StatusCode::OK) << "expect to set the overridden property ok"; result = getValue(VehiclePropValue{ .prop = gearProp, }); ASSERT_TRUE(result.ok()) << "expect to get the overridden property after setting value ok"; ASSERT_EQ(static_cast<size_t>(1), result.value().value.int32Values.size()); ASSERT_EQ(5, result.value().value.int32Values[0]); } TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesMultipleAreas) { std::string overrideDir = android::base::GetExecutableDirectory() + "/override/"; // Set vendor override directory. FakeVehicleHardwareTestHelper helper(getHardware()); helper.overrideProperties(overrideDir.c_str()); // This is the same as the prop in 'hvac_temperature_set.json'. int hvacProp = toInt(VehicleProperty::HVAC_TEMPERATURE_SET); auto result = getValue(VehiclePropValue{ .prop = hvacProp, .areaId = HVAC_LEFT, }); ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size()); ASSERT_EQ(30.0f, result.value().value.floatValues[0]); // HVAC_RIGHT should not be affected and return the default value. result = getValue(VehiclePropValue{ .prop = hvacProp, .areaId = HVAC_RIGHT, }); ASSERT_TRUE(result.ok()) << "expect to get the default property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size()); ASSERT_EQ(20.0f, result.value().value.floatValues[0]); } TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesDirDoesNotExist) { // Set vendor override directory to a non-existing dir FakeVehicleHardwareTestHelper helper(getHardware()); helper.overrideProperties("123"); auto result = getValue(VehiclePropValue{ .prop = toInt(VehicleProperty::GEAR_SELECTION), }); ASSERT_TRUE(result.ok()) << "expect to get the default property ok: " << getStatus(result); ASSERT_EQ(static_cast<size_t>(1), result.value().value.int32Values.size()); ASSERT_EQ(4, result.value().value.int32Values[0]); } } // namespace fake } // namespace vehicle } // namespace automotive Loading