xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/fuchsia/host/socket/socket_channel_relay_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/fuchsia/host/socket/socket_channel_relay.h"
16 
17 #include <lib/async-loop/cpp/loop.h>
18 #include <lib/async-loop/default.h>
19 #include <pw_async_fuchsia/dispatcher.h>
20 
21 #include <memory>
22 #include <type_traits>
23 
24 #include "pw_bluetooth_sapphire/internal/host/common/assert.h"
25 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
26 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel.h"
27 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
28 #include "pw_unit_test/framework.h"
29 
30 namespace bt::socket {
31 namespace {
32 
33 // We'll test the template just for L2CAP channels.
34 using RelayT = SocketChannelRelay<l2cap::Channel>;
35 constexpr size_t kDefaultSocketWriteQueueLimitFrames = 2;
36 
37 class SocketChannelRelayTest : public ::testing::Test {
38  public:
SocketChannelRelayTest()39   SocketChannelRelayTest()
40       : loop_(&kAsyncLoopConfigAttachToCurrentThread),
41         pw_dispatcher_(dispatcher()) {
42     EXPECT_EQ(ASYNC_LOOP_RUNNABLE, loop_.GetState());
43 
44     constexpr l2cap::ChannelId kDynamicChannelIdMin = 0x0040;
45     constexpr l2cap::ChannelId kRemoteChannelId = 0x0050;
46     constexpr hci_spec::ConnectionHandle kDefaultConnectionHandle = 0x0001;
47     channel_ =
48         std::make_unique<l2cap::testing::FakeChannel>(kDynamicChannelIdMin,
49                                                       kRemoteChannelId,
50                                                       kDefaultConnectionHandle,
51                                                       bt::LinkType::kACL);
52 
53     const auto socket_status =
54         zx::socket::create(ZX_SOCKET_DATAGRAM, &local_socket_, &remote_socket_);
55     local_socket_unowned_ = zx::unowned_socket(local_socket_);
56     EXPECT_EQ(ZX_OK, socket_status);
57   }
58 
pw_dispatcher()59   pw::async::Dispatcher& pw_dispatcher() { return pw_dispatcher_; }
60 
61   // Writes data on |local_socket| until the socket is full, or an error occurs.
62   // Returns the number of bytes written if the socket fills, and zero
63   // otherwise.
StuffSocket()64   [[nodiscard]] size_t StuffSocket() {
65     size_t n_total_bytes_written = 0;
66     zx_status_t write_res;
67     // Fill the socket buffer completely, while minimzing the number of
68     // syscalls required.
69     for (const auto spam_size_bytes : {65536,
70                                        32768,
71                                        16384,
72                                        8192,
73                                        4096,
74                                        2048,
75                                        1024,
76                                        512,
77                                        256,
78                                        128,
79                                        64,
80                                        32,
81                                        16,
82                                        8,
83                                        4,
84                                        2,
85                                        1}) {
86       DynamicByteBuffer spam_data(spam_size_bytes);
87       spam_data.Fill(kSpamChar);
88       do {
89         size_t n_iter_bytes_written = 0;
90         write_res = local_socket_unowned_->write(
91             0, spam_data.data(), spam_data.size(), &n_iter_bytes_written);
92         if (write_res != ZX_OK && write_res != ZX_ERR_SHOULD_WAIT) {
93           bt_log(ERROR,
94                  "l2cap",
95                  "Failure in zx_socket_write(): %s",
96                  zx_status_get_string(write_res));
97           return 0;
98         }
99         n_total_bytes_written += n_iter_bytes_written;
100       } while (write_res == ZX_OK);
101     }
102     return n_total_bytes_written;
103   }
104 
105   // Reads and discards |n_bytes| on |remote_socket|. Returns true if at-least
106   // |n_bytes| were successfully discarded. (The actual number of discarded
107   // bytes is not known, as a pending datagram may be larger than our read
108   // buffer.)
DiscardFromSocket(size_t n_bytes_requested)109   [[nodiscard]] bool DiscardFromSocket(size_t n_bytes_requested) {
110     DynamicByteBuffer received_data(n_bytes_requested);
111     zx_status_t read_res;
112     size_t n_total_bytes_read = 0;
113     while (n_total_bytes_read < n_bytes_requested) {
114       size_t n_iter_bytes_read = 0;
115       read_res = remote_socket_.read(0,
116                                      received_data.mutable_data(),
117                                      received_data.size(),
118                                      &n_iter_bytes_read);
119       if (read_res != ZX_OK && read_res != ZX_ERR_SHOULD_WAIT) {
120         bt_log(ERROR,
121                "l2cap",
122                "Failure in zx_socket_read(): %s",
123                zx_status_get_string(read_res));
124         return false;
125       }
126       if (read_res == ZX_ERR_SHOULD_WAIT) {
127         EXPECT_EQ(n_bytes_requested, n_total_bytes_read);
128         return false;
129       } else {
130         n_total_bytes_read += n_iter_bytes_read;
131       }
132     }
133     return true;
134   }
135 
136  protected:
137   static constexpr auto kGoodChar = 'a';
138   static constexpr auto kSpamChar = 'b';
channel()139   l2cap::testing::FakeChannel* channel() { return channel_.get(); }
dispatcher()140   async_dispatcher_t* dispatcher() { return loop_.dispatcher(); }
local_socket()141   zx::socket* local_socket() { return &local_socket_; }
local_socket_unowned()142   zx::unowned_socket local_socket_unowned() {
143     return zx::unowned_socket(local_socket_unowned_);
144   }
remote_socket()145   zx::socket* remote_socket() { return &remote_socket_; }
ConsumeLocalSocket()146   zx::socket ConsumeLocalSocket() { return std::move(local_socket_); }
CloseRemoteSocket()147   void CloseRemoteSocket() { remote_socket_.reset(); }
148   // Note: A call to RunLoopOnce() may cause multiple timer-based tasks
149   // to be dispatched. (When the timer expires, async_loop_run_once() dispatches
150   // all expired timer-based tasks.)
RunLoopOnce()151   void RunLoopOnce() { loop_.Run(zx::time::infinite(), /*once=*/true); }
RunLoopUntilIdle()152   void RunLoopUntilIdle() { loop_.RunUntilIdle(); }
ShutdownLoop()153   void ShutdownLoop() { loop_.Shutdown(); }
154 
155  private:
156   std::unique_ptr<l2cap::testing::FakeChannel> channel_;
157   zx::socket local_socket_;
158   zx::socket remote_socket_;
159   zx::unowned_socket local_socket_unowned_;
160   // TODO(fxbug.dev/42150969): Move to FakeChannelTest, which wraps pw_async.
161   async::Loop loop_;
162   pw::async_fuchsia::FuchsiaDispatcher pw_dispatcher_;
163 };
164 
165 class SocketChannelRelayLifetimeTest : public SocketChannelRelayTest {
166  public:
SocketChannelRelayLifetimeTest()167   SocketChannelRelayLifetimeTest()
168       : was_deactivation_callback_invoked_(false),
169         relay_(std::make_unique<RelayT>(
170             ConsumeLocalSocket(), channel()->GetWeakPtr(), [this]() {
171               was_deactivation_callback_invoked_ = true;
172             })) {}
173 
174  protected:
was_deactivation_callback_invoked()175   bool was_deactivation_callback_invoked() {
176     return was_deactivation_callback_invoked_;
177   }
relay()178   RelayT* relay() {
179     PW_DCHECK(relay_);
180     return relay_.get();
181   }
DestroyRelay()182   void DestroyRelay() { relay_ = nullptr; }
183 
184  private:
185   bool was_deactivation_callback_invoked_;
186   std::unique_ptr<RelayT> relay_;
187 };
188 
TEST_F(SocketChannelRelayLifetimeTest,ActivateFailsIfGivenStoppedDispatcher)189 TEST_F(SocketChannelRelayLifetimeTest, ActivateFailsIfGivenStoppedDispatcher) {
190   ShutdownLoop();
191   EXPECT_FALSE(relay()->Activate());
192 }
193 
TEST_F(SocketChannelRelayLifetimeTest,ActivateDoesNotInvokeDeactivationCallbackOnSuccess)194 TEST_F(SocketChannelRelayLifetimeTest,
195        ActivateDoesNotInvokeDeactivationCallbackOnSuccess) {
196   ASSERT_TRUE(relay()->Activate());
197   EXPECT_FALSE(was_deactivation_callback_invoked());
198 }
199 
TEST_F(SocketChannelRelayLifetimeTest,ActivateDoesNotInvokeDeactivationCallbackOnFailure)200 TEST_F(SocketChannelRelayLifetimeTest,
201        ActivateDoesNotInvokeDeactivationCallbackOnFailure) {
202   ShutdownLoop();
203   ASSERT_FALSE(relay()->Activate());
204   EXPECT_FALSE(was_deactivation_callback_invoked());
205 }
206 
TEST_F(SocketChannelRelayLifetimeTest,SocketIsClosedWhenRelayIsDestroyed)207 TEST_F(SocketChannelRelayLifetimeTest, SocketIsClosedWhenRelayIsDestroyed) {
208   const char data = kGoodChar;
209   ASSERT_EQ(ZX_OK, remote_socket()->write(0, &data, sizeof(data), nullptr));
210   DestroyRelay();
211   EXPECT_EQ(ZX_ERR_PEER_CLOSED,
212             remote_socket()->write(0, &data, sizeof(data), nullptr));
213 }
214 
TEST_F(SocketChannelRelayLifetimeTest,RelayIsDeactivatedWhenDispatcherIsShutDown)215 TEST_F(SocketChannelRelayLifetimeTest,
216        RelayIsDeactivatedWhenDispatcherIsShutDown) {
217   ASSERT_TRUE(relay()->Activate());
218 
219   ShutdownLoop();
220   EXPECT_TRUE(was_deactivation_callback_invoked());
221 }
222 
TEST_F(SocketChannelRelayLifetimeTest,RelayActivationFailsIfChannelActivationFails)223 TEST_F(SocketChannelRelayLifetimeTest,
224        RelayActivationFailsIfChannelActivationFails) {
225   channel()->set_activate_fails(true);
226   EXPECT_FALSE(relay()->Activate());
227 }
228 
TEST_F(SocketChannelRelayLifetimeTest,DestructionWithPendingSdusFromChannelDoesNotCrash)229 TEST_F(SocketChannelRelayLifetimeTest,
230        DestructionWithPendingSdusFromChannelDoesNotCrash) {
231   ASSERT_TRUE(relay()->Activate());
232   channel()->Receive(StaticByteBuffer('h', 'e', 'l', 'l', 'o'));
233   DestroyRelay();
234   RunLoopUntilIdle();
235 }
236 
TEST_F(SocketChannelRelayLifetimeTest,RelayIsDeactivatedWhenChannelIsClosed)237 TEST_F(SocketChannelRelayLifetimeTest, RelayIsDeactivatedWhenChannelIsClosed) {
238   ASSERT_TRUE(relay()->Activate());
239 
240   channel()->Close();
241   EXPECT_TRUE(was_deactivation_callback_invoked());
242 }
243 
TEST_F(SocketChannelRelayLifetimeTest,RelayIsDeactivatedWhenRemoteSocketIsClosed)244 TEST_F(SocketChannelRelayLifetimeTest,
245        RelayIsDeactivatedWhenRemoteSocketIsClosed) {
246   ASSERT_TRUE(relay()->Activate());
247 
248   CloseRemoteSocket();
249   RunLoopUntilIdle();
250   EXPECT_TRUE(was_deactivation_callback_invoked());
251 }
252 
TEST_F(SocketChannelRelayLifetimeTest,RelayIsDeactivatedWhenRemoteSocketIsClosedEvenWithPendingSocketData)253 TEST_F(SocketChannelRelayLifetimeTest,
254        RelayIsDeactivatedWhenRemoteSocketIsClosedEvenWithPendingSocketData) {
255   ASSERT_TRUE(relay()->Activate());
256   ASSERT_TRUE(StuffSocket());
257 
258   channel()->Receive(StaticByteBuffer('h', 'e', 'l', 'l', 'o'));
259   RunLoopUntilIdle();
260   ASSERT_FALSE(was_deactivation_callback_invoked());
261 
262   CloseRemoteSocket();
263   RunLoopUntilIdle();
264   EXPECT_TRUE(was_deactivation_callback_invoked());
265 }
266 
TEST_F(SocketChannelRelayLifetimeTest,OversizedDatagramDeactivatesRelay)267 TEST_F(SocketChannelRelayLifetimeTest, OversizedDatagramDeactivatesRelay) {
268   const size_t kMessageBufSize = channel()->max_tx_sdu_size() * 5;
269   DynamicByteBuffer large_message(kMessageBufSize);
270   large_message.Fill('a');
271   ASSERT_TRUE(relay()->Activate());
272 
273   size_t n_bytes_written_to_socket = 0;
274   const auto write_res = remote_socket()->write(0,
275                                                 large_message.data(),
276                                                 large_message.size(),
277                                                 &n_bytes_written_to_socket);
278   ASSERT_EQ(ZX_OK, write_res);
279   ASSERT_EQ(large_message.size(), n_bytes_written_to_socket);
280   RunLoopUntilIdle();
281 
282   EXPECT_TRUE(was_deactivation_callback_invoked());
283 }
284 
TEST_F(SocketChannelRelayLifetimeTest,SocketClosureAfterChannelClosureDoesNotHangOrCrash)285 TEST_F(SocketChannelRelayLifetimeTest,
286        SocketClosureAfterChannelClosureDoesNotHangOrCrash) {
287   ASSERT_TRUE(relay()->Activate());
288   channel()->Close();
289   ASSERT_TRUE(was_deactivation_callback_invoked());
290 
291   CloseRemoteSocket();
292   RunLoopUntilIdle();
293 }
294 
TEST_F(SocketChannelRelayLifetimeTest,ChannelClosureAfterSocketClosureDoesNotHangOrCrash)295 TEST_F(SocketChannelRelayLifetimeTest,
296        ChannelClosureAfterSocketClosureDoesNotHangOrCrash) {
297   ASSERT_TRUE(relay()->Activate());
298   CloseRemoteSocket();
299   RunLoopUntilIdle();
300 
301   channel()->Close();
302   ASSERT_TRUE(was_deactivation_callback_invoked());
303 }
304 
TEST_F(SocketChannelRelayLifetimeTest,DeactivationClosesSocket)305 TEST_F(SocketChannelRelayLifetimeTest, DeactivationClosesSocket) {
306   ASSERT_TRUE(relay()->Activate());
307   channel()->Close();  // Triggers relay deactivation.
308 
309   const char data = kGoodChar;
310   EXPECT_EQ(ZX_ERR_PEER_CLOSED,
311             remote_socket()->write(0, &data, sizeof(data), nullptr));
312 }
313 
314 class SocketChannelRelayDataPathTest : public SocketChannelRelayTest {
315  public:
SocketChannelRelayDataPathTest()316   SocketChannelRelayDataPathTest()
317       : relay_(ConsumeLocalSocket(),
318                channel()->GetWeakPtr(),
319                /*deactivation_cb=*/nullptr,
320                kDefaultSocketWriteQueueLimitFrames) {
321     channel()->SetSendCallback(
322         [&](auto data) { sent_to_channel_.push_back(std::move(data)); },
323         pw_dispatcher());
324   }
325 
326  protected:
relay()327   RelayT* relay() { return &relay_; }
sent_to_channel()328   auto& sent_to_channel() { return sent_to_channel_; }
329 
330  private:
331   RelayT relay_;
332   std::vector<ByteBufferPtr> sent_to_channel_;
333 };
334 
335 // Fixture for tests which exercise the datapath from the controller.
336 class SocketChannelRelayRxTest : public SocketChannelRelayDataPathTest {
337  protected:
ReadDatagramFromSocket(const size_t dgram_len)338   DynamicByteBuffer ReadDatagramFromSocket(const size_t dgram_len) {
339     DynamicByteBuffer socket_read_buffer(dgram_len +
340                                          1);  // +1 to detect trailing garbage.
341     size_t n_bytes_read = 0;
342     const auto read_res =
343         remote_socket()->read(0,
344                               socket_read_buffer.mutable_data(),
345                               socket_read_buffer.size(),
346                               &n_bytes_read);
347     if (read_res != ZX_OK) {
348       bt_log(ERROR,
349              "l2cap",
350              "Failure in zx_socket_read(): %s",
351              zx_status_get_string(read_res));
352       return {};
353     }
354     return DynamicByteBuffer(BufferView(socket_read_buffer, n_bytes_read));
355   }
356 };
357 
TEST_F(SocketChannelRelayRxTest,MessageFromChannelIsCopiedToSocketSynchronously)358 TEST_F(SocketChannelRelayRxTest,
359        MessageFromChannelIsCopiedToSocketSynchronously) {
360   const StaticByteBuffer kExpectedMessage('h', 'e', 'l', 'l', 'o');
361   ASSERT_TRUE(relay()->Activate());
362   channel()->Receive(kExpectedMessage);
363   // The data should be copied synchronously, so the async loop should not be
364   // run here.
365   EXPECT_TRUE(ContainersEqual(kExpectedMessage,
366                               ReadDatagramFromSocket(kExpectedMessage.size())));
367 }
368 
TEST_F(SocketChannelRelayRxTest,MultipleSdusFromChannelAreCopiedToSocketPreservingSduBoundaries)369 TEST_F(SocketChannelRelayRxTest,
370        MultipleSdusFromChannelAreCopiedToSocketPreservingSduBoundaries) {
371   const StaticByteBuffer kExpectedMessage1('h', 'e', 'l', 'l', 'o');
372   const StaticByteBuffer kExpectedMessage2('g', 'o', 'o', 'd', 'b', 'y', 'e');
373   ASSERT_TRUE(relay()->Activate());
374   channel()->Receive(kExpectedMessage1);
375   channel()->Receive(kExpectedMessage2);
376   RunLoopUntilIdle();
377 
378   EXPECT_TRUE(ContainersEqual(
379       kExpectedMessage1, ReadDatagramFromSocket(kExpectedMessage1.size())));
380   EXPECT_TRUE(ContainersEqual(
381       kExpectedMessage2, ReadDatagramFromSocket(kExpectedMessage2.size())));
382 }
383 
TEST_F(SocketChannelRelayRxTest,SduFromChannelIsCopiedToSocketWhenSocketUnblocks)384 TEST_F(SocketChannelRelayRxTest,
385        SduFromChannelIsCopiedToSocketWhenSocketUnblocks) {
386   size_t n_junk_bytes = StuffSocket();
387   ASSERT_TRUE(n_junk_bytes);
388 
389   const StaticByteBuffer kExpectedMessage('h', 'e', 'l', 'l', 'o');
390   ASSERT_TRUE(relay()->Activate());
391   channel()->Receive(kExpectedMessage);
392   RunLoopUntilIdle();
393 
394   ASSERT_TRUE(DiscardFromSocket(n_junk_bytes));
395   RunLoopUntilIdle();
396   EXPECT_TRUE(ContainersEqual(kExpectedMessage,
397                               ReadDatagramFromSocket(kExpectedMessage.size())));
398 }
399 
TEST_F(SocketChannelRelayRxTest,CanQueueAndWriteMultipleSDUs)400 TEST_F(SocketChannelRelayRxTest, CanQueueAndWriteMultipleSDUs) {
401   size_t n_junk_bytes = StuffSocket();
402   ASSERT_TRUE(n_junk_bytes);
403 
404   const StaticByteBuffer kExpectedMessage1('h', 'e', 'l', 'l', 'o');
405   const StaticByteBuffer kExpectedMessage2('g', 'o', 'o', 'd', 'b', 'y', 'e');
406   ASSERT_TRUE(relay()->Activate());
407   channel()->Receive(kExpectedMessage1);
408   channel()->Receive(kExpectedMessage2);
409   RunLoopUntilIdle();
410 
411   ASSERT_TRUE(DiscardFromSocket(n_junk_bytes));
412   // Run only one task. This verifies that the relay writes both pending SDUs in
413   // one shot, rather than re-arming the async::Wait for each SDU.
414   RunLoopOnce();
415 
416   EXPECT_TRUE(ContainersEqual(
417       kExpectedMessage1, ReadDatagramFromSocket(kExpectedMessage1.size())));
418   EXPECT_TRUE(ContainersEqual(
419       kExpectedMessage2, ReadDatagramFromSocket(kExpectedMessage2.size())));
420 }
421 
TEST_F(SocketChannelRelayRxTest,CanQueueAndIncrementallyWriteMultipleSDUs)422 TEST_F(SocketChannelRelayRxTest, CanQueueAndIncrementallyWriteMultipleSDUs) {
423   // Find the socket buffer size.
424   const size_t socket_buffer_size = StuffSocket();
425   ASSERT_TRUE(DiscardFromSocket(socket_buffer_size));
426 
427   // Stuff the socket manually, rather than using StuffSocket(), so that we know
428   // exactly how much buffer space we free, as we read datagrams out of
429   // |remote_socket()|.
430   constexpr size_t kLargeSduSize = 1023;
431   zx_status_t write_res = ZX_ERR_INTERNAL;
432   DynamicByteBuffer spam_sdu(kLargeSduSize);
433   size_t n_junk_bytes = 0;
434   size_t n_junk_datagrams = 0;
435   spam_sdu.Fill('s');
436   do {
437     size_t n_iter_bytes_written = 0;
438     write_res = local_socket_unowned()->write(
439         0, spam_sdu.data(), spam_sdu.size(), &n_iter_bytes_written);
440     ASSERT_TRUE(write_res == ZX_OK || write_res == ZX_ERR_SHOULD_WAIT)
441         << "Failure in zx_socket_write: " << zx_status_get_string(write_res);
442     if (write_res == ZX_OK) {
443       ASSERT_EQ(spam_sdu.size(), n_iter_bytes_written);
444       n_junk_bytes += spam_sdu.size();
445       n_junk_datagrams += 1;
446     }
447   } while (write_res == ZX_OK);
448   ASSERT_NE(socket_buffer_size, n_junk_bytes)
449       << "Need non-zero free space in socket buffer.";
450 
451   DynamicByteBuffer hello_sdu(kLargeSduSize);
452   DynamicByteBuffer goodbye_sdu(kLargeSduSize);
453   hello_sdu.Fill('h');
454   goodbye_sdu.Fill('g');
455   ASSERT_TRUE(relay()->Activate());
456   channel()->Receive(hello_sdu);
457   channel()->Receive(goodbye_sdu);
458   RunLoopUntilIdle();
459 
460   // Free up space for just the first SDU.
461   ASSERT_TRUE(
462       ContainersEqual(spam_sdu, ReadDatagramFromSocket(spam_sdu.size())));
463   n_junk_datagrams -= 1;
464   RunLoopUntilIdle();
465 
466   // Free up space for just the second SDU.
467   ASSERT_TRUE(
468       ContainersEqual(spam_sdu, ReadDatagramFromSocket(spam_sdu.size())));
469   n_junk_datagrams -= 1;
470   RunLoopUntilIdle();
471 
472   // Discard spam.
473   while (n_junk_datagrams) {
474     ASSERT_TRUE(
475         ContainersEqual(spam_sdu, ReadDatagramFromSocket(spam_sdu.size())));
476     n_junk_datagrams -= 1;
477   }
478 
479   // Read out our expected datagrams, verifying that boundaries are preserved.
480   EXPECT_TRUE(
481       ContainersEqual(hello_sdu, ReadDatagramFromSocket(hello_sdu.size())));
482   EXPECT_TRUE(
483       ContainersEqual(goodbye_sdu, ReadDatagramFromSocket(goodbye_sdu.size())));
484   EXPECT_EQ(0u, ReadDatagramFromSocket(1u).size())
485       << "Found unexpected datagram";
486 }
487 
TEST_F(SocketChannelRelayRxTest,ZeroByteSDUsDropped)488 TEST_F(SocketChannelRelayRxTest, ZeroByteSDUsDropped) {
489   const StaticByteBuffer kMessage1('h', 'e', 'l', 'l', 'o');
490   DynamicByteBuffer kMessageZero(0);
491   const StaticByteBuffer kMessage3('f', 'u', 'c', 'h', 's', 'i', 'a');
492 
493   ASSERT_TRUE(relay()->Activate());
494   channel()->Receive(kMessageZero);
495   channel()->Receive(kMessage1);
496   channel()->Receive(kMessageZero);
497   channel()->Receive(kMessage3);
498   channel()->Receive(kMessageZero);
499   RunLoopUntilIdle();
500 
501   ASSERT_TRUE(
502       ContainersEqual(kMessage1, ReadDatagramFromSocket(kMessage1.size())));
503   ASSERT_TRUE(
504       ContainersEqual(kMessage3, ReadDatagramFromSocket(kMessage3.size())));
505 
506   EXPECT_EQ(0u, ReadDatagramFromSocket(1u).size())
507       << "Found unexpected datagram";
508 }
509 
TEST_F(SocketChannelRelayRxTest,OldestSDUIsDroppedOnOverflow)510 TEST_F(SocketChannelRelayRxTest, OldestSDUIsDroppedOnOverflow) {
511   size_t n_junk_bytes = StuffSocket();
512   ASSERT_TRUE(n_junk_bytes);
513 
514   const StaticByteBuffer kSentMessage1(1);
515   const StaticByteBuffer kSentMessage2(2);
516   const StaticByteBuffer kSentMessage3(3);
517   ASSERT_TRUE(relay()->Activate());
518   channel()->Receive(kSentMessage1);
519   channel()->Receive(kSentMessage2);
520   channel()->Receive(kSentMessage3);
521   RunLoopUntilIdle();
522 
523   ASSERT_TRUE(DiscardFromSocket(n_junk_bytes));
524   RunLoopUntilIdle();
525 
526   EXPECT_TRUE(ContainersEqual(kSentMessage2,
527                               ReadDatagramFromSocket(kSentMessage2.size())));
528   EXPECT_TRUE(ContainersEqual(kSentMessage3,
529                               ReadDatagramFromSocket(kSentMessage3.size())));
530 }
531 
TEST_F(SocketChannelRelayRxTest,SdusReceivedBeforeChannelActivationAreCopiedToSocket)532 TEST_F(SocketChannelRelayRxTest,
533        SdusReceivedBeforeChannelActivationAreCopiedToSocket) {
534   const StaticByteBuffer kExpectedMessage1('h', 'e', 'l', 'l', 'o');
535   const StaticByteBuffer kExpectedMessage2('g', 'o', 'o', 'd', 'b', 'y', 'e');
536   channel()->Receive(kExpectedMessage1);
537   channel()->Receive(kExpectedMessage2);
538   ASSERT_TRUE(relay()->Activate());
539   // Note: we omit RunLoopOnce()/RunLoopUntilIdle(), as Channel activation
540   // delivers the messages synchronously.
541 
542   EXPECT_TRUE(ContainersEqual(
543       kExpectedMessage1, ReadDatagramFromSocket(kExpectedMessage1.size())));
544   EXPECT_TRUE(ContainersEqual(
545       kExpectedMessage2, ReadDatagramFromSocket(kExpectedMessage2.size())));
546 }
547 
TEST_F(SocketChannelRelayRxTest,SdusPendingAtChannelClosureAreCopiedToSocket)548 TEST_F(SocketChannelRelayRxTest, SdusPendingAtChannelClosureAreCopiedToSocket) {
549   ASSERT_TRUE(StuffSocket());
550   ASSERT_TRUE(relay()->Activate());
551 
552   const StaticByteBuffer kExpectedMessage1('h');
553   const StaticByteBuffer kExpectedMessage2('i');
554   channel()->Receive(kExpectedMessage1);
555   channel()->Receive(kExpectedMessage2);
556   RunLoopUntilIdle();
557 
558   // Discard two datagrams from socket, to make room for our SDUs to be copied
559   // over.
560   ASSERT_NE(0u, ReadDatagramFromSocket(1u).size());
561   ASSERT_NE(0u, ReadDatagramFromSocket(1u).size());
562   channel()->Close();
563 
564   // Read past all of the spam from StuffSocket().
565   DynamicByteBuffer dgram;
566   do {
567     dgram = ReadDatagramFromSocket(1u);
568   } while (dgram.size() && dgram[0] == kSpamChar);
569 
570   // First non-spam message should be kExpectedMessage1, and second should be
571   // kExpectedMessage2.
572   EXPECT_TRUE(ContainersEqual(kExpectedMessage1, dgram));
573   EXPECT_TRUE(ContainersEqual(kExpectedMessage2, ReadDatagramFromSocket(1u)));
574 }
575 
TEST_F(SocketChannelRelayRxTest,ReceivingFromChannelBetweenSocketCloseAndCloseWaitTriggerDoesNotCrash)576 TEST_F(SocketChannelRelayRxTest,
577        ReceivingFromChannelBetweenSocketCloseAndCloseWaitTriggerDoesNotCrash) {
578   // Note: we call Channel::Receive() first, to force FakeChannel to deliver the
579   // SDU synchronously to the SocketChannelRelay. Asynchronous delivery could
580   // compromise the test's validity, since that would allow OnSocketClosed() to
581   // be invoked before OnChannelDataReceived().
582   channel()->Receive(StaticByteBuffer(kGoodChar));
583   CloseRemoteSocket();
584   ASSERT_TRUE(relay()->Activate());
585 }
586 
TEST_F(SocketChannelRelayRxTest,SocketCloseBetweenReceivingFromChannelAndSocketWritabilityDoesNotCrashOrHang)587 TEST_F(
588     SocketChannelRelayRxTest,
589     SocketCloseBetweenReceivingFromChannelAndSocketWritabilityDoesNotCrashOrHang) {
590   ASSERT_TRUE(relay()->Activate());
591 
592   size_t n_junk_bytes = StuffSocket();
593   ASSERT_TRUE(n_junk_bytes);
594   channel()->Receive(StaticByteBuffer(kGoodChar));
595   RunLoopUntilIdle();
596 
597   ASSERT_TRUE(DiscardFromSocket(n_junk_bytes));
598   CloseRemoteSocket();
599   RunLoopUntilIdle();
600 }
601 
TEST_F(SocketChannelRelayRxTest,NoDataFromChannelIsWrittenToSocketAfterDeactivation)602 TEST_F(SocketChannelRelayRxTest,
603        NoDataFromChannelIsWrittenToSocketAfterDeactivation) {
604   ASSERT_TRUE(relay()->Activate());
605 
606   size_t n_junk_bytes = StuffSocket();
607   ASSERT_TRUE(n_junk_bytes);
608 
609   channel()->Receive(StaticByteBuffer('h', 'e', 'l', 'l', 'o'));
610   RunLoopUntilIdle();
611 
612   channel()->Close();  // Triggers relay deactivation.
613   ASSERT_TRUE(DiscardFromSocket(n_junk_bytes));
614   RunLoopUntilIdle();
615 
616   zx_info_socket_t info = {};
617   info.rx_buf_available = std::numeric_limits<size_t>::max();
618   const auto status = remote_socket()->get_info(ZX_INFO_SOCKET,
619                                                 &info,
620                                                 sizeof(info),
621                                                 /*actual_count=*/nullptr,
622                                                 /*avail_count=*/nullptr);
623   EXPECT_EQ(ZX_OK, status);
624   EXPECT_EQ(0u, info.rx_buf_available);
625 }
626 
627 // Alias for the fixture for tests which exercise the datapath to the
628 // controller.
629 using SocketChannelRelayTxTest = SocketChannelRelayDataPathTest;
630 
TEST_F(SocketChannelRelayTxTest,SduFromSocketIsCopiedToChannel)631 TEST_F(SocketChannelRelayTxTest, SduFromSocketIsCopiedToChannel) {
632   const StaticByteBuffer kExpectedMessage('h', 'e', 'l', 'l', 'o');
633   ASSERT_TRUE(relay()->Activate());
634 
635   size_t n_bytes_written = 0;
636   const auto write_res = remote_socket()->write(
637       0, kExpectedMessage.data(), kExpectedMessage.size(), &n_bytes_written);
638   ASSERT_EQ(ZX_OK, write_res);
639   ASSERT_EQ(kExpectedMessage.size(), n_bytes_written);
640   RunLoopUntilIdle();
641 
642   const auto& sdus = sent_to_channel();
643   ASSERT_FALSE(sdus.empty());
644   EXPECT_EQ(1u, sdus.size());
645   ASSERT_TRUE(sdus[0]);
646   EXPECT_EQ(kExpectedMessage.size(), sdus[0]->size());
647   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[0]));
648 }
649 
TEST_F(SocketChannelRelayTxTest,MultipleSdusFromSocketAreCopiedToChannel)650 TEST_F(SocketChannelRelayTxTest, MultipleSdusFromSocketAreCopiedToChannel) {
651   const StaticByteBuffer kExpectedMessage('h', 'e', 'l', 'l', 'o');
652   const size_t kNumMessages = 3;
653   ASSERT_TRUE(relay()->Activate());
654 
655   for (size_t i = 0; i < kNumMessages; ++i) {
656     size_t n_bytes_written = 0;
657     const auto write_res = remote_socket()->write(
658         0, kExpectedMessage.data(), kExpectedMessage.size(), &n_bytes_written);
659     ASSERT_EQ(ZX_OK, write_res);
660     ASSERT_EQ(kExpectedMessage.size(), n_bytes_written);
661     RunLoopUntilIdle();
662   }
663 
664   const auto& sdus = sent_to_channel();
665   ASSERT_FALSE(sdus.empty());
666   ASSERT_EQ(3U, sdus.size());
667   ASSERT_TRUE(sdus[0]);
668   ASSERT_TRUE(sdus[1]);
669   ASSERT_TRUE(sdus[2]);
670   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[0]));
671   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[1]));
672   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[2]));
673 }
674 
TEST_F(SocketChannelRelayTxTest,MultipleSdusAreCopiedToChannelInOneRelayTask)675 TEST_F(SocketChannelRelayTxTest, MultipleSdusAreCopiedToChannelInOneRelayTask) {
676   const StaticByteBuffer kExpectedMessage('h', 'e', 'l', 'l', 'o');
677   const size_t kNumMessages = 3;
678   ASSERT_TRUE(relay()->Activate());
679 
680   for (size_t i = 0; i < kNumMessages; ++i) {
681     size_t n_bytes_written = 0;
682     const auto write_res = remote_socket()->write(
683         0, kExpectedMessage.data(), kExpectedMessage.size(), &n_bytes_written);
684     ASSERT_EQ(ZX_OK, write_res);
685     ASSERT_EQ(kExpectedMessage.size(), n_bytes_written);
686   }
687 
688   RunLoopOnce();  // Runs SocketChannelRelay::OnSocketReadable().
689   RunLoopOnce();  // Runs all tasks queued by FakeChannel::Send().
690 
691   const auto& sdus = sent_to_channel();
692   ASSERT_FALSE(sdus.empty());
693   ASSERT_EQ(3U, sdus.size());
694   ASSERT_TRUE(sdus[0]);
695   ASSERT_TRUE(sdus[1]);
696   ASSERT_TRUE(sdus[2]);
697   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[0]));
698   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[1]));
699   EXPECT_TRUE(ContainersEqual(kExpectedMessage, *sdus[2]));
700 }
701 
TEST_F(SocketChannelRelayTxTest,OversizedSduIsDropped)702 TEST_F(SocketChannelRelayTxTest, OversizedSduIsDropped) {
703   const size_t kMessageBufSize = channel()->max_tx_sdu_size() * 5;
704   DynamicByteBuffer large_message(kMessageBufSize);
705   large_message.Fill(kGoodChar);
706   ASSERT_TRUE(relay()->Activate());
707 
708   size_t n_bytes_written_to_socket = 0;
709   const auto write_res = remote_socket()->write(0,
710                                                 large_message.data(),
711                                                 large_message.size(),
712                                                 &n_bytes_written_to_socket);
713   ASSERT_EQ(ZX_OK, write_res);
714   ASSERT_EQ(large_message.size(), n_bytes_written_to_socket);
715   RunLoopUntilIdle();
716 
717   ASSERT_TRUE(sent_to_channel().empty());
718 }
719 
TEST_F(SocketChannelRelayTxTest,ValidSduAfterOversizedSduIsIgnored)720 TEST_F(SocketChannelRelayTxTest, ValidSduAfterOversizedSduIsIgnored) {
721   const StaticByteBuffer kSentMsg('h', 'e', 'l', 'l', 'o');
722   ASSERT_TRUE(relay()->Activate());
723 
724   {
725     DynamicByteBuffer dropped_msg(channel()->max_tx_sdu_size() + 1);
726     size_t n_bytes_written = 0;
727     zx_status_t write_res = ZX_ERR_INTERNAL;
728     dropped_msg.Fill(kGoodChar);
729     write_res = remote_socket()->write(
730         0, dropped_msg.data(), dropped_msg.size(), &n_bytes_written);
731     ASSERT_EQ(ZX_OK, write_res);
732     ASSERT_EQ(dropped_msg.size(), n_bytes_written);
733   }
734 
735   {
736     size_t n_bytes_written = 0;
737     zx_status_t write_res = ZX_ERR_INTERNAL;
738     write_res = remote_socket()->write(
739         0, kSentMsg.data(), kSentMsg.size(), &n_bytes_written);
740     ASSERT_EQ(ZX_OK, write_res);
741     ASSERT_EQ(kSentMsg.size(), n_bytes_written);
742   }
743 
744   RunLoopUntilIdle();
745   EXPECT_TRUE(sent_to_channel().empty());
746 }
747 
TEST_F(SocketChannelRelayTxTest,NewSocketDataAfterChannelClosureIsNotSentToChannel)748 TEST_F(SocketChannelRelayTxTest,
749        NewSocketDataAfterChannelClosureIsNotSentToChannel) {
750   ASSERT_TRUE(relay()->Activate());
751   channel()->Close();
752 
753   const char data = kGoodChar;
754   const auto write_res =
755       remote_socket()->write(0, &data, sizeof(data), /*actual=*/nullptr);
756   ASSERT_TRUE(write_res == ZX_OK || write_res == ZX_ERR_PEER_CLOSED)
757       << ": " << zx_status_get_string(write_res);
758   RunLoopUntilIdle();
759   EXPECT_TRUE(sent_to_channel().empty());
760 }
761 
TEST_F(SocketChannelRelayRxTest,DrainWriteQueueWhileSocketWritableWaitIsPending)762 TEST_F(SocketChannelRelayRxTest,
763        DrainWriteQueueWhileSocketWritableWaitIsPending) {
764   ASSERT_EQ(kDefaultSocketWriteQueueLimitFrames, 2u);
765   const StaticByteBuffer kSentMessage0(0);
766   const StaticByteBuffer kSentMessage1(1, 1, 1);
767   const StaticByteBuffer kSentMessage2(2);
768   const StaticByteBuffer kSentMessage3(3);
769 
770   // Make the first 2 datagrams 1 byte each so that we can discard exactly 2
771   // bytes after stuffing the socket.
772   size_t n_bytes_written = 0;
773   zx_status_t write_res = local_socket_unowned()->write(
774       0, kSentMessage0.data(), kSentMessage0.size(), &n_bytes_written);
775   ASSERT_EQ(write_res, ZX_OK);
776   ASSERT_EQ(n_bytes_written, 1u);
777   write_res = local_socket_unowned()->write(
778       0, kSentMessage0.data(), kSentMessage0.size(), &n_bytes_written);
779   ASSERT_EQ(write_res, ZX_OK);
780   ASSERT_EQ(n_bytes_written, 1u);
781 
782   size_t n_junk_bytes = StuffSocket();
783   ASSERT_TRUE(n_junk_bytes);
784 
785   ASSERT_TRUE(relay()->Activate());
786 
787   // Drain enough space for kSentMessage2 and kSentMessage3, but not
788   // kSentMessage1!
789   ASSERT_TRUE(DiscardFromSocket(2 * kSentMessage0.size()));
790 
791   // The kSentMessage1 is too big to write to the almost-stuffed socket. The
792   // packet will be queued, and the "socket writable" signal wait will start.
793   channel()->Receive(kSentMessage1);
794   // The second 1-byte packet that will fit into the socket is also queued.
795   channel()->Receive(kSentMessage2);
796   // When the third 1-byte packet is queued, kSentMessage1 will be dropped from
797   // the queue, allowing kSentMessage2 and kSendMessage3 to be written to the
798   // socket. The queue will be emptied.
799   channel()->Receive(kSentMessage3);
800 
801   // Allow any signals to be processed.
802   RunLoopUntilIdle();
803 
804   // Verify that kSentMessage2 and kSentMessage3 were actually written to the
805   // socket.
806   ASSERT_TRUE(DiscardFromSocket(n_junk_bytes));
807   RunLoopUntilIdle();
808   EXPECT_TRUE(ContainersEqual(kSentMessage2,
809                               ReadDatagramFromSocket(kSentMessage2.size())));
810   EXPECT_TRUE(ContainersEqual(kSentMessage3,
811                               ReadDatagramFromSocket(kSentMessage3.size())));
812 }
813 
814 }  // namespace
815 }  // namespace bt::socket
816