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