OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "net/quic/quic_write_blocked_list.h" | |
6 | |
7 #include "net/quic/test_tools/quic_test_utils.h" | |
8 #include "testing/gtest/include/gtest/gtest.h" | |
9 | |
10 using net::kV3LowestPriority; | |
11 using net::kV3HighestPriority; | |
12 | |
13 namespace net { | |
14 namespace test { | |
15 namespace { | |
16 | |
17 TEST(QuicWriteBlockedListTest, PriorityOrder) { | |
18 QuicWriteBlockedList write_blocked_list; | |
19 | |
20 // Mark streams blocked in roughly reverse priority order, and | |
21 // verify that streams are sorted. | |
22 write_blocked_list.RegisterStream(40, kV3LowestPriority); | |
23 write_blocked_list.RegisterStream(23, kV3HighestPriority); | |
24 write_blocked_list.RegisterStream(17, kV3HighestPriority); | |
25 write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority); | |
26 write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority); | |
27 | |
28 write_blocked_list.AddStream(40); | |
29 write_blocked_list.AddStream(23); | |
30 write_blocked_list.AddStream(17); | |
31 write_blocked_list.AddStream(kHeadersStreamId); | |
32 write_blocked_list.AddStream(kCryptoStreamId); | |
33 | |
34 EXPECT_EQ(5u, write_blocked_list.NumBlockedStreams()); | |
35 EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
36 EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams()); | |
37 // The Crypto stream is highest priority. | |
38 EXPECT_EQ(kCryptoStreamId, write_blocked_list.PopFront()); | |
39 // Followed by the Headers stream. | |
40 EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront()); | |
41 // Streams with same priority are popped in the order they were inserted. | |
42 EXPECT_EQ(23u, write_blocked_list.PopFront()); | |
43 EXPECT_EQ(17u, write_blocked_list.PopFront()); | |
44 // Low priority stream appears last. | |
45 EXPECT_EQ(40u, write_blocked_list.PopFront()); | |
46 | |
47 EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams()); | |
48 EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
49 EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams()); | |
50 } | |
51 | |
52 TEST(QuicWriteBlockedListTest, CryptoStream) { | |
53 QuicWriteBlockedList write_blocked_list; | |
54 write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority); | |
55 write_blocked_list.AddStream(kCryptoStreamId); | |
56 | |
57 EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams()); | |
58 EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
59 EXPECT_EQ(kCryptoStreamId, write_blocked_list.PopFront()); | |
60 EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams()); | |
61 EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
62 } | |
63 | |
64 TEST(QuicWriteBlockedListTest, HeadersStream) { | |
65 QuicWriteBlockedList write_blocked_list; | |
66 write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority); | |
67 write_blocked_list.AddStream(kHeadersStreamId); | |
68 | |
69 EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams()); | |
70 EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
71 EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront()); | |
72 EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams()); | |
73 EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
74 } | |
75 | |
76 TEST(QuicWriteBlockedListTest, VerifyHeadersStream) { | |
77 QuicWriteBlockedList write_blocked_list; | |
78 write_blocked_list.RegisterStream(5, kV3HighestPriority); | |
79 write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority); | |
80 write_blocked_list.AddStream(5); | |
81 write_blocked_list.AddStream(kHeadersStreamId); | |
82 | |
83 EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams()); | |
84 EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
85 EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams()); | |
86 // In newer QUIC versions, there is a headers stream which is | |
87 // higher priority than data streams. | |
88 EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront()); | |
89 EXPECT_EQ(5u, write_blocked_list.PopFront()); | |
90 EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams()); | |
91 EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream()); | |
92 EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams()); | |
93 } | |
94 | |
95 TEST(QuicWriteBlockedListTest, NoDuplicateEntries) { | |
96 // Test that QuicWriteBlockedList doesn't allow duplicate entries. | |
97 QuicWriteBlockedList write_blocked_list; | |
98 | |
99 // Try to add a stream to the write blocked list multiple times at the same | |
100 // priority. | |
101 const QuicStreamId kBlockedId = kClientDataStreamId1; | |
102 write_blocked_list.RegisterStream(kBlockedId, kV3HighestPriority); | |
103 write_blocked_list.AddStream(kBlockedId); | |
104 write_blocked_list.AddStream(kBlockedId); | |
105 write_blocked_list.AddStream(kBlockedId); | |
106 | |
107 // This should only result in one blocked stream being added. | |
108 EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams()); | |
109 EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams()); | |
110 | |
111 // There should only be one stream to pop off the front. | |
112 EXPECT_EQ(kBlockedId, write_blocked_list.PopFront()); | |
113 EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams()); | |
114 EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams()); | |
115 } | |
116 | |
117 TEST(QuicWriteBlockedListTest, BatchingWrites) { | |
118 QuicWriteBlockedList write_blocked_list; | |
119 | |
120 const QuicStreamId id1 = kClientDataStreamId1; | |
121 const QuicStreamId id2 = kClientDataStreamId2; | |
122 const QuicStreamId id3 = kClientDataStreamId2 + 2; | |
123 write_blocked_list.RegisterStream(id1, kV3LowestPriority); | |
124 write_blocked_list.RegisterStream(id2, kV3LowestPriority); | |
125 write_blocked_list.RegisterStream(id3, kV3HighestPriority); | |
126 | |
127 write_blocked_list.AddStream(id1); | |
128 write_blocked_list.AddStream(id2); | |
129 EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams()); | |
130 | |
131 // The first stream we push back should stay at the front until 16k is | |
132 // written. | |
133 EXPECT_EQ(id1, write_blocked_list.PopFront()); | |
134 write_blocked_list.UpdateBytesForStream(id1, 15999); | |
135 write_blocked_list.AddStream(id1); | |
136 EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams()); | |
137 EXPECT_EQ(id1, write_blocked_list.PopFront()); | |
138 | |
139 // Once 16k is written the first stream will yield to the next. | |
140 write_blocked_list.UpdateBytesForStream(id1, 1); | |
141 write_blocked_list.AddStream(id1); | |
142 EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams()); | |
143 EXPECT_EQ(id2, write_blocked_list.PopFront()); | |
144 | |
145 // Set the new stream to have written all but one byte. | |
146 write_blocked_list.UpdateBytesForStream(id2, 15999); | |
147 write_blocked_list.AddStream(id2); | |
148 EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams()); | |
149 | |
150 // Ensure higher priority streams are popped first. | |
151 write_blocked_list.AddStream(id3); | |
152 EXPECT_EQ(id3, write_blocked_list.PopFront()); | |
153 | |
154 // Higher priority streams will always be popped first, even if using their | |
155 // byte quota | |
156 write_blocked_list.UpdateBytesForStream(id3, 20000); | |
157 write_blocked_list.AddStream(id3); | |
158 EXPECT_EQ(id3, write_blocked_list.PopFront()); | |
159 | |
160 // Once the higher priority stream is out of the way, id2 will resume its 16k | |
161 // write, with only 1 byte remaining of its guaranteed write allocation. | |
162 EXPECT_EQ(id2, write_blocked_list.PopFront()); | |
163 write_blocked_list.AddStream(id2); | |
164 write_blocked_list.UpdateBytesForStream(id2, 1); | |
165 write_blocked_list.AddStream(id2); | |
166 EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams()); | |
167 EXPECT_EQ(id1, write_blocked_list.PopFront()); | |
168 } | |
169 | |
170 TEST(QuicWriteBlockedListTest, Ceding) { | |
171 QuicWriteBlockedList write_blocked_list; | |
172 | |
173 write_blocked_list.RegisterStream(15, kV3HighestPriority); | |
174 write_blocked_list.RegisterStream(16, kV3HighestPriority); | |
175 write_blocked_list.RegisterStream(5, 5); | |
176 write_blocked_list.RegisterStream(4, 5); | |
177 write_blocked_list.RegisterStream(7, 7); | |
178 write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority); | |
179 write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority); | |
180 | |
181 // When nothing is on the list, nothing yields. | |
182 EXPECT_FALSE(write_blocked_list.ShouldYield(5)); | |
183 | |
184 write_blocked_list.AddStream(5); | |
185 // 5 should not yield to itself. | |
186 EXPECT_FALSE(write_blocked_list.ShouldYield(5)); | |
187 // 4 and 7 are equal or lower priority and should yield to 5. | |
188 EXPECT_TRUE(write_blocked_list.ShouldYield(4)); | |
189 EXPECT_TRUE(write_blocked_list.ShouldYield(7)); | |
190 // 15, headers and crypto should preempt 5. | |
191 EXPECT_FALSE(write_blocked_list.ShouldYield(15)); | |
192 EXPECT_FALSE(write_blocked_list.ShouldYield(kHeadersStreamId)); | |
193 EXPECT_FALSE(write_blocked_list.ShouldYield(kCryptoStreamId)); | |
194 | |
195 // Block a high priority stream. | |
196 write_blocked_list.AddStream(15); | |
197 // 16 should yield (same priority) but headers and crypto will still not. | |
198 EXPECT_TRUE(write_blocked_list.ShouldYield(16)); | |
199 EXPECT_FALSE(write_blocked_list.ShouldYield(kHeadersStreamId)); | |
200 EXPECT_FALSE(write_blocked_list.ShouldYield(kCryptoStreamId)); | |
201 | |
202 // Block the headers stream. All streams but crypto and headers should yield. | |
203 write_blocked_list.AddStream(kHeadersStreamId); | |
204 EXPECT_TRUE(write_blocked_list.ShouldYield(16)); | |
205 EXPECT_TRUE(write_blocked_list.ShouldYield(15)); | |
206 EXPECT_FALSE(write_blocked_list.ShouldYield(kHeadersStreamId)); | |
207 EXPECT_FALSE(write_blocked_list.ShouldYield(kCryptoStreamId)); | |
208 | |
209 // Block the crypto stream. All streams but crypto should yield. | |
210 write_blocked_list.AddStream(kCryptoStreamId); | |
211 EXPECT_TRUE(write_blocked_list.ShouldYield(16)); | |
212 EXPECT_TRUE(write_blocked_list.ShouldYield(15)); | |
213 EXPECT_TRUE(write_blocked_list.ShouldYield(kHeadersStreamId)); | |
214 EXPECT_FALSE(write_blocked_list.ShouldYield(kCryptoStreamId)); | |
215 } | |
216 | |
217 } // namespace | |
218 } // namespace test | |
219 } // namespace net | |
OLD | NEW |