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