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:
GrpcServerTest()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
SetUp()46 void SetUp() override {
47 mGrpcServer = makeGrpcVehicleServer(mServerInfo);
48
49 ASSERT_TRUE(GetGrpcServer() != nullptr);
50 GetGrpcServer()->Start();
51 }
52
TearDown()53 void TearDown() override {
54 GetGrpcServer()->Stop().Wait();
55 mGrpcServer.reset();
56 }
57
58 static unsigned GetTestCID();
59
GetGrpcServer() const60 GrpcVehicleServer* GetGrpcServer() const { return mGrpcServer.get(); }
61
GetGrpcServerUri() const62 std::string GetGrpcServerUri() const { return mServerInfo.getServerUri(); }
63
GetPowerStateSocketPath() const64 std::string GetPowerStateSocketPath() const { return mPowerStateSocketForTest; }
65
GetPowerStateMarkerFilePath() const66 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
GetTestCID()88 unsigned GrpcServerTest::GetTestCID() {
89 // TODO(chenhaosjtuacm): find a way to get the local CID
90 return 1000;
91 }
92
SendDummyValueFromServer()93 void GrpcServerTest::SendDummyValueFromServer() {
94 VehiclePropValue value;
95 value.prop = toInt(VehicleProperty::INVALID);
96 GetGrpcServer()->onPropertyValueFromCar(value, false);
97 }
98
ExpectActivePropValueStreamNum(unsigned expected)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
WriteToPowerStateSocket(const std::string & val)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
ReadFromPowerStateMarkerFile() const125 std::string GrpcServerTest::ReadFromPowerStateMarkerFile() const {
126 std::ifstream stream(GetPowerStateMarkerFilePath());
127 std::string val;
128 stream >> val;
129 return val;
130 }
131
TEST_F(GrpcServerTest,PropertyValueStreamTest)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
TEST_F(GrpcServerTest,PowerStateListenerTest)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