• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //       http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "GRPCVehicleHardware.h"
16 #include "VehicleServer.grpc.pb.h"
17 #include "VehicleServer.pb.h"
18 #include "VehicleServer_mock.grpc.pb.h"
19 
20 #include <gmock/gmock.h>
21 #include <grpc++/grpc++.h>
22 #include <grpcpp/test/mock_stream.h>
23 #include <gtest/gtest.h>
24 
25 #include <utils/SystemClock.h>
26 #include <chrono>
27 #include <memory>
28 #include <string>
29 
30 namespace android::hardware::automotive::vehicle::virtualization {
31 
32 namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
33 
34 using ::testing::_;
35 using ::testing::DoAll;
36 using ::testing::ElementsAre;
37 using ::testing::NiceMock;
38 using ::testing::Return;
39 using ::testing::SaveArg;
40 using ::testing::SetArgPointee;
41 using ::testing::SizeIs;
42 
43 using ::grpc::testing::MockClientReader;
44 
45 using proto::MockVehicleServerStub;
46 
47 class GRPCVehicleHardwareUnitTest : public ::testing::Test {
48   protected:
49     NiceMock<MockVehicleServerStub>* mGrpcStub;
50     std::unique_ptr<GRPCVehicleHardware> mHardware;
51 
SetUp()52     void SetUp() override {
53         auto stub = std::make_unique<NiceMock<MockVehicleServerStub>>();
54         mGrpcStub = stub.get();
55         // Cannot use make_unique here since the constructor is a private method.
56         mHardware = std::unique_ptr<GRPCVehicleHardware>(
57                 new GRPCVehicleHardware(std::move(stub), /*startValuePollingLoop=*/false));
58     }
59 
TearDown()60     void TearDown() override { mHardware.reset(); }
61 
62     // Access GRPCVehicleHardware private method.
pollValue()63     void pollValue() { mHardware->pollValue(); }
64 
startValuePollingLoop(std::unique_ptr<proto::VehicleServer::StubInterface> stub)65     void startValuePollingLoop(std::unique_ptr<proto::VehicleServer::StubInterface> stub) {
66         mHardware = std::unique_ptr<GRPCVehicleHardware>(
67                 new GRPCVehicleHardware(std::move(stub), /*startValuePollingLoop=*/true));
68     }
69 
70     void generatePropertyUpdateEvent(int32_t propId, int64_t timestamp);
71 };
72 
73 MATCHER_P(RepeatedInt32Eq, expected_values, "") {
74     return std::vector<int32_t>(arg.begin(), arg.end()) == expected_values;
75 }
76 
TEST_F(GRPCVehicleHardwareUnitTest,TestSubscribe)77 TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribe) {
78     proto::VehicleHalCallStatus protoStatus;
79     protoStatus.set_status_code(proto::StatusCode::OK);
80     proto::SubscribeRequest actualRequest;
81 
82     EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
83             .WillOnce(DoAll(SaveArg<1>(&actualRequest), SetArgPointee<2>(protoStatus),
84                             Return(::grpc::Status::OK)));
85 
86     aidlvhal::SubscribeOptions options = {.propId = 1,
87                                           .areaIds = {1, 2, 3, 4},
88                                           .sampleRate = 1.234,
89                                           .resolution = 0.01,
90                                           .enableVariableUpdateRate = true};
91     auto status = mHardware->subscribe(options);
92 
93     EXPECT_EQ(status, aidlvhal::StatusCode::OK);
94     const auto& protoOptions = actualRequest.options();
95     EXPECT_EQ(protoOptions.prop_id(), 1);
96     EXPECT_THAT(protoOptions.area_ids(), RepeatedInt32Eq(std::vector<int32_t>({1, 2, 3, 4})));
97     EXPECT_FLOAT_EQ(protoOptions.sample_rate(), 1.234);
98     EXPECT_FLOAT_EQ(protoOptions.resolution(), 0.01);
99     EXPECT_EQ(protoOptions.enable_variable_update_rate(), true);
100 }
101 
TEST_F(GRPCVehicleHardwareUnitTest,TestSubscribeLegacyServer)102 TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribeLegacyServer) {
103     EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
104             .WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")));
105 
106     aidlvhal::SubscribeOptions options;
107     auto status = mHardware->subscribe(options);
108 
109     EXPECT_EQ(status, aidlvhal::StatusCode::OK);
110 }
111 
TEST_F(GRPCVehicleHardwareUnitTest,TestSubscribeGrpcFailure)112 TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribeGrpcFailure) {
113     EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
114             .WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error")));
115 
116     aidlvhal::SubscribeOptions options;
117     auto status = mHardware->subscribe(options);
118 
119     EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR);
120 }
121 
TEST_F(GRPCVehicleHardwareUnitTest,TestSubscribeProtoFailure)122 TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribeProtoFailure) {
123     proto::VehicleHalCallStatus protoStatus;
124     protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW);
125 
126     EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
127             .WillOnce(DoAll(SetArgPointee<2>(protoStatus),  // Set the output status
128                             Return(::grpc::Status::OK)));
129 
130     aidlvhal::SubscribeOptions options;
131     auto status = mHardware->subscribe(options);
132 
133     EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW);
134 }
135 
TEST_F(GRPCVehicleHardwareUnitTest,TestUnsubscribe)136 TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribe) {
137     proto::VehicleHalCallStatus protoStatus;
138     protoStatus.set_status_code(proto::StatusCode::OK);
139     proto::UnsubscribeRequest actualRequest;
140 
141     EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
142             .WillOnce(DoAll(SaveArg<1>(&actualRequest), SetArgPointee<2>(protoStatus),
143                             Return(::grpc::Status::OK)));
144 
145     int32_t propId = 1;
146     int32_t areaId = 2;
147     auto status = mHardware->unsubscribe(propId, areaId);
148 
149     EXPECT_EQ(status, aidlvhal::StatusCode::OK);
150     EXPECT_EQ(actualRequest.prop_id(), propId);
151     EXPECT_EQ(actualRequest.area_id(), areaId);
152 }
153 
TEST_F(GRPCVehicleHardwareUnitTest,TestUnsubscribeLegacyServer)154 TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribeLegacyServer) {
155     EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
156             .WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")));
157 
158     auto status = mHardware->unsubscribe(1, 2);
159 
160     EXPECT_EQ(status, aidlvhal::StatusCode::OK);
161 }
162 
TEST_F(GRPCVehicleHardwareUnitTest,TestUnsubscribeGrpcFailure)163 TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribeGrpcFailure) {
164     EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
165             .WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error")));
166 
167     auto status = mHardware->unsubscribe(1, 2);
168 
169     EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR);
170 }
171 
TEST_F(GRPCVehicleHardwareUnitTest,TestUnsubscribeProtoFailure)172 TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribeProtoFailure) {
173     proto::VehicleHalCallStatus protoStatus;
174     protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW);
175 
176     EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
177             .WillOnce(DoAll(SetArgPointee<2>(protoStatus),  // Set the output status
178                             Return(::grpc::Status::OK)));
179 
180     auto status = mHardware->unsubscribe(1, 2);
181 
182     EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW);
183 }
184 
TEST_F(GRPCVehicleHardwareUnitTest,TestPollValue)185 TEST_F(GRPCVehicleHardwareUnitTest, TestPollValue) {
186     int64_t testTimestamp = 12345;
187     int32_t testPropId = 54321;
188     int64_t startTimestamp = elapsedRealtimeNano();
189 
190     // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
191     // there.
192     auto clientReader = new MockClientReader<proto::VehiclePropValues>();
193     EXPECT_CALL(*mGrpcStub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
194     EXPECT_CALL(*clientReader, Read(_))
195             .WillOnce([testTimestamp, testPropId](proto::VehiclePropValues* values) {
196                 values->Clear();
197                 auto value = values->add_values();
198                 value->set_timestamp(testTimestamp);
199                 value->set_prop(testPropId);
200                 return true;
201             })
202             .WillOnce(Return(false));
203     EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
204 
205     std::vector<aidlvhal::VehiclePropValue> propertyEvents;
206 
207     mHardware->registerOnPropertyChangeEvent(
208             std::make_unique<GRPCVehicleHardware::PropertyChangeCallback>(
209                     [&propertyEvents](const std::vector<aidlvhal::VehiclePropValue>& events) {
210                         for (const auto& event : events) {
211                             propertyEvents.push_back(event);
212                         }
213                     }));
214 
215     pollValue();
216 
217     ASSERT_THAT(propertyEvents, SizeIs(1));
218     EXPECT_EQ(propertyEvents[0].prop, testPropId);
219     EXPECT_GT(propertyEvents[0].timestamp, startTimestamp)
220             << "Timestamp must be updated to Android timestamp";
221     EXPECT_LT(propertyEvents[0].timestamp, elapsedRealtimeNano())
222             << "Timestamp must be updated to Android timestamp";
223 }
224 
TEST_F(GRPCVehicleHardwareUnitTest,TestPollValueIgnoreOutdatedValue)225 TEST_F(GRPCVehicleHardwareUnitTest, TestPollValueIgnoreOutdatedValue) {
226     int64_t testTimestamp1 = 12345;
227     int32_t value1 = 1324;
228     int64_t testTimestamp2 = 12340;
229     int32_t value2 = 1423;
230     int32_t testPropId = 54321;
231     int64_t startTimestamp = elapsedRealtimeNano();
232 
233     // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
234     // there.
235     auto clientReader = new MockClientReader<proto::VehiclePropValues>();
236     EXPECT_CALL(*mGrpcStub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
237     EXPECT_CALL(*clientReader, Read(_))
238             .WillOnce([testTimestamp1, value1, testPropId](proto::VehiclePropValues* values) {
239                 values->Clear();
240                 auto value = values->add_values();
241                 value->set_timestamp(testTimestamp1);
242                 value->set_prop(testPropId);
243                 value->add_int32_values(value1);
244                 return true;
245             })
246             .WillOnce([testTimestamp2, value2, testPropId](proto::VehiclePropValues* values) {
247                 values->Clear();
248                 // This event is outdated, must be ignored.
249                 auto value = values->add_values();
250                 value->set_timestamp(testTimestamp2);
251                 value->set_prop(testPropId);
252                 value->add_int32_values(value2);
253                 return true;
254             })
255             .WillOnce(Return(false));
256     EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
257 
258     std::vector<aidlvhal::VehiclePropValue> propertyEvents;
259 
260     mHardware->registerOnPropertyChangeEvent(
261             std::make_unique<GRPCVehicleHardware::PropertyChangeCallback>(
262                     [&propertyEvents](const std::vector<aidlvhal::VehiclePropValue>& events) {
263                         for (const auto& event : events) {
264                             propertyEvents.push_back(event);
265                         }
266                     }));
267 
268     pollValue();
269 
270     ASSERT_THAT(propertyEvents, SizeIs(1)) << "Outdated event must be ignored";
271     EXPECT_EQ(propertyEvents[0].prop, testPropId);
272     EXPECT_GT(propertyEvents[0].timestamp, startTimestamp);
273     EXPECT_LT(propertyEvents[0].timestamp, elapsedRealtimeNano());
274     EXPECT_THAT(propertyEvents[0].value.int32Values, ElementsAre(value1));
275 }
276 
TEST_F(GRPCVehicleHardwareUnitTest,TestValuePollingLoop)277 TEST_F(GRPCVehicleHardwareUnitTest, TestValuePollingLoop) {
278     int64_t testTimestamp = 12345;
279     int32_t testPropId = 54321;
280     auto stub = std::make_unique<NiceMock<MockVehicleServerStub>>();
281 
282     // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
283     // there.
284     auto clientReader = new MockClientReader<proto::VehiclePropValues>();
285     EXPECT_CALL(*stub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
286     EXPECT_CALL(*clientReader, Read(_))
287             .WillRepeatedly([testTimestamp, testPropId](proto::VehiclePropValues* values) {
288                 // Sleep for 10ms and always return the same property event.
289                 std::this_thread::sleep_for(std::chrono::milliseconds(10));
290                 values->Clear();
291                 auto value = values->add_values();
292                 value->set_timestamp(testTimestamp);
293                 value->set_prop(testPropId);
294                 return true;
295             });
296     EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
297 
298     startValuePollingLoop(std::move(stub));
299 
300     std::this_thread::sleep_for(std::chrono::milliseconds(100));
301 
302     // This must stop the loop and wait for the thread to finish.
303     mHardware.reset();
304 }
305 
TEST_F(GRPCVehicleHardwareUnitTest,TestGetValues)306 TEST_F(GRPCVehicleHardwareUnitTest, TestGetValues) {
307     int64_t testRequestId = 1234;
308     int32_t testPropId = 4321;
309     int32_t testValue = 123456;
310     proto::VehiclePropValueRequests gotRequests;
311     EXPECT_CALL(*mGrpcStub, GetValues(_, _, _))
312             .WillOnce([&gotRequests, testRequestId, testPropId, testValue](
313                               ::grpc::ClientContext* context,
314                               const proto::VehiclePropValueRequests& request,
315                               proto::GetValueResults* response) {
316                 gotRequests = request;
317                 response->Clear();
318                 auto* resultPtr = response->add_results();
319                 resultPtr->set_request_id(testRequestId);
320                 resultPtr->set_status(proto::StatusCode::OK);
321                 auto* valuePtr = resultPtr->mutable_value();
322                 valuePtr->set_prop(testPropId);
323                 valuePtr->add_int32_values(testValue);
324                 return ::grpc::Status::OK;
325             });
326 
327     std::vector<aidlvhal::GetValueRequest> requests;
328     requests.push_back(aidlvhal::GetValueRequest{.requestId = testRequestId,
329                                                  .prop = {
330                                                          .prop = testPropId,
331                                                  }});
332 
333     std::vector<aidlvhal::GetValueResult> gotResults;
334 
335     auto status = mHardware->getValues(
336             std::make_shared<GRPCVehicleHardware::GetValuesCallback>(
337                     [&gotResults](std::vector<aidlvhal::GetValueResult> results) {
338                         for (const auto& result : results) {
339                             gotResults.push_back(result);
340                         }
341                     }),
342             requests);
343 
344     ASSERT_EQ(status, aidlvhal::StatusCode::OK);
345     ASSERT_THAT(gotRequests.requests(), SizeIs(1));
346     EXPECT_THAT(gotRequests.requests(0).request_id(), testRequestId);
347     EXPECT_THAT(gotRequests.requests(0).value().prop(), testPropId);
348 
349     ASSERT_THAT(gotResults, SizeIs(1));
350     EXPECT_EQ(gotResults[0].requestId, testRequestId);
351     EXPECT_EQ(gotResults[0].status, aidlvhal::StatusCode::OK);
352     EXPECT_EQ(gotResults[0].prop->prop, testPropId);
353     EXPECT_THAT(gotResults[0].prop->value.int32Values, ElementsAre(testValue));
354 }
355 
generatePropertyUpdateEvent(int32_t propId,int64_t timestamp)356 void GRPCVehicleHardwareUnitTest::generatePropertyUpdateEvent(int32_t propId, int64_t timestamp) {
357     // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
358     // there.
359     auto clientReader = new MockClientReader<proto::VehiclePropValues>();
360     EXPECT_CALL(*mGrpcStub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
361     EXPECT_CALL(*clientReader, Read(_))
362             .WillOnce([timestamp, propId](proto::VehiclePropValues* values) {
363                 values->Clear();
364                 auto value = values->add_values();
365                 value->set_timestamp(timestamp);
366                 value->set_prop(propId);
367                 return true;
368             })
369             .WillOnce(Return(false));
370     EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
371 
372     pollValue();
373 }
374 
TEST_F(GRPCVehicleHardwareUnitTest,TestGetValuesOutdatedRetry)375 TEST_F(GRPCVehicleHardwareUnitTest, TestGetValuesOutdatedRetry) {
376     int64_t startTimestamp = elapsedRealtimeNano();
377     int64_t testRequestId = 1234;
378     int32_t testPropId = 4321;
379     int32_t testValue1 = 123456;
380     int32_t testValue2 = 654321;
381     int32_t testTimestamp1 = 1000;
382     int32_t testTimestamp2 = 2000;
383 
384     // A property update event for testTimestamp2 happens before getValues returns.
385     generatePropertyUpdateEvent(testPropId, testTimestamp2);
386 
387     // GetValues first returns an outdated result, then an up-to-date result.
388     EXPECT_CALL(*mGrpcStub, GetValues(_, _, _))
389             .WillOnce([testRequestId, testPropId, testValue1, testTimestamp1](
390                               ::grpc::ClientContext* context,
391                               const proto::VehiclePropValueRequests& request,
392                               proto::GetValueResults* response) {
393                 response->Clear();
394                 auto* resultPtr = response->add_results();
395                 resultPtr->set_request_id(testRequestId);
396                 resultPtr->set_status(proto::StatusCode::OK);
397                 auto* valuePtr = resultPtr->mutable_value();
398                 valuePtr->set_prop(testPropId);
399                 valuePtr->set_timestamp(testTimestamp1);
400                 valuePtr->add_int32_values(testValue1);
401                 return ::grpc::Status::OK;
402             })
403             .WillOnce([testRequestId, testPropId, testValue2, testTimestamp2](
404                               ::grpc::ClientContext* context,
405                               const proto::VehiclePropValueRequests& request,
406                               proto::GetValueResults* response) {
407                 response->Clear();
408                 auto* resultPtr = response->add_results();
409                 resultPtr->set_request_id(testRequestId);
410                 resultPtr->set_status(proto::StatusCode::OK);
411                 auto* valuePtr = resultPtr->mutable_value();
412                 valuePtr->set_prop(testPropId);
413                 valuePtr->set_timestamp(testTimestamp2);
414                 valuePtr->add_int32_values(testValue2);
415                 return ::grpc::Status::OK;
416             });
417 
418     std::vector<aidlvhal::GetValueRequest> requests;
419     requests.push_back(aidlvhal::GetValueRequest{.requestId = testRequestId,
420                                                  .prop = {
421                                                          .prop = testPropId,
422                                                  }});
423 
424     std::vector<aidlvhal::GetValueResult> gotResults;
425 
426     auto status = mHardware->getValues(
427             std::make_shared<GRPCVehicleHardware::GetValuesCallback>(
428                     [&gotResults](std::vector<aidlvhal::GetValueResult> results) {
429                         for (const auto& result : results) {
430                             gotResults.push_back(result);
431                         }
432                     }),
433             requests);
434 
435     ASSERT_EQ(status, aidlvhal::StatusCode::OK);
436     ASSERT_THAT(gotResults, SizeIs(1));
437     EXPECT_EQ(gotResults[0].requestId, testRequestId);
438     EXPECT_EQ(gotResults[0].status, aidlvhal::StatusCode::OK);
439     EXPECT_EQ(gotResults[0].prop->prop, testPropId);
440     EXPECT_THAT(gotResults[0].prop->value.int32Values, ElementsAre(testValue2));
441     EXPECT_GT(gotResults[0].prop->timestamp, startTimestamp);
442     EXPECT_LT(gotResults[0].prop->timestamp, elapsedRealtimeNano());
443 }
444 
TEST_F(GRPCVehicleHardwareUnitTest,testGetMinMaxSupportedValues)445 TEST_F(GRPCVehicleHardwareUnitTest, testGetMinMaxSupportedValues) {
446     int32_t testPropId = 1234;
447     int32_t testAreaId = 4321;
448     int32_t testValue1 = 12345;
449     int32_t testValue2 = 123456;
450     std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
451 
452     EXPECT_CALL(*mGrpcStub, GetMinMaxSupportedValues(_, _, _))
453             .WillOnce([=](::grpc::ClientContext* context,
454                           const proto::GetMinMaxSupportedValuesRequest& request,
455                           proto::GetMinMaxSupportedValuesResult* response) {
456                 for (const auto& propIdAreaId : request.prop_id_area_id()) {
457                     proto::MinMaxSupportedValueResult* individualResult = response->add_result();
458                     individualResult->set_status(proto::StatusCode::OK);
459                     individualResult->mutable_min_supported_value()->add_int32_values(testValue1);
460                     individualResult->mutable_max_supported_value()->add_int32_values(testValue2);
461                 }
462                 return ::grpc::Status::OK;
463             });
464 
465     auto results = mHardware->getMinMaxSupportedValues(propIdAreaIds);
466 
467     ASSERT_THAT(results, ::testing::SizeIs(1));
468     EXPECT_EQ(results[0].status, aidlvhal::StatusCode::OK);
469     ASSERT_TRUE(results[0].minSupportedValue.has_value());
470     EXPECT_EQ(results[0].minSupportedValue.value(),
471               aidlvhal::RawPropValues{.int32Values = {testValue1}});
472     ASSERT_TRUE(results[0].maxSupportedValue.has_value());
473     EXPECT_EQ(results[0].maxSupportedValue.value(),
474               aidlvhal::RawPropValues{.int32Values = {testValue2}});
475 }
476 
TEST_F(GRPCVehicleHardwareUnitTest,testGetMinMaxSupportedValues_noMaxValue)477 TEST_F(GRPCVehicleHardwareUnitTest, testGetMinMaxSupportedValues_noMaxValue) {
478     int32_t testPropId = 1234;
479     int32_t testAreaId = 4321;
480     int32_t testValue1 = 12345;
481     std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
482 
483     EXPECT_CALL(*mGrpcStub, GetMinMaxSupportedValues(_, _, _))
484             .WillOnce([=](::grpc::ClientContext* context,
485                           const proto::GetMinMaxSupportedValuesRequest& request,
486                           proto::GetMinMaxSupportedValuesResult* response) {
487                 for (const auto& propIdAreaId : request.prop_id_area_id()) {
488                     proto::MinMaxSupportedValueResult* individualResult = response->add_result();
489                     individualResult->set_status(proto::StatusCode::OK);
490                     individualResult->mutable_min_supported_value()->add_int32_values(testValue1);
491                 }
492                 return ::grpc::Status::OK;
493             });
494 
495     auto results = mHardware->getMinMaxSupportedValues(propIdAreaIds);
496 
497     ASSERT_THAT(results, ::testing::SizeIs(1));
498     EXPECT_EQ(results[0].status, aidlvhal::StatusCode::OK);
499     ASSERT_TRUE(results[0].minSupportedValue.has_value());
500     EXPECT_EQ(results[0].minSupportedValue.value(),
501               aidlvhal::RawPropValues{.int32Values = {testValue1}});
502     ASSERT_FALSE(results[0].maxSupportedValue.has_value());
503 }
504 
TEST_F(GRPCVehicleHardwareUnitTest,testGetSupportedValuesLists)505 TEST_F(GRPCVehicleHardwareUnitTest, testGetSupportedValuesLists) {
506     int32_t testPropId = 1234;
507     int32_t testAreaId = 4321;
508     int32_t testValue1 = 12345;
509     int32_t testValue2 = 123456;
510     std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
511 
512     EXPECT_CALL(*mGrpcStub, GetSupportedValuesLists(_, _, _))
513             .WillOnce([=](::grpc::ClientContext* context,
514                           const proto::GetSupportedValuesListsRequest& request,
515                           proto::GetSupportedValuesListsResult* response) {
516                 for (const auto& propIdAreaId : request.prop_id_area_id()) {
517                     proto::SupportedValuesListResult* individualResult = response->add_result();
518                     individualResult->set_status(proto::StatusCode::OK);
519                     individualResult->add_supported_values_list()->add_int32_values(testValue1);
520                     individualResult->add_supported_values_list()->add_int32_values(testValue2);
521                 }
522                 return ::grpc::Status::OK;
523             });
524 
525     auto results = mHardware->getSupportedValuesLists(propIdAreaIds);
526 
527     ASSERT_THAT(results, ::testing::SizeIs(1));
528     EXPECT_EQ(results[0].status, aidlvhal::StatusCode::OK);
529     ASSERT_TRUE(results[0].supportedValuesList.has_value());
530     ASSERT_THAT(results[0].supportedValuesList.value(), ::testing::SizeIs(2));
531     EXPECT_EQ(results[0].supportedValuesList.value()[0],
532               aidlvhal::RawPropValues{.int32Values = {testValue1}});
533     EXPECT_EQ(results[0].supportedValuesList.value()[1],
534               aidlvhal::RawPropValues{.int32Values = {testValue2}});
535 }
536 
TEST_F(GRPCVehicleHardwareUnitTest,testGetSupportedValuesLists_noSupportedValue)537 TEST_F(GRPCVehicleHardwareUnitTest, testGetSupportedValuesLists_noSupportedValue) {
538     int32_t testPropId = 1234;
539     int32_t testAreaId = 4321;
540     std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
541 
542     EXPECT_CALL(*mGrpcStub, GetSupportedValuesLists(_, _, _))
543             .WillOnce([=](::grpc::ClientContext* context,
544                           const proto::GetSupportedValuesListsRequest& request,
545                           proto::GetSupportedValuesListsResult* response) {
546                 for (const auto& propIdAreaId : request.prop_id_area_id()) {
547                     proto::SupportedValuesListResult* individualResult = response->add_result();
548                     individualResult->set_status(proto::StatusCode::INTERNAL_ERROR);
549                 }
550                 return ::grpc::Status::OK;
551             });
552 
553     auto results = mHardware->getSupportedValuesLists(propIdAreaIds);
554 
555     ASSERT_THAT(results, ::testing::SizeIs(1));
556     EXPECT_EQ(results[0].status, aidlvhal::StatusCode::INTERNAL_ERROR);
557     ASSERT_FALSE(results[0].supportedValuesList.has_value());
558 }
559 
560 }  // namespace android::hardware::automotive::vehicle::virtualization
561