// Copyright (c) 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/quic/quic_multipath_received_packet_manager.h" #include "net/quic/quic_connection_stats.h" #include "net/quic/quic_flags.h" #include "net/quic/test_tools/quic_test_utils.h" #include "net/test/gtest_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using testing::Return; using testing::_; namespace net { namespace test { class QuicMultipathReceivedPacketManagerPeer { public: static bool PathReceivedPacketManagerExists( QuicMultipathReceivedPacketManager* multipath_manager, QuicPathId path_id) { return multipath_manager->path_managers_.count(path_id); } static void SetPathReceivedPacketManager( QuicMultipathReceivedPacketManager* multipath_manager, QuicPathId path_id, QuicReceivedPacketManager* manager) { delete multipath_manager->path_managers_[path_id]; multipath_manager->path_managers_[path_id] = manager; } }; namespace { const QuicPathId kPathId1 = 1; const QuicPathId kPathId2 = 2; const QuicPathId kPathId3 = 3; const QuicByteCount kBytes = 1350; class QuicMultipathReceivedPacketManagerTest : public testing::Test { public: QuicMultipathReceivedPacketManagerTest() : multipath_manager_(&stats_), manager_0_(new MockReceivedPacketManager(&stats_)), manager_1_(new MockReceivedPacketManager(&stats_)) { QuicMultipathReceivedPacketManagerPeer::SetPathReceivedPacketManager( &multipath_manager_, kDefaultPathId, manager_0_); QuicMultipathReceivedPacketManagerPeer::SetPathReceivedPacketManager( &multipath_manager_, kPathId1, manager_1_); } QuicConnectionStats stats_; QuicMultipathReceivedPacketManager multipath_manager_; MockReceivedPacketManager* manager_0_; MockReceivedPacketManager* manager_1_; QuicPacketHeader header_; }; TEST_F(QuicMultipathReceivedPacketManagerTest, OnPathCreatedAndClosed) { EXPECT_TRUE( QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists( &multipath_manager_, kDefaultPathId)); EXPECT_TRUE( QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists( &multipath_manager_, kPathId1)); EXPECT_DFATAL(multipath_manager_.OnPathCreated(kDefaultPathId, &stats_), "Received packet manager of path already exists"); // Path 2 created. multipath_manager_.OnPathCreated(kPathId2, &stats_); EXPECT_TRUE( QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists( &multipath_manager_, kPathId2)); EXPECT_FALSE( QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists( &multipath_manager_, kPathId3)); // Path 3 created. multipath_manager_.OnPathCreated(kPathId3, &stats_); EXPECT_TRUE( QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists( &multipath_manager_, kPathId3)); // Path 0 closed. multipath_manager_.OnPathClosed(kDefaultPathId); EXPECT_FALSE( QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists( &multipath_manager_, kDefaultPathId)); EXPECT_DFATAL(multipath_manager_.OnPathClosed(kDefaultPathId), "Received packet manager of path does not exist"); } TEST_F(QuicMultipathReceivedPacketManagerTest, RecordPacketReceived) { EXPECT_CALL(*manager_0_, RecordPacketReceived(_, _, _)).Times(1); multipath_manager_.RecordPacketReceived(kDefaultPathId, kBytes, header_, QuicTime::Zero()); EXPECT_DFATAL(multipath_manager_.RecordPacketReceived( kPathId2, kBytes, header_, QuicTime::Zero()), "Received a packet on a non-existent path"); } TEST_F(QuicMultipathReceivedPacketManagerTest, IsMissing) { EXPECT_CALL(*manager_0_, IsMissing(header_.packet_number)) .WillOnce(Return(true)); EXPECT_CALL(*manager_1_, IsMissing(header_.packet_number)) .WillOnce(Return(false)); EXPECT_TRUE( multipath_manager_.IsMissing(kDefaultPathId, header_.packet_number)); EXPECT_FALSE(multipath_manager_.IsMissing(kPathId1, header_.packet_number)); EXPECT_DFATAL(multipath_manager_.IsMissing(kPathId2, header_.packet_number), "Check whether a packet is missing on a non-existent path"); } TEST_F(QuicMultipathReceivedPacketManagerTest, IsAwaitingPacket) { EXPECT_CALL(*manager_0_, IsAwaitingPacket(header_.packet_number)) .WillOnce(Return(true)); EXPECT_CALL(*manager_1_, IsAwaitingPacket(header_.packet_number)) .WillOnce(Return(false)); EXPECT_TRUE(multipath_manager_.IsAwaitingPacket(kDefaultPathId, header_.packet_number)); EXPECT_FALSE( multipath_manager_.IsAwaitingPacket(kPathId1, header_.packet_number)); EXPECT_DFATAL( multipath_manager_.IsAwaitingPacket(kPathId2, header_.packet_number), "Check whether a packet is awaited on a non-existent path"); } TEST_F(QuicMultipathReceivedPacketManagerTest, UpdateReceivedPacketInfo) { FLAGS_quic_dont_copy_acks = false; std::vector ack_frames; EXPECT_EQ(static_cast(0), ack_frames.size()); EXPECT_CALL(*manager_0_, ack_frame_updated()).WillOnce(Return(false)); EXPECT_CALL(*manager_1_, ack_frame_updated()).WillRepeatedly(Return(false)); multipath_manager_.UpdateReceivedPacketInfo(&ack_frames, QuicTime::Zero(), /*force_all_paths=*/false); EXPECT_EQ(static_cast(0), ack_frames.size()); EXPECT_CALL(*manager_0_, ack_frame_updated()).WillOnce(Return(true)); multipath_manager_.UpdateReceivedPacketInfo(&ack_frames, QuicTime::Zero(), /*force_all_paths=*/false); EXPECT_EQ(static_cast(1), ack_frames.size()); std::vector ack_frames_all; multipath_manager_.UpdateReceivedPacketInfo(&ack_frames_all, QuicTime::Zero(), /*force_all_paths=*/true); EXPECT_EQ(static_cast(2), ack_frames_all.size()); } TEST_F(QuicMultipathReceivedPacketManagerTest, UpdatePacketInformationSentByPeer) { std::vector stop_waitings; QuicStopWaitingFrame stop_waiting_0; QuicStopWaitingFrame stop_waiting_1; QuicStopWaitingFrame stop_waiting_2; stop_waiting_0.path_id = kDefaultPathId; stop_waiting_1.path_id = kPathId1; stop_waiting_2.path_id = kPathId2; stop_waitings.push_back(stop_waiting_0); stop_waitings.push_back(stop_waiting_1); stop_waitings.push_back(stop_waiting_2); EXPECT_CALL(*manager_0_, UpdatePacketInformationSentByPeer(_)).Times(1); EXPECT_CALL(*manager_1_, UpdatePacketInformationSentByPeer(_)).Times(1); multipath_manager_.UpdatePacketInformationSentByPeer(stop_waitings); } TEST_F(QuicMultipathReceivedPacketManagerTest, HasNewMissingPackets) { EXPECT_CALL(*manager_0_, HasNewMissingPackets()).WillOnce(Return(true)); EXPECT_CALL(*manager_1_, HasNewMissingPackets()).WillOnce(Return(false)); EXPECT_TRUE(multipath_manager_.HasNewMissingPackets(kDefaultPathId)); EXPECT_FALSE(multipath_manager_.HasNewMissingPackets(kPathId1)); EXPECT_DFATAL(multipath_manager_.HasNewMissingPackets(kPathId2), "Check whether has new missing packets on a non-existent path"); } } // namespace } // namespace test } // namespace net