| Index: net/tools/quic/quic_server_test.cc
|
| diff --git a/net/tools/quic/quic_server_test.cc b/net/tools/quic/quic_server_test.cc
|
| index d9acf8658f81ae168c436414335b3a37f0bc7eed..4d99cff5ac627e908844fa4a1cbe7b474258a392 100644
|
| --- a/net/tools/quic/quic_server_test.cc
|
| +++ b/net/tools/quic/quic_server_test.cc
|
| @@ -11,6 +11,7 @@
|
| #include "net/tools/quic/quic_epoll_alarm_factory.h"
|
| #include "net/tools/quic/quic_epoll_connection_helper.h"
|
| #include "net/tools/quic/quic_simple_server_session_helper.h"
|
| +#include "net/tools/quic/test_tools/quic_server_peer.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| using ::testing::_;
|
| @@ -22,6 +23,120 @@ namespace test {
|
|
|
| namespace {
|
|
|
| +class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
|
| + public:
|
| + MockQuicSimpleDispatcher(
|
| + const QuicConfig& config,
|
| + const QuicCryptoServerConfig* crypto_config,
|
| + QuicVersionManager* version_manager,
|
| + std::unique_ptr<QuicConnectionHelperInterface> helper,
|
| + std::unique_ptr<QuicServerSessionBase::Helper> session_helper,
|
| + std::unique_ptr<QuicAlarmFactory> alarm_factory)
|
| + : QuicSimpleDispatcher(config,
|
| + crypto_config,
|
| + version_manager,
|
| + std::move(helper),
|
| + std::move(session_helper),
|
| + std::move(alarm_factory)) {}
|
| + ~MockQuicSimpleDispatcher() override {}
|
| +
|
| + MOCK_METHOD0(OnCanWrite, void());
|
| + MOCK_CONST_METHOD0(HasPendingWrites, bool());
|
| + MOCK_CONST_METHOD0(HasChlosBuffered, bool());
|
| + MOCK_METHOD1(ProcessBufferedChlos, void(size_t));
|
| +};
|
| +
|
| +class TestQuicServer : public QuicServer {
|
| + public:
|
| + TestQuicServer() : QuicServer(CryptoTestUtils::ProofSourceForTesting()) {}
|
| +
|
| + ~TestQuicServer() override {}
|
| +
|
| + MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
|
| +
|
| + protected:
|
| + QuicDispatcher* CreateQuicDispatcher() override {
|
| + mock_dispatcher_ = new MockQuicSimpleDispatcher(
|
| + config(), &crypto_config(), version_manager(),
|
| + std::unique_ptr<QuicEpollConnectionHelper>(
|
| + new QuicEpollConnectionHelper(epoll_server(),
|
| + QuicAllocator::BUFFER_POOL)),
|
| + std::unique_ptr<QuicServerSessionBase::Helper>(
|
| + new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())),
|
| + std::unique_ptr<QuicEpollAlarmFactory>(
|
| + new QuicEpollAlarmFactory(epoll_server())));
|
| + return mock_dispatcher_;
|
| + }
|
| +
|
| + MockQuicSimpleDispatcher* mock_dispatcher_;
|
| +};
|
| +
|
| +class QuicServerEpollInTest : public ::testing::Test {
|
| + public:
|
| + QuicServerEpollInTest()
|
| + : port_(net::test::kTestPort), server_address_(Loopback4(), port_) {}
|
| +
|
| + void StartListening() {
|
| + server_.CreateUDPSocketAndListen(server_address_);
|
| + ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
|
| +
|
| + if (!server_.overflow_supported()) {
|
| + LOG(WARNING) << "Overflow not supported. Not testing.";
|
| + return;
|
| + }
|
| + }
|
| +
|
| + protected:
|
| + int port_;
|
| + IPEndPoint server_address_;
|
| + TestQuicServer server_;
|
| +};
|
| +
|
| +// Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
|
| +// event should try to create connections for them. And set epoll mask with
|
| +// EPOLLIN if there are still CHLOs remaining at the end of epoll event.
|
| +TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
|
| + FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true;
|
| + FLAGS_quic_buffer_packet_till_chlo = true;
|
| + // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
|
| + // event, dispatcher can't create session for all of CHLOs. So listener should
|
| + // register another EPOLLIN event by itself. Even without new packet arrival,
|
| + // the rest CHLOs should be process in next epoll event.
|
| + StartListening();
|
| + bool more_chlos = true;
|
| + MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
|
| + DCHECK(dispatcher_ != nullptr);
|
| + EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
|
| + EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
|
| + EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
|
| + // Expect there are still CHLOs buffered after 1st event. But not any more
|
| + // after 2nd event.
|
| + EXPECT_CALL(*dispatcher_, HasChlosBuffered())
|
| + .WillOnce(testing::Return(true))
|
| + .WillOnce(
|
| + DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
|
| +
|
| + // Send a packet to trigger epoll event.
|
| + int fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
|
| + ASSERT_LT(0, fd);
|
| +
|
| + char buf[1024];
|
| + memset(buf, 0, arraysize(buf));
|
| + sockaddr_storage storage;
|
| + socklen_t storage_size = sizeof(storage);
|
| + ASSERT_TRUE(server_address_.ToSockAddr(reinterpret_cast<sockaddr*>(&storage),
|
| + &storage_size));
|
| + int rc = sendto(fd, buf, arraysize(buf), 0,
|
| + reinterpret_cast<sockaddr*>(&storage), storage_size);
|
| + if (rc < 0) {
|
| + DVLOG(1) << errno << " " << strerror(errno);
|
| + }
|
| +
|
| + while (more_chlos) {
|
| + server_.WaitForEvents();
|
| + }
|
| +}
|
| +
|
| class QuicServerDispatchPacketTest : public ::testing::Test {
|
| public:
|
| QuicServerDispatchPacketTest()
|
|
|