1 /*
2 * Copyright 2020 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 "hal/snoop_logger_socket_thread.h"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <netinet/in.h>
22 #include <sys/socket.h>
23
24 #include <future>
25
26 #include "hal/snoop_logger_common.h"
27 #include "hal/syscall_wrapper_impl.h"
28 #include "os/utils.h"
29
30 namespace testing {
31
32 using bluetooth::hal::SnoopLoggerCommon;
33 using bluetooth::hal::SnoopLoggerSocket;
34 using bluetooth::hal::SnoopLoggerSocketThread;
35 using bluetooth::hal::SyscallWrapperImpl;
36
37 static constexpr int INVALID_FD = -1;
38
39 class SnoopLoggerSocketThreadModuleTest : public Test {};
40
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_start_no_stop_test)41 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_start_no_stop_test) {
42 {
43 SyscallWrapperImpl socket_if;
44 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
45 auto thread_start_future = sls.Start();
46 thread_start_future.wait();
47 ASSERT_TRUE(thread_start_future.get());
48 }
49
50 // Destructor calls Stop();
51 }
52
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_stop_no_start_test)53 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_stop_no_start_test) {
54 SyscallWrapperImpl socket_if;
55 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
56 sls.Stop();
57
58 ASSERT_FALSE(sls.ThreadIsRunning());
59 }
60
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_start_stop_test)61 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_start_stop_test) {
62 SyscallWrapperImpl socket_if;
63 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
64 auto thread_start_future = sls.Start();
65 thread_start_future.wait();
66 ASSERT_TRUE(thread_start_future.get());
67
68 sls.Stop();
69
70 ASSERT_FALSE(sls.ThreadIsRunning());
71 }
72
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_repeated_start_stop_test)73 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_repeated_start_stop_test) {
74 int repeat = 10;
75 {
76 SyscallWrapperImpl socket_if;
77 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
78
79 for (int i = 0; i < repeat; ++i) {
80 auto thread_start_future = sls.Start();
81 thread_start_future.wait();
82 ASSERT_TRUE(thread_start_future.get());
83
84 sls.Stop();
85
86 ASSERT_FALSE(sls.ThreadIsRunning());
87 }
88 }
89 }
90
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_connect_test)91 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_connect_test) {
92 int ret = 0;
93 SyscallWrapperImpl socket_if;
94 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
95 auto thread_start_future = sls.Start();
96 thread_start_future.wait();
97 ASSERT_TRUE(thread_start_future.get());
98
99 // // Create a TCP socket file descriptor
100 int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
101 ASSERT_TRUE(socket_fd != INVALID_FD);
102
103 struct sockaddr_in addr;
104 addr.sin_family = AF_INET;
105 addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_);
106 addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_);
107
108 // Connect to snoop logger socket
109 RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)));
110 ASSERT_EQ(0, ret);
111
112 sls.Stop();
113
114 ASSERT_FALSE(sls.ThreadIsRunning());
115 close(socket_fd);
116 }
117
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_connect_disconnect_test)118 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_connect_disconnect_test) {
119 int ret = 0;
120 SyscallWrapperImpl socket_if;
121 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
122 auto thread_start_future = sls.Start();
123 thread_start_future.wait();
124 ASSERT_TRUE(thread_start_future.get());
125
126 // // Create a TCP socket file descriptor
127 int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
128 ASSERT_TRUE(socket_fd != INVALID_FD);
129
130 struct sockaddr_in addr;
131 addr.sin_family = AF_INET;
132 addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_);
133 addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_);
134
135 // Connect to snoop logger socket
136 RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)));
137 ASSERT_EQ(0, ret);
138
139 // Close snoop logger socket
140 RUN_NO_INTR(ret = close(socket_fd));
141 ASSERT_EQ(0, ret);
142
143 sls.Stop();
144
145 ASSERT_FALSE(sls.ThreadIsRunning());
146 close(socket_fd);
147 }
148
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_send_no_start_test)149 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_send_no_start_test) {
150 SyscallWrapperImpl socket_if;
151 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
152
153 ASSERT_FALSE(sls.ThreadIsRunning());
154
155 sls.Write(&SnoopLoggerCommon::kBtSnoopFileHeader, sizeof(SnoopLoggerCommon::FileHeaderType));
156
157 ASSERT_FALSE(sls.ThreadIsRunning());
158 }
159
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_send_before_connect_test)160 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_send_before_connect_test) {
161 int ret = 0;
162 SyscallWrapperImpl socket_if;
163 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
164 auto thread_start_future = sls.Start();
165 thread_start_future.wait();
166 ASSERT_TRUE(thread_start_future.get());
167
168 char test_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
169 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0f};
170 sls.Write(test_data, sizeof(test_data));
171
172 // // Create a TCP socket file descriptor
173 int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
174 ASSERT_TRUE(socket_fd != INVALID_FD);
175
176 struct sockaddr_in addr;
177 addr.sin_family = AF_INET;
178 addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_);
179 addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_);
180
181 // Connect to snoop logger socket
182 RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)));
183 ASSERT_EQ(0, ret);
184
185 char recv_buf1[sizeof(SnoopLoggerCommon::FileHeaderType)];
186 char recv_buf2[sizeof(test_data)];
187 int bytes_read = -1;
188
189 auto a = std::async(std::launch::async, [socket_fd, &recv_buf1, &recv_buf2] {
190 recv(socket_fd, recv_buf1, sizeof(recv_buf1), 0);
191 return recv(socket_fd, recv_buf2, sizeof(recv_buf2), MSG_DONTWAIT);
192 });
193
194 sls.GetSocket()->WaitForClientSocketConnected();
195 a.wait();
196 bytes_read = a.get();
197 ASSERT_EQ(bytes_read, -1);
198 close(socket_fd);
199 }
200
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_recv_file_header_test)201 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_recv_file_header_test) {
202 int ret = 0;
203 SyscallWrapperImpl socket_if;
204 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
205 auto thread_start_future = sls.Start();
206 thread_start_future.wait();
207 ASSERT_TRUE(thread_start_future.get());
208
209 // // Create a TCP socket file descriptor
210 int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
211 ASSERT_TRUE(socket_fd != INVALID_FD);
212
213 struct sockaddr_in addr;
214 addr.sin_family = AF_INET;
215 addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_);
216 addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_);
217
218 // Connect to snoop logger socket
219 RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)));
220 ASSERT_EQ(0, ret);
221
222 char recv_buf[sizeof(SnoopLoggerCommon::FileHeaderType)];
223 int bytes_read = -1;
224
225 auto a = std::async(std::launch::async, [socket_fd, &recv_buf] {
226 return recv(socket_fd, recv_buf, sizeof(SnoopLoggerCommon::FileHeaderType), 0);
227 });
228
229 sls.GetSocket()->WaitForClientSocketConnected();
230
231 a.wait();
232 bytes_read = a.get();
233
234 ASSERT_EQ(bytes_read, static_cast<int>(sizeof(SnoopLoggerCommon::FileHeaderType)));
235 ASSERT_EQ(0, std::memcmp(recv_buf, &SnoopLoggerCommon::kBtSnoopFileHeader, bytes_read));
236 close(socket_fd);
237 }
238
TEST_F(SnoopLoggerSocketThreadModuleTest,socket_send_recv_test)239 TEST_F(SnoopLoggerSocketThreadModuleTest, socket_send_recv_test) {
240 int ret = 0;
241 SyscallWrapperImpl socket_if;
242 SnoopLoggerSocketThread sls(std::make_unique<SnoopLoggerSocket>(&socket_if));
243 auto thread_start_future = sls.Start();
244 thread_start_future.wait();
245 ASSERT_TRUE(thread_start_future.get());
246
247 // // Create a TCP socket file descriptor
248 int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
249 ASSERT_TRUE(socket_fd != INVALID_FD);
250
251 struct sockaddr_in addr;
252 addr.sin_family = AF_INET;
253 addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_);
254 addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_);
255
256 // Connect to snoop logger socket
257 RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)));
258 ASSERT_EQ(0, ret);
259
260 char test_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
261 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0f};
262
263 char recv_buf1[sizeof(SnoopLoggerCommon::FileHeaderType)];
264 char recv_buf2[sizeof(test_data)];
265 int bytes_read = -1;
266
267 auto a = std::async(std::launch::async, [socket_fd, &recv_buf1, &recv_buf2] {
268 recv(socket_fd, recv_buf1, sizeof(recv_buf1), 0);
269 return recv(socket_fd, recv_buf2, sizeof(recv_buf2), 0);
270 });
271
272 sls.GetSocket()->WaitForClientSocketConnected();
273
274 sls.Write(test_data, sizeof(test_data));
275 a.wait();
276 bytes_read = a.get();
277
278 ASSERT_EQ(0, std::memcmp(recv_buf1, &SnoopLoggerCommon::kBtSnoopFileHeader, sizeof(recv_buf1)));
279
280 ASSERT_EQ(bytes_read, static_cast<int>(sizeof(test_data)));
281 ASSERT_EQ(0, std::memcmp(recv_buf2, test_data, bytes_read));
282 close(socket_fd);
283 }
284
285 } // namespace testing
286