1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <chrono> 18 #include <fstream> 19 #include <thread> 20 21 #include <sys/socket.h> 22 #include <sys/un.h> 23 #include <unistd.h> 24 25 #include <android-base/file.h> 26 #include <android/hardware/automotive/vehicle/2.0/types.h> 27 #include <gtest/gtest.h> 28 29 #include "GrpcVehicleClient.h" 30 #include "GrpcVehicleServer.h" 31 #include "Utils.h" 32 #include "vhal_v2_0/VehicleUtils.h" 33 34 namespace android::hardware::automotive::vehicle::V2_0::impl { 35 36 class GrpcServerTest : public ::testing::Test { 37 public: 38 GrpcServerTest() 39 : mPowerStateSocketForTest(std::string(mTestTempDir.path) + 40 std::string("/power_state_socket_for_test_") + 41 std::to_string(getpid())), 42 mServerInfo({{GetTestCID(), 12345}, 43 mPowerStateMarkerFileForTest.path, 44 mPowerStateSocketForTest}) {} 45 46 void SetUp() override { 47 mGrpcServer = makeGrpcVehicleServer(mServerInfo); 48 49 ASSERT_TRUE(GetGrpcServer() != nullptr); 50 GetGrpcServer()->Start(); 51 } 52 53 void TearDown() override { 54 GetGrpcServer()->Stop().Wait(); 55 mGrpcServer.reset(); 56 } 57 58 static unsigned GetTestCID(); 59 60 GrpcVehicleServer* GetGrpcServer() const { return mGrpcServer.get(); } 61 62 std::string GetGrpcServerUri() const { return mServerInfo.getServerUri(); } 63 64 std::string GetPowerStateSocketPath() const { return mPowerStateSocketForTest; } 65 66 std::string GetPowerStateMarkerFilePath() const { 67 return std::string(mPowerStateMarkerFileForTest.path); 68 } 69 70 void SendDummyValueFromServer(); 71 72 void ExpectActivePropValueStreamNum(unsigned expected); 73 74 void WriteToPowerStateSocket(const std::string& val); 75 76 std::string ReadFromPowerStateMarkerFile() const; 77 78 private: 79 TemporaryDir mTestTempDir; 80 TemporaryFile mPowerStateMarkerFileForTest; 81 82 std::string mPowerStateSocketForTest{}; 83 84 GrpcVehicleServerPtr mGrpcServer{nullptr}; 85 VirtualizedVhalServerInfo mServerInfo; 86 }; 87 88 unsigned GrpcServerTest::GetTestCID() { 89 // TODO(chenhaosjtuacm): find a way to get the local CID 90 return 1000; 91 } 92 93 void GrpcServerTest::SendDummyValueFromServer() { 94 VehiclePropValue value; 95 value.prop = toInt(VehicleProperty::INVALID); 96 GetGrpcServer()->onPropertyValueFromCar(value, false); 97 } 98 99 void GrpcServerTest::ExpectActivePropValueStreamNum(unsigned expected) { 100 // Force the server to refresh streams 101 SendDummyValueFromServer(); 102 103 std::this_thread::sleep_for(std::chrono::seconds(1)); 104 EXPECT_EQ(GetGrpcServer()->NumOfActivePropertyValueStream(), expected); 105 } 106 107 void GrpcServerTest::WriteToPowerStateSocket(const std::string& val) { 108 int power_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); 109 ASSERT_GE(power_socket_fd, 0); 110 111 struct sockaddr_un addr; 112 std::memset(&addr, 0, sizeof(addr)); 113 addr.sun_family = AF_UNIX; 114 std::string socket_path = GetPowerStateSocketPath(); 115 std::strncpy(addr.sun_path, socket_path.c_str(), socket_path.length() + 1); 116 117 sync(); 118 119 ASSERT_EQ(connect(power_socket_fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), 0); 120 EXPECT_EQ(write(power_socket_fd, val.c_str(), val.length()), 121 static_cast<ssize_t>(val.length())); 122 close(power_socket_fd); 123 } 124 125 std::string GrpcServerTest::ReadFromPowerStateMarkerFile() const { 126 std::ifstream stream(GetPowerStateMarkerFilePath()); 127 std::string val; 128 stream >> val; 129 return val; 130 } 131 132 TEST_F(GrpcServerTest, PropertyValueStreamTest) { 133 ExpectActivePropValueStreamNum(0); 134 { 135 auto client1 = makeGrpcVehicleClient(GetGrpcServerUri()); 136 ExpectActivePropValueStreamNum(1); 137 { 138 auto client2 = makeGrpcVehicleClient(GetGrpcServerUri()); 139 ExpectActivePropValueStreamNum(2); 140 } 141 ExpectActivePropValueStreamNum(1); 142 } 143 ExpectActivePropValueStreamNum(0); 144 } 145 146 TEST_F(GrpcServerTest, PowerStateListenerTest) { 147 { 148 std::string power_state_str = "ok"; 149 WriteToPowerStateSocket(power_state_str); 150 std::this_thread::sleep_for(std::chrono::seconds(1)); 151 EXPECT_EQ(ReadFromPowerStateMarkerFile(), power_state_str); 152 } 153 154 { 155 std::string power_state_str = "shutdown"; 156 WriteToPowerStateSocket(power_state_str); 157 std::this_thread::sleep_for(std::chrono::seconds(1)); 158 EXPECT_EQ(ReadFromPowerStateMarkerFile(), power_state_str); 159 } 160 } 161 162 } // namespace android::hardware::automotive::vehicle::V2_0::impl 163