// Copyright (C) 2023 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "GRPCVehicleHardware.h" #include "VehicleServer.grpc.pb.h" #include "VehicleServer.pb.h" #include #include #include #include #include #include namespace android::hardware::automotive::vehicle::virtualization { const std::string kFakeServerAddr = "0.0.0.0:54321"; class FakeVehicleServer : public proto::VehicleServer::Service { public: ::grpc::Status StartPropertyValuesStream( ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::grpc::ServerWriter* stream) override { stream->Write(proto::VehiclePropValues()); // A fake disconnection. return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost."); } // Functions that we do not care. ::grpc::Status GetAllPropertyConfig( ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::grpc::ServerWriter* stream) override { return ::grpc::Status::OK; } ::grpc::Status SetValues(::grpc::ServerContext* context, const proto::VehiclePropValueRequests* requests, proto::SetValueResults* results) override { return ::grpc::Status::OK; } ::grpc::Status GetValues(::grpc::ServerContext* context, const proto::VehiclePropValueRequests* requests, proto::GetValueResults* results) override { return ::grpc::Status::OK; } }; TEST(GRPCVehicleHardwareUnitTest, Reconnect) { auto receivedUpdate = std::make_shared>(0); auto vehicleHardware = std::make_unique(kFakeServerAddr); vehicleHardware->registerOnPropertyChangeEvent( std::make_unique( [receivedUpdate](const auto&) { receivedUpdate->fetch_add(1); })); constexpr size_t kServerRestartTimes = 5; for (size_t serverStart = 0; serverStart < kServerRestartTimes; ++serverStart) { EXPECT_EQ(receivedUpdate->load(), 0); auto fakeServer = std::make_unique(); ::grpc::ServerBuilder builder; builder.RegisterService(fakeServer.get()); builder.AddListeningPort(kFakeServerAddr, ::grpc::InsecureServerCredentials()); auto grpcServer = builder.BuildAndStart(); // Wait until the vehicle hardware received the second update (after one fake // disconnection). constexpr auto kMaxWaitTime = std::chrono::seconds(5); auto startTime = std::chrono::steady_clock::now(); while (receivedUpdate->load() <= 1 && std::chrono::steady_clock::now() - startTime < kMaxWaitTime) ; grpcServer->Shutdown(); grpcServer->Wait(); EXPECT_GT(receivedUpdate->load(), 1); // Reset for the next round. receivedUpdate->store(0); } } } // namespace android::hardware::automotive::vehicle::virtualization