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