1 // Copyright (c) 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h"
6
7 #include "quiche/quic/platform/api/quic_test.h"
8 #include "quiche/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h"
9 #include "quiche/quic/qbone/mock_qbone_client.h"
10 #include "quiche/quic/qbone/platform/mock_kernel.h"
11
12 namespace quic::test {
13 namespace {
14
15 const size_t kMtu = 1000;
16 const size_t kMaxPendingPackets = 5;
17 const int kFd = 15;
18
19 using ::testing::_;
20 using ::testing::Invoke;
21 using ::testing::StrEq;
22 using ::testing::StrictMock;
23
24 class MockVisitor : public QbonePacketExchanger::Visitor {
25 public:
26 MOCK_METHOD(void, OnReadError, (const std::string&), (override));
27 MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
28 };
29
30 class TunDevicePacketExchangerTest : public QuicTest {
31 protected:
TunDevicePacketExchangerTest()32 TunDevicePacketExchangerTest()
33 : exchanger_(kMtu, &mock_kernel_, nullptr, &mock_visitor_,
34 kMaxPendingPackets, false, &mock_stats_,
35 absl::string_view()) {
36 exchanger_.set_file_descriptor(kFd);
37 }
38
39 ~TunDevicePacketExchangerTest() override = default;
40
41 MockKernel mock_kernel_;
42 StrictMock<MockVisitor> mock_visitor_;
43 StrictMock<MockQboneClient> mock_client_;
44 StrictMock<MockPacketExchangerStatsInterface> mock_stats_;
45 TunDevicePacketExchanger exchanger_;
46 };
47
TEST_F(TunDevicePacketExchangerTest,WritePacketReturnsFalseOnError)48 TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsFalseOnError) {
49 std::string packet = "fake packet";
50 EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
51 .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
52 errno = ECOMM;
53 return -1;
54 }));
55
56 EXPECT_CALL(mock_visitor_, OnWriteError(_));
57 exchanger_.WritePacketToNetwork(packet.data(), packet.size());
58 }
59
TEST_F(TunDevicePacketExchangerTest,WritePacketReturnFalseAndBlockedOnBlockedTunnel)60 TEST_F(TunDevicePacketExchangerTest,
61 WritePacketReturnFalseAndBlockedOnBlockedTunnel) {
62 std::string packet = "fake packet";
63 EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
64 .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
65 errno = EAGAIN;
66 return -1;
67 }));
68
69 EXPECT_CALL(mock_stats_, OnWriteError(_)).Times(1);
70 exchanger_.WritePacketToNetwork(packet.data(), packet.size());
71 }
72
TEST_F(TunDevicePacketExchangerTest,WritePacketReturnsTrueOnSuccessfulWrite)73 TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsTrueOnSuccessfulWrite) {
74 std::string packet = "fake packet";
75 EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
76 .WillOnce(Invoke([packet](int fd, const void* buf, size_t count) {
77 EXPECT_THAT(reinterpret_cast<const char*>(buf), StrEq(packet));
78 return count;
79 }));
80
81 EXPECT_CALL(mock_stats_, OnPacketWritten(_)).Times(1);
82 exchanger_.WritePacketToNetwork(packet.data(), packet.size());
83 }
84
TEST_F(TunDevicePacketExchangerTest,ReadPacketReturnsNullOnError)85 TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnError) {
86 EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
87 .WillOnce(Invoke([](int fd, void* buf, size_t count) {
88 errno = ECOMM;
89 return -1;
90 }));
91 EXPECT_CALL(mock_visitor_, OnReadError(_));
92 exchanger_.ReadAndDeliverPacket(&mock_client_);
93 }
94
TEST_F(TunDevicePacketExchangerTest,ReadPacketReturnsNullOnBlockedRead)95 TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnBlockedRead) {
96 EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
97 .WillOnce(Invoke([](int fd, void* buf, size_t count) {
98 errno = EAGAIN;
99 return -1;
100 }));
101 EXPECT_CALL(mock_stats_, OnReadError(_)).Times(1);
102 EXPECT_FALSE(exchanger_.ReadAndDeliverPacket(&mock_client_));
103 }
104
TEST_F(TunDevicePacketExchangerTest,ReadPacketReturnsThePacketOnSuccessfulRead)105 TEST_F(TunDevicePacketExchangerTest,
106 ReadPacketReturnsThePacketOnSuccessfulRead) {
107 std::string packet = "fake_packet";
108 EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
109 .WillOnce(Invoke([packet](int fd, void* buf, size_t count) {
110 memcpy(buf, packet.data(), packet.size());
111 return packet.size();
112 }));
113 EXPECT_CALL(mock_client_, ProcessPacketFromNetwork(StrEq(packet)));
114 EXPECT_CALL(mock_stats_, OnPacketRead(_)).Times(1);
115 EXPECT_TRUE(exchanger_.ReadAndDeliverPacket(&mock_client_));
116 }
117
118 } // namespace
119 } // namespace quic::test
120