Loading automotive/vehicle/TEST_MAPPING +3 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,9 @@ }, { "name": "VehicleHalVehicleUtilsTest" }, { "name": "FakeVehicleHardwareTest" } ] } automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +58 −6 Original line number Diff line number Diff line Loading @@ -106,15 +106,67 @@ std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() cons return mServerSidePropStore->getAllConfigs(); } StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&&, const std::vector<SetValueRequest>&) { // TODO(b/201830716): Implement this. StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&& callback, const std::vector<SetValueRequest>& requests) { std::vector<VehiclePropValue> updatedValues; std::vector<SetValueResult> results; for (auto& request : requests) { const VehiclePropValue* value = &request.value; ALOGD("setValues(%d)", value->prop); auto updatedValue = mValuePool->obtain(*value); int64_t timestamp = elapsedRealtimeNano(); updatedValue->timestamp = timestamp; auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue)); SetValueResult setValueResult; setValueResult.requestId = request.requestId; if (!writeResult.ok()) { ALOGE("failed to write value into property store, error: %s, code: %d", writeResult.error().message().c_str(), writeResult.error().code()); setValueResult.status = StatusCode::INVALID_ARG; } else { setValueResult.status = StatusCode::OK; } results.push_back(std::move(setValueResult)); } // In the real vhal, the values will be sent to Car ECU. We just pretend it is done here and // send back the updated property values to client. callback(std::move(results)); return StatusCode::OK; } StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback&&, const std::vector<GetValueRequest>&) const { // TODO(b/201830716): Implement this. StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback&& callback, const std::vector<GetValueRequest>& requests) const { std::vector<GetValueResult> results; for (auto& request : requests) { const VehiclePropValue* value = &request.prop; ALOGD("getValues(%d)", value->prop); auto readResult = mServerSidePropStore->readValue(*value); GetValueResult getValueResult; getValueResult.requestId = request.requestId; if (!readResult.ok()) { auto error = readResult.error(); if (error.code() == toInt(StatusCode::NOT_AVAILABLE)) { ALOGW("%s", "value has not been set yet"); getValueResult.status = StatusCode::NOT_AVAILABLE; } else { ALOGE("failed to get value, error: %s, code: %d", error.message().c_str(), error.code()); getValueResult.status = StatusCode::INVALID_ARG; } } else { getValueResult.status = StatusCode::OK; getValueResult.prop = *readResult.value(); } results.push_back(std::move(getValueResult)); } callback(std::move(results)); return StatusCode::OK; } Loading automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +264 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ using ::testing::ContainerEq; using ::testing::Eq; using ::testing::WhenSortedBy; constexpr int INVALID_PROP_ID = 0; } // namespace class FakeVehicleHardwareTest : public ::testing::Test { Loading Loading @@ -159,6 +161,268 @@ TEST_F(FakeVehicleHardwareTest, testGetAllPropertyConfigs) { ASSERT_EQ(configs.size(), defaultconfig::getDefaultConfigs().size()); } TEST_F(FakeVehicleHardwareTest, testGetDefaultValues) { std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; int64_t requestId = 1; for (auto& config : defaultconfig::getDefaultConfigs()) { int propId = config.config.prop; if (isGlobalProp(propId)) { if (config.initialValue == RawPropValues{}) { addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, VehiclePropValue{.prop = propId}, StatusCode::NOT_AVAILABLE); continue; } addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, VehiclePropValue{ .prop = propId, .value = config.initialValue, }, StatusCode::OK); continue; } for (auto areaConfig : config.config.areaConfigs) { StatusCode status = StatusCode::OK; VehiclePropValue propValue{ .prop = propId, .areaId = areaConfig.areaId, }; if (config.initialAreaValues.empty()) { if (config.initialValue == RawPropValues{}) { status = StatusCode::NOT_AVAILABLE; } else { propValue.value = config.initialValue; } } else if (auto valueForAreaIt = config.initialAreaValues.find(areaConfig.areaId); valueForAreaIt != config.initialAreaValues.end()) { propValue.value = valueForAreaIt->second; } else { status = StatusCode::NOT_AVAILABLE; } addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, propValue, status); } } // In our implementation, this would finish immediately. StatusCode status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueResult> getValueResultsWithNoTimestamp; for (auto& result : getGetValueResults()) { GetValueResult resultCopy = result; resultCopy.prop->timestamp = 0; getValueResultsWithNoTimestamp.push_back(std::move(resultCopy)); } ASSERT_THAT(getValueResultsWithNoTimestamp, ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testSetValues) { std::vector<SetValueRequest> requests; std::vector<SetValueResult> expectedResults; int64_t requestId = 1; for (auto& value : getTestPropValues()) { addSetValueRequest(requests, expectedResults, requestId++, value, StatusCode::OK); } StatusCode status = setValues(requests); ASSERT_EQ(status, StatusCode::OK); // Although callback might be called asynchronously, in our implementation, the callback would // be called before setValues returns. ASSERT_THAT(getSetValueResults(), ContainerEq(expectedResults)); } TEST_F(FakeVehicleHardwareTest, testSetValuesError) { std::vector<SetValueRequest> requests; std::vector<SetValueResult> expectedResults; int64_t requestId = 1; VehiclePropValue invalidProp = { .prop = INVALID_PROP_ID, }; addSetValueRequest(requests, expectedResults, requestId++, invalidProp, StatusCode::INVALID_ARG); for (auto& value : getTestPropValues()) { addSetValueRequest(requests, expectedResults, requestId++, value, StatusCode::OK); } StatusCode status = setValues(requests); ASSERT_EQ(status, StatusCode::OK); // Although callback might be called asynchronously, in our implementation, the callback would // be called before setValues returns. ASSERT_THAT(getSetValueResults(), ContainerEq(expectedResults)); } TEST_F(FakeVehicleHardwareTest, testRegisterOnPropertyChangeEvent) { getHardware()->registerOnPropertyChangeEvent(std::bind( &FakeVehicleHardwareTest_testRegisterOnPropertyChangeEvent_Test::onPropertyChangeEvent, this, std::placeholders::_1)); auto testValues = getTestPropValues(); std::vector<SetValueRequest> requests; std::vector<SetValueResult> expectedResults; int64_t requestId = 1; for (auto& value : testValues) { addSetValueRequest(requests, expectedResults, requestId++, value, StatusCode::OK); } int64_t timestamp = elapsedRealtimeNano(); StatusCode status = setValues(requests); ASSERT_EQ(status, StatusCode::OK); auto updatedValues = getChangedProperties(); std::vector<VehiclePropValue> updatedValuesWithNoTimestamp; for (auto& value : updatedValues) { ASSERT_GE(value.timestamp, timestamp); VehiclePropValue valueCopy = value; valueCopy.timestamp = 0; updatedValuesWithNoTimestamp.push_back(std::move(valueCopy)); } ASSERT_THAT(updatedValuesWithNoTimestamp, WhenSortedBy(mPropValueCmp, Eq(testValues))); } TEST_F(FakeVehicleHardwareTest, testReadValues) { std::vector<SetValueRequest> setValueRequests; std::vector<SetValueResult> expectedSetValueResults; int64_t requestId = 1; for (auto& value : getTestPropValues()) { addSetValueRequest(setValueRequests, expectedSetValueResults, requestId++, value, StatusCode::OK); } int64_t timestamp = elapsedRealtimeNano(); // In our implementation, this would finish immediately. StatusCode status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; for (auto& value : getTestPropValues()) { addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, value, StatusCode::OK); } // In our implementation, this would finish immediately. status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueResult> getValueResultsWithNoTimestamp; for (auto& result : getGetValueResults()) { ASSERT_GE(result.prop->timestamp, timestamp); GetValueResult resultCopy = result; resultCopy.prop->timestamp = 0; getValueResultsWithNoTimestamp.push_back(std::move(resultCopy)); } ASSERT_THAT(getValueResultsWithNoTimestamp, ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testReadValuesErrorInvalidProp) { std::vector<SetValueRequest> setValueRequests; std::vector<SetValueResult> expectedSetValueResults; int64_t requestId = 1; for (auto& value : getTestPropValues()) { addSetValueRequest(setValueRequests, expectedSetValueResults, requestId++, value, StatusCode::OK); } // In our implementation, this would finish immediately. StatusCode status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; VehiclePropValue invalidProp = { .prop = INVALID_PROP_ID, }; addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, invalidProp, StatusCode::INVALID_ARG); // In our implementation, this would finish immediately. status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_THAT(getGetValueResults(), ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testReadValuesErrorNotAvailable) { std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; // VEHICLE_MAP_SERVICE does not have initial value, 'get' must always return // StatusCode::NOT_AVAILABLE. addGetValueRequest(getValueRequests, expectedGetValueResults, 0, VehiclePropValue{ .prop = VEHICLE_MAP_SERVICE, }, StatusCode::NOT_AVAILABLE); // In our implementation, this would finish immediately. StatusCode status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_THAT(getGetValueResults(), ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testSetStatusMustIgnore) { VehiclePropValue testValue = getTestPropValues()[0]; testValue.status = VehiclePropertyStatus::UNAVAILABLE; std::vector<SetValueRequest> setValueRequests; std::vector<SetValueResult> expectedSetValueResults; int64_t requestId = 1; addSetValueRequest(setValueRequests, expectedSetValueResults, requestId++, testValue, StatusCode::OK); // In our implementation, this would finish immediately. StatusCode status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_THAT(getSetValueResults(), ContainerEq(expectedSetValueResults)); std::vector<GetValueRequest> getValueRequests; getValueRequests.push_back(GetValueRequest{ .requestId = requestId++, .prop = testValue, }); // In our implementation, this would finish immediately. status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_EQ(getGetValueResults().size(), static_cast<size_t>(1)); ASSERT_EQ(getGetValueResults()[0].status, StatusCode::OK); // The status should be by-default AVAILABLE for new status. ASSERT_EQ(getGetValueResults()[0].prop->status, VehiclePropertyStatus::AVAILABLE); // Try to set the property again. The status should not be overwritten. status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_EQ(getGetValueResults().size(), static_cast<size_t>(2)); ASSERT_EQ(getGetValueResults()[1].status, StatusCode::OK); ASSERT_EQ(getGetValueResults()[1].prop->status, VehiclePropertyStatus::AVAILABLE); } } // namespace vehicle } // namespace automotive } // namespace hardware Loading Loading
automotive/vehicle/TEST_MAPPING +3 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,9 @@ }, { "name": "VehicleHalVehicleUtilsTest" }, { "name": "FakeVehicleHardwareTest" } ] }
automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +58 −6 Original line number Diff line number Diff line Loading @@ -106,15 +106,67 @@ std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() cons return mServerSidePropStore->getAllConfigs(); } StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&&, const std::vector<SetValueRequest>&) { // TODO(b/201830716): Implement this. StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&& callback, const std::vector<SetValueRequest>& requests) { std::vector<VehiclePropValue> updatedValues; std::vector<SetValueResult> results; for (auto& request : requests) { const VehiclePropValue* value = &request.value; ALOGD("setValues(%d)", value->prop); auto updatedValue = mValuePool->obtain(*value); int64_t timestamp = elapsedRealtimeNano(); updatedValue->timestamp = timestamp; auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue)); SetValueResult setValueResult; setValueResult.requestId = request.requestId; if (!writeResult.ok()) { ALOGE("failed to write value into property store, error: %s, code: %d", writeResult.error().message().c_str(), writeResult.error().code()); setValueResult.status = StatusCode::INVALID_ARG; } else { setValueResult.status = StatusCode::OK; } results.push_back(std::move(setValueResult)); } // In the real vhal, the values will be sent to Car ECU. We just pretend it is done here and // send back the updated property values to client. callback(std::move(results)); return StatusCode::OK; } StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback&&, const std::vector<GetValueRequest>&) const { // TODO(b/201830716): Implement this. StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback&& callback, const std::vector<GetValueRequest>& requests) const { std::vector<GetValueResult> results; for (auto& request : requests) { const VehiclePropValue* value = &request.prop; ALOGD("getValues(%d)", value->prop); auto readResult = mServerSidePropStore->readValue(*value); GetValueResult getValueResult; getValueResult.requestId = request.requestId; if (!readResult.ok()) { auto error = readResult.error(); if (error.code() == toInt(StatusCode::NOT_AVAILABLE)) { ALOGW("%s", "value has not been set yet"); getValueResult.status = StatusCode::NOT_AVAILABLE; } else { ALOGE("failed to get value, error: %s, code: %d", error.message().c_str(), error.code()); getValueResult.status = StatusCode::INVALID_ARG; } } else { getValueResult.status = StatusCode::OK; getValueResult.prop = *readResult.value(); } results.push_back(std::move(getValueResult)); } callback(std::move(results)); return StatusCode::OK; } Loading
automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +264 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ using ::testing::ContainerEq; using ::testing::Eq; using ::testing::WhenSortedBy; constexpr int INVALID_PROP_ID = 0; } // namespace class FakeVehicleHardwareTest : public ::testing::Test { Loading Loading @@ -159,6 +161,268 @@ TEST_F(FakeVehicleHardwareTest, testGetAllPropertyConfigs) { ASSERT_EQ(configs.size(), defaultconfig::getDefaultConfigs().size()); } TEST_F(FakeVehicleHardwareTest, testGetDefaultValues) { std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; int64_t requestId = 1; for (auto& config : defaultconfig::getDefaultConfigs()) { int propId = config.config.prop; if (isGlobalProp(propId)) { if (config.initialValue == RawPropValues{}) { addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, VehiclePropValue{.prop = propId}, StatusCode::NOT_AVAILABLE); continue; } addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, VehiclePropValue{ .prop = propId, .value = config.initialValue, }, StatusCode::OK); continue; } for (auto areaConfig : config.config.areaConfigs) { StatusCode status = StatusCode::OK; VehiclePropValue propValue{ .prop = propId, .areaId = areaConfig.areaId, }; if (config.initialAreaValues.empty()) { if (config.initialValue == RawPropValues{}) { status = StatusCode::NOT_AVAILABLE; } else { propValue.value = config.initialValue; } } else if (auto valueForAreaIt = config.initialAreaValues.find(areaConfig.areaId); valueForAreaIt != config.initialAreaValues.end()) { propValue.value = valueForAreaIt->second; } else { status = StatusCode::NOT_AVAILABLE; } addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, propValue, status); } } // In our implementation, this would finish immediately. StatusCode status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueResult> getValueResultsWithNoTimestamp; for (auto& result : getGetValueResults()) { GetValueResult resultCopy = result; resultCopy.prop->timestamp = 0; getValueResultsWithNoTimestamp.push_back(std::move(resultCopy)); } ASSERT_THAT(getValueResultsWithNoTimestamp, ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testSetValues) { std::vector<SetValueRequest> requests; std::vector<SetValueResult> expectedResults; int64_t requestId = 1; for (auto& value : getTestPropValues()) { addSetValueRequest(requests, expectedResults, requestId++, value, StatusCode::OK); } StatusCode status = setValues(requests); ASSERT_EQ(status, StatusCode::OK); // Although callback might be called asynchronously, in our implementation, the callback would // be called before setValues returns. ASSERT_THAT(getSetValueResults(), ContainerEq(expectedResults)); } TEST_F(FakeVehicleHardwareTest, testSetValuesError) { std::vector<SetValueRequest> requests; std::vector<SetValueResult> expectedResults; int64_t requestId = 1; VehiclePropValue invalidProp = { .prop = INVALID_PROP_ID, }; addSetValueRequest(requests, expectedResults, requestId++, invalidProp, StatusCode::INVALID_ARG); for (auto& value : getTestPropValues()) { addSetValueRequest(requests, expectedResults, requestId++, value, StatusCode::OK); } StatusCode status = setValues(requests); ASSERT_EQ(status, StatusCode::OK); // Although callback might be called asynchronously, in our implementation, the callback would // be called before setValues returns. ASSERT_THAT(getSetValueResults(), ContainerEq(expectedResults)); } TEST_F(FakeVehicleHardwareTest, testRegisterOnPropertyChangeEvent) { getHardware()->registerOnPropertyChangeEvent(std::bind( &FakeVehicleHardwareTest_testRegisterOnPropertyChangeEvent_Test::onPropertyChangeEvent, this, std::placeholders::_1)); auto testValues = getTestPropValues(); std::vector<SetValueRequest> requests; std::vector<SetValueResult> expectedResults; int64_t requestId = 1; for (auto& value : testValues) { addSetValueRequest(requests, expectedResults, requestId++, value, StatusCode::OK); } int64_t timestamp = elapsedRealtimeNano(); StatusCode status = setValues(requests); ASSERT_EQ(status, StatusCode::OK); auto updatedValues = getChangedProperties(); std::vector<VehiclePropValue> updatedValuesWithNoTimestamp; for (auto& value : updatedValues) { ASSERT_GE(value.timestamp, timestamp); VehiclePropValue valueCopy = value; valueCopy.timestamp = 0; updatedValuesWithNoTimestamp.push_back(std::move(valueCopy)); } ASSERT_THAT(updatedValuesWithNoTimestamp, WhenSortedBy(mPropValueCmp, Eq(testValues))); } TEST_F(FakeVehicleHardwareTest, testReadValues) { std::vector<SetValueRequest> setValueRequests; std::vector<SetValueResult> expectedSetValueResults; int64_t requestId = 1; for (auto& value : getTestPropValues()) { addSetValueRequest(setValueRequests, expectedSetValueResults, requestId++, value, StatusCode::OK); } int64_t timestamp = elapsedRealtimeNano(); // In our implementation, this would finish immediately. StatusCode status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; for (auto& value : getTestPropValues()) { addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, value, StatusCode::OK); } // In our implementation, this would finish immediately. status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueResult> getValueResultsWithNoTimestamp; for (auto& result : getGetValueResults()) { ASSERT_GE(result.prop->timestamp, timestamp); GetValueResult resultCopy = result; resultCopy.prop->timestamp = 0; getValueResultsWithNoTimestamp.push_back(std::move(resultCopy)); } ASSERT_THAT(getValueResultsWithNoTimestamp, ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testReadValuesErrorInvalidProp) { std::vector<SetValueRequest> setValueRequests; std::vector<SetValueResult> expectedSetValueResults; int64_t requestId = 1; for (auto& value : getTestPropValues()) { addSetValueRequest(setValueRequests, expectedSetValueResults, requestId++, value, StatusCode::OK); } // In our implementation, this would finish immediately. StatusCode status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; VehiclePropValue invalidProp = { .prop = INVALID_PROP_ID, }; addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++, invalidProp, StatusCode::INVALID_ARG); // In our implementation, this would finish immediately. status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_THAT(getGetValueResults(), ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testReadValuesErrorNotAvailable) { std::vector<GetValueRequest> getValueRequests; std::vector<GetValueResult> expectedGetValueResults; // VEHICLE_MAP_SERVICE does not have initial value, 'get' must always return // StatusCode::NOT_AVAILABLE. addGetValueRequest(getValueRequests, expectedGetValueResults, 0, VehiclePropValue{ .prop = VEHICLE_MAP_SERVICE, }, StatusCode::NOT_AVAILABLE); // In our implementation, this would finish immediately. StatusCode status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_THAT(getGetValueResults(), ContainerEq(expectedGetValueResults)); } TEST_F(FakeVehicleHardwareTest, testSetStatusMustIgnore) { VehiclePropValue testValue = getTestPropValues()[0]; testValue.status = VehiclePropertyStatus::UNAVAILABLE; std::vector<SetValueRequest> setValueRequests; std::vector<SetValueResult> expectedSetValueResults; int64_t requestId = 1; addSetValueRequest(setValueRequests, expectedSetValueResults, requestId++, testValue, StatusCode::OK); // In our implementation, this would finish immediately. StatusCode status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_THAT(getSetValueResults(), ContainerEq(expectedSetValueResults)); std::vector<GetValueRequest> getValueRequests; getValueRequests.push_back(GetValueRequest{ .requestId = requestId++, .prop = testValue, }); // In our implementation, this would finish immediately. status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_EQ(getGetValueResults().size(), static_cast<size_t>(1)); ASSERT_EQ(getGetValueResults()[0].status, StatusCode::OK); // The status should be by-default AVAILABLE for new status. ASSERT_EQ(getGetValueResults()[0].prop->status, VehiclePropertyStatus::AVAILABLE); // Try to set the property again. The status should not be overwritten. status = setValues(setValueRequests); ASSERT_EQ(status, StatusCode::OK); status = getValues(getValueRequests); ASSERT_EQ(status, StatusCode::OK); ASSERT_EQ(getGetValueResults().size(), static_cast<size_t>(2)); ASSERT_EQ(getGetValueResults()[1].status, StatusCode::OK); ASSERT_EQ(getGetValueResults()[1].prop->status, VehiclePropertyStatus::AVAILABLE); } } // namespace vehicle } // namespace automotive } // namespace hardware Loading