OLD | NEW |
| (Empty) |
1 // Copyright 2016 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/spdy/http2_priority_dependencies.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "testing/gmock/include/gmock/gmock.h" | |
10 #include "testing/platform_test.h" | |
11 | |
12 using ::testing::ContainerEq; | |
13 | |
14 namespace net { | |
15 | |
16 bool operator==(const Http2PriorityDependencies::DependencyUpdate& a, | |
17 const Http2PriorityDependencies::DependencyUpdate& b) { | |
18 return a.id == b.id && a.dependent_stream_id == b.dependent_stream_id && | |
19 a.exclusive == b.exclusive; | |
20 } | |
21 | |
22 std::ostream& operator<<( | |
23 std::ostream& os, | |
24 const std::vector<Http2PriorityDependencies::DependencyUpdate>& v) { | |
25 for (auto e : v) { | |
26 os << "{" << e.id << "," << e.dependent_stream_id << "," | |
27 << (e.exclusive ? "true" : "false") << "}"; | |
28 } | |
29 return os; | |
30 } | |
31 | |
32 class HttpPriorityDependencyTest : public PlatformTest { | |
33 public: | |
34 HttpPriorityDependencyTest() : next_id_(0u) {} | |
35 | |
36 // Fixed priority values to use for testing. | |
37 enum { | |
38 HIGHEST = kV3HighestPriority, | |
39 MEDIUM = HIGHEST + 1, | |
40 LOW = MEDIUM + 1, | |
41 LOWEST = kV3LowestPriority, | |
42 }; | |
43 | |
44 SpdyStreamId GetId() { return ++next_id_; } | |
45 | |
46 void TestStreamCreation(SpdyStreamId new_id, | |
47 SpdyPriority priority, | |
48 SpdyStreamId expected_dependent_id) { | |
49 SpdyStreamId dependent_id = 999u; | |
50 bool exclusive = false; | |
51 dependency_state_.OnStreamCreation(new_id, priority, &dependent_id, | |
52 &exclusive); | |
53 if (expected_dependent_id != dependent_id || !exclusive) { | |
54 ADD_FAILURE() << "OnStreamCreation(" << new_id << ", " << int(priority) | |
55 << ")\n" | |
56 << " Got: (" << dependent_id << ", " << exclusive << ")\n" | |
57 << " Want: (" << expected_dependent_id << ", true)\n"; | |
58 } | |
59 } | |
60 | |
61 struct ExpectedDependencyUpdate { | |
62 SpdyStreamId id; | |
63 SpdyStreamId parent_id; | |
64 }; | |
65 | |
66 void TestStreamUpdate(SpdyStreamId id, | |
67 SpdyPriority new_priority, | |
68 std::vector<ExpectedDependencyUpdate> expected) { | |
69 auto value = dependency_state_.OnStreamUpdate(id, new_priority); | |
70 std::vector<Http2PriorityDependencies::DependencyUpdate> expected_value; | |
71 for (auto e : expected) { | |
72 expected_value.push_back({e.id, e.parent_id, true /* exclusive */}); | |
73 } | |
74 if (value != expected_value) { | |
75 ADD_FAILURE() << "OnStreamUpdate(" << id << ", " << int(new_priority) | |
76 << ")\n" | |
77 << " Value: " << value << "\n" | |
78 << " Expected: " << expected_value << "\n"; | |
79 } | |
80 } | |
81 | |
82 void OnStreamDestruction(SpdyStreamId id) { | |
83 dependency_state_.OnStreamDestruction(id); | |
84 } | |
85 | |
86 private: | |
87 SpdyStreamId next_id_; | |
88 Http2PriorityDependencies dependency_state_; | |
89 }; | |
90 | |
91 // Confirm dependencies correct for entries at the same priority. | |
92 TEST_F(HttpPriorityDependencyTest, SamePriority) { | |
93 const SpdyStreamId first_id = GetId(); | |
94 const SpdyStreamId second_id = GetId(); | |
95 const SpdyStreamId third_id = GetId(); | |
96 | |
97 TestStreamCreation(first_id, MEDIUM, 0u); | |
98 TestStreamCreation(second_id, MEDIUM, first_id); | |
99 TestStreamCreation(third_id, MEDIUM, second_id); | |
100 } | |
101 | |
102 // Confirm dependencies correct for entries at different priorities, increasing. | |
103 TEST_F(HttpPriorityDependencyTest, DifferentPriorityIncreasing) { | |
104 const SpdyStreamId first_id = GetId(); | |
105 const SpdyStreamId second_id = GetId(); | |
106 const SpdyStreamId third_id = GetId(); | |
107 | |
108 TestStreamCreation(first_id, LOWEST, 0u); | |
109 TestStreamCreation(second_id, MEDIUM, 0u); | |
110 TestStreamCreation(third_id, HIGHEST, 0u); | |
111 } | |
112 | |
113 // Confirm dependencies correct for entries at different priorities, increasing. | |
114 TEST_F(HttpPriorityDependencyTest, DifferentPriorityDecreasing) { | |
115 const SpdyStreamId first_id = GetId(); | |
116 const SpdyStreamId second_id = GetId(); | |
117 const SpdyStreamId third_id = GetId(); | |
118 | |
119 TestStreamCreation(first_id, HIGHEST, 0u); | |
120 TestStreamCreation(second_id, MEDIUM, first_id); | |
121 TestStreamCreation(third_id, LOWEST, second_id); | |
122 } | |
123 | |
124 // Confirm dependencies correct if requests are completed between before | |
125 // next creation. | |
126 TEST_F(HttpPriorityDependencyTest, CompletionBeforeIssue) { | |
127 const SpdyStreamId first_id = GetId(); | |
128 const SpdyStreamId second_id = GetId(); | |
129 const SpdyStreamId third_id = GetId(); | |
130 | |
131 TestStreamCreation(first_id, HIGHEST, 0u); | |
132 OnStreamDestruction(first_id); | |
133 TestStreamCreation(second_id, MEDIUM, 0u); | |
134 OnStreamDestruction(second_id); | |
135 TestStreamCreation(third_id, LOWEST, 0u); | |
136 } | |
137 | |
138 // Confirm dependencies correct if some requests are completed between before | |
139 // next creation. | |
140 TEST_F(HttpPriorityDependencyTest, SomeCompletions) { | |
141 const SpdyStreamId first_id = GetId(); | |
142 const SpdyStreamId second_id = GetId(); | |
143 const SpdyStreamId third_id = GetId(); | |
144 | |
145 TestStreamCreation(first_id, HIGHEST, 0u); | |
146 TestStreamCreation(second_id, MEDIUM, first_id); | |
147 OnStreamDestruction(second_id); | |
148 TestStreamCreation(third_id, LOWEST, first_id); | |
149 } | |
150 | |
151 // A more complex example parallel to a simple web page. | |
152 TEST_F(HttpPriorityDependencyTest, Complex) { | |
153 const SpdyStreamId first_id = GetId(); | |
154 const SpdyStreamId second_id = GetId(); | |
155 const SpdyStreamId third_id = GetId(); | |
156 const SpdyStreamId fourth_id = GetId(); | |
157 const SpdyStreamId fifth_id = GetId(); | |
158 const SpdyStreamId sixth_id = GetId(); | |
159 const SpdyStreamId seventh_id = GetId(); | |
160 const SpdyStreamId eighth_id = GetId(); | |
161 const SpdyStreamId nineth_id = GetId(); | |
162 const SpdyStreamId tenth_id = GetId(); | |
163 | |
164 TestStreamCreation(first_id, HIGHEST, 0u); | |
165 TestStreamCreation(second_id, MEDIUM, first_id); | |
166 TestStreamCreation(third_id, MEDIUM, second_id); | |
167 OnStreamDestruction(first_id); | |
168 TestStreamCreation(fourth_id, MEDIUM, third_id); | |
169 TestStreamCreation(fifth_id, LOWEST, fourth_id); | |
170 TestStreamCreation(sixth_id, MEDIUM, fourth_id); | |
171 OnStreamDestruction(third_id); | |
172 TestStreamCreation(seventh_id, MEDIUM, sixth_id); | |
173 TestStreamCreation(eighth_id, LOW, seventh_id); | |
174 OnStreamDestruction(second_id); | |
175 OnStreamDestruction(fourth_id); | |
176 OnStreamDestruction(fifth_id); | |
177 OnStreamDestruction(sixth_id); | |
178 OnStreamDestruction(seventh_id); | |
179 TestStreamCreation(nineth_id, MEDIUM, 0u); | |
180 TestStreamCreation(tenth_id, HIGHEST, 0u); | |
181 } | |
182 | |
183 // Confirm dependencies correct after updates with just one stream. | |
184 // All updates are no-ops. | |
185 TEST_F(HttpPriorityDependencyTest, UpdateSingleStream) { | |
186 const SpdyStreamId id = GetId(); | |
187 | |
188 TestStreamCreation(id, HIGHEST, 0); | |
189 | |
190 std::vector<ExpectedDependencyUpdate> empty; | |
191 TestStreamUpdate(id, HIGHEST, empty); | |
192 TestStreamUpdate(id, MEDIUM, empty); | |
193 TestStreamUpdate(id, LOWEST, empty); | |
194 TestStreamUpdate(id, HIGHEST, empty); | |
195 } | |
196 | |
197 // Confirm dependencies correct after updates with three streams. | |
198 TEST_F(HttpPriorityDependencyTest, UpdateThreeStreams) { | |
199 const SpdyStreamId first_id = GetId(); | |
200 const SpdyStreamId second_id = GetId(); | |
201 const SpdyStreamId third_id = GetId(); | |
202 | |
203 TestStreamCreation(first_id, HIGHEST, 0); | |
204 TestStreamCreation(second_id, MEDIUM, first_id); | |
205 TestStreamCreation(third_id, LOWEST, second_id); | |
206 | |
207 std::vector<ExpectedDependencyUpdate> empty; | |
208 | |
209 // no-op: still at top. | |
210 TestStreamUpdate(first_id, HIGHEST, empty); | |
211 | |
212 // no-op: still below first. | |
213 TestStreamUpdate(second_id, MEDIUM, empty); | |
214 | |
215 // no-op: still below second. | |
216 TestStreamUpdate(third_id, LOWEST, empty); | |
217 | |
218 // second moves to top, first moves below second. | |
219 TestStreamUpdate(first_id, MEDIUM, {{second_id, 0}, {first_id, second_id}}); | |
220 | |
221 // third moves to top. | |
222 TestStreamUpdate(third_id, HIGHEST, {{third_id, 0}}); | |
223 | |
224 // third moves to bottom. | |
225 TestStreamUpdate(third_id, LOWEST, {{second_id, 0}, {third_id, first_id}}); | |
226 | |
227 // first moves to top. | |
228 TestStreamUpdate(first_id, HIGHEST, {{third_id, second_id}, {first_id, 0}}); | |
229 } | |
230 | |
231 // A more complex example parallel to a simple web page with pushed responses. | |
232 TEST_F(HttpPriorityDependencyTest, UpdateComplex) { | |
233 const SpdyStreamId first_id = GetId(); | |
234 const SpdyStreamId second_id = GetId(); // pushed | |
235 const SpdyStreamId third_id = GetId(); // pushed | |
236 const SpdyStreamId fourth_id = GetId(); | |
237 const SpdyStreamId fifth_id = GetId(); | |
238 const SpdyStreamId sixth_id = GetId(); | |
239 const SpdyStreamId seventh_id = GetId(); | |
240 | |
241 TestStreamCreation(first_id, HIGHEST, 0u); | |
242 TestStreamCreation(second_id, LOWEST, first_id); | |
243 TestStreamCreation(third_id, LOWEST, second_id); | |
244 TestStreamCreation(fourth_id, HIGHEST, first_id); | |
245 TestStreamCreation(fifth_id, MEDIUM, fourth_id); | |
246 TestStreamCreation(sixth_id, MEDIUM, fifth_id); | |
247 TestStreamCreation(seventh_id, LOW, sixth_id); | |
248 | |
249 // second matches a HIGHEST priority response. | |
250 // 3 moves under 7 | |
251 // 2 moves under 4 | |
252 TestStreamUpdate(second_id, HIGHEST, | |
253 {{third_id, seventh_id}, {second_id, fourth_id}}); | |
254 | |
255 // third matches a MEDIUM priority response. | |
256 // 3 moves under 6 | |
257 TestStreamUpdate(third_id, MEDIUM, {{third_id, sixth_id}}); | |
258 } | |
259 | |
260 } // namespace net | |
OLD | NEW |