15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace test {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(QuicWriteBlockedListTest, PriorityOrder) {
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicWriteBlockedList write_blocked_list;
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Mark streams blocked in roughly reverse priority order, and
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // verify that streams are sorted.
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(40,
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kLowestPriority);
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(23,
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(17,
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(kHeadersStreamId,
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(kCryptoStreamId,
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(5u, write_blocked_list.NumBlockedStreams());
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams());
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The Crypto stream is highest priority.
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kCryptoStreamId, write_blocked_list.PopFront());
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Followed by the Headers stream.
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront());
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Streams with same priority are popped in the order they were inserted.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(23u, write_blocked_list.PopFront());
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(17u, write_blocked_list.PopFront());
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Low priority stream appears last.
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(40u, write_blocked_list.PopFront());
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(QuicWriteBlockedListTest, CryptoStream) {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicWriteBlockedList write_blocked_list;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(kCryptoStreamId,
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kCryptoStreamId, write_blocked_list.PopFront());
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(QuicWriteBlockedListTest, HeadersStream) {
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicWriteBlockedList write_blocked_list;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_blocked_list.PushBack(kHeadersStreamId,
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront());
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(QuicWriteBlockedListTest, VerifyHeadersStream) {
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicWriteBlockedList write_blocked_list;
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  write_blocked_list.PushBack(5,
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  write_blocked_list.PushBack(kHeadersStreamId,
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams());
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // In newer QUIC versions, there is a headers stream which is
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // higher priority than data streams.
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront());
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5u, write_blocked_list.PopFront());
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST(QuicWriteBlockedListTest, NoDuplicateEntries) {
92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Test that QuicWriteBlockedList doesn't allow duplicate entries.
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  QuicWriteBlockedList write_blocked_list;
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Try to add a stream to the write blocked list multiple times at the same
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // priority.
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const QuicStreamId kBlockedId = kClientDataStreamId1;
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  write_blocked_list.PushBack(kBlockedId,
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  write_blocked_list.PushBack(kBlockedId,
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  write_blocked_list.PushBack(kBlockedId,
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              QuicWriteBlockedList::kHighestPriority);
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // This should only result in one blocked stream being added.
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams());
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // There should only be one stream to pop off the front.
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(kBlockedId, write_blocked_list.PopFront());
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace test
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
118