• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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