@@ -48,16 +48,14 @@ def before
48
48
# a
49
49
# /
50
50
# b
51
- begin
52
- a . priority = a . priority
53
- server . read_frame
54
-
55
- priority = b . priority
56
- priority . stream_dependency = a . id
57
- b . priority = priority
58
-
59
- server . read_frame
60
- end
51
+ a . priority = a . priority
52
+ server . read_frame
53
+
54
+ priority = b . priority
55
+ priority . stream_dependency = a . id
56
+ b . priority = priority
57
+
58
+ server . read_frame
61
59
62
60
expect ( a . dependency . children ) . to be == { b . id => b . dependency }
63
61
@@ -68,13 +66,11 @@ def before
68
66
# a
69
67
# / \
70
68
# b c
71
- begin
72
- priority = c . priority
73
- priority . stream_dependency = a . id
74
- c . priority = priority
75
-
76
- server . read_frame
77
- end
69
+ priority = c . priority
70
+ priority . stream_dependency = a . id
71
+ c . priority = priority
72
+
73
+ server . read_frame
78
74
79
75
expect ( a . dependency . children ) . to be == { b . id => b . dependency , c . id => c . dependency }
80
76
expect ( server . dependencies [ a . id ] . children ) . to be == { b . id => server . dependencies [ b . id ] , c . id => server . dependencies [ c . id ] }
@@ -84,14 +80,12 @@ def before
84
80
# d
85
81
# / \
86
82
# b c
87
- begin
88
- priority = d . priority
89
- priority . stream_dependency = a . id
90
- priority . exclusive = true
91
- d . priority = priority
92
-
93
- server . read_frame
94
- end
83
+ priority = d . priority
84
+ priority . stream_dependency = a . id
85
+ priority . exclusive = true
86
+ d . priority = priority
87
+
88
+ server . read_frame
95
89
96
90
expect ( a . dependency . children ) . to be == { d . id => d . dependency }
97
91
expect ( d . dependency . children ) . to be == { b . id => b . dependency , c . id => c . dependency }
@@ -163,36 +157,32 @@ def before
163
157
# b c
164
158
# |
165
159
# d
166
- begin
167
- a . priority = a . priority
168
- server . read_frame
169
-
170
- priority = b . priority
171
- priority . stream_dependency = a . id
172
- b . priority = priority
173
- server . read_frame
174
-
175
- priority = c . priority
176
- priority . stream_dependency = a . id
177
- c . priority = priority
178
- server . read_frame
179
-
180
- priority = d . priority
181
- priority . stream_dependency = c . id
182
- d . priority = priority
183
- server . read_frame
184
- end
160
+ a . priority = a . priority
161
+ server . read_frame
162
+
163
+ priority = b . priority
164
+ priority . stream_dependency = a . id
165
+ b . priority = priority
166
+ server . read_frame
167
+
168
+ priority = c . priority
169
+ priority . stream_dependency = a . id
170
+ c . priority = priority
171
+ server . read_frame
172
+
173
+ priority = d . priority
174
+ priority . stream_dependency = c . id
175
+ d . priority = priority
176
+ server . read_frame
185
177
186
178
expect ( server . dependencies [ a . id ] . children ) . to be == { b . id => server . dependencies [ b . id ] , c . id => server . dependencies [ c . id ] }
187
179
expect ( server . dependencies [ c . id ] . children ) . to be == { d . id => server . dependencies [ d . id ] }
188
180
189
181
# a
190
182
# / \
191
183
# b d
192
- begin
193
- c . send_reset_stream
194
- server . read_frame
195
- end
184
+ c . send_reset_stream
185
+ server . read_frame
196
186
197
187
expect ( server . dependencies [ a . id ] . children ) . to be == { b . id => server . dependencies [ b . id ] , d . id => server . dependencies [ d . id ] }
198
188
expect ( server . dependencies [ c . id ] ) . to be == nil
@@ -205,20 +195,18 @@ def before
205
195
# a
206
196
# / \
207
197
# b c
208
- begin
209
- a . priority = a . priority
210
- server . read_frame
211
-
212
- priority = b . priority
213
- priority . stream_dependency = a . id
214
- b . priority = priority
215
- server . read_frame
216
-
217
- priority = c . priority
218
- priority . stream_dependency = a . id
219
- c . priority = priority
220
- server . read_frame
221
- end
198
+ a . priority = a . priority
199
+ server . read_frame
200
+
201
+ priority = b . priority
202
+ priority . stream_dependency = a . id
203
+ b . priority = priority
204
+ server . read_frame
205
+
206
+ priority = c . priority
207
+ priority . stream_dependency = a . id
208
+ c . priority = priority
209
+ server . read_frame
222
210
223
211
a . dependency . print_hierarchy ( buffer )
224
212
@@ -228,4 +216,143 @@ def before
228
216
#<Protocol::HTTP2::Dependency id=5 parent id=1 weight=16 0 children>
229
217
END
230
218
end
219
+
220
+ it "can insert several children" do
221
+ a , b , c , d = 4 . times . collect { client . create_stream }
222
+
223
+ b . dependency . weight = 10
224
+ c . dependency . weight = 20
225
+ d . dependency . weight = 30
226
+
227
+ # a
228
+ # / | \
229
+ # b c d
230
+
231
+ a . priority = a . priority
232
+ server . read_frame
233
+
234
+ priority = d . priority
235
+ priority . stream_dependency = a . id
236
+ d . priority = priority
237
+ server . read_frame
238
+
239
+ # Force the ordered_children to be generated, so that we start triggering insertion logic:
240
+ ordered_children = server . dependencies [ a . id ] . ordered_children
241
+
242
+ priority = b . priority
243
+ priority . stream_dependency = a . id
244
+ b . priority = priority
245
+ server . read_frame
246
+
247
+ priority = c . priority
248
+ priority . stream_dependency = a . id
249
+ c . priority = priority
250
+ server . read_frame
251
+
252
+ expect ( ordered_children ) . to be == [ b . dependency , c . dependency , d . dependency ]
253
+ end
254
+
255
+ it "handles case where index is nil during insertion" do
256
+ a , b , c , d = 4 . times . collect { client . create_stream }
257
+
258
+ # Assign weights such that no existing child meets the condition:
259
+ b . dependency . weight = 5
260
+ c . dependency . weight = 10
261
+ d . dependency . weight = 15
262
+
263
+ # Priority tree setup:
264
+ # a
265
+ # /|\
266
+ # b c d
267
+
268
+ a . priority = a . priority
269
+ server . read_frame
270
+
271
+ priority = b . priority
272
+ priority . stream_dependency = a . id
273
+ b . priority = priority
274
+ server . read_frame
275
+
276
+ # Force the ordered_children to be generated, so that we start triggering insertion logic:
277
+ ordered_children = server . dependencies [ a . id ] . ordered_children
278
+
279
+ priority = c . priority
280
+ priority . stream_dependency = a . id
281
+ c . priority = priority
282
+ server . read_frame
283
+
284
+ priority = d . priority
285
+ priority . stream_dependency = a . id
286
+ d . priority = priority
287
+ server . read_frame
288
+
289
+ # Insert a new dependency with a weight that is higher than all current children:
290
+ new_child = client . create_stream
291
+ new_child . dependency . weight = 20 # Greater than the weights of b, c, and d
292
+
293
+ # Verify that `index` would have been `nil` when finding the insertion point:
294
+ index = ordered_children . bsearch_index { |child | child . weight >= new_child . dependency . weight }
295
+ expect ( index ) . to be_nil
296
+
297
+ priority = new_child . priority
298
+ priority . stream_dependency = a . id
299
+ new_child . priority = priority
300
+ server . read_frame
301
+
302
+ # Check that the new child is inserted at the correct place:
303
+ expect ( ordered_children ) . to be ( :include? , new_child . dependency )
304
+ expect ( ordered_children . last ) . to be == new_child . dependency
305
+ end
306
+
307
+ it "can update the weight of a child on removal" do
308
+ a , b , c , d = 4 . times . collect { client . create_stream }
309
+
310
+ # Assign weights such that no existing child meets the condition:
311
+ b . dependency . weight = 5
312
+ c . dependency . weight = 10
313
+ d . dependency . weight = 15
314
+
315
+ # Priority tree setup:
316
+ # a
317
+ # /|\
318
+ # b c d
319
+
320
+ a . priority = a . priority
321
+ server . read_frame
322
+
323
+ priority = b . priority
324
+ priority . stream_dependency = a . id
325
+ b . priority = priority
326
+ server . read_frame
327
+
328
+ # Force the ordered_children to be generated, so that we start triggering insertion logic:
329
+ ordered_children = server . dependencies [ a . id ] . ordered_children
330
+
331
+ priority = c . priority
332
+ priority . stream_dependency = a . id
333
+ c . priority = priority
334
+ server . read_frame
335
+
336
+ priority = d . priority
337
+ priority . stream_dependency = a . id
338
+ d . priority = priority
339
+ server . read_frame
340
+
341
+ expect ( ordered_children ) . to be == [ b . dependency , c . dependency , d . dependency ]
342
+
343
+ # Check the total weight makes sense:
344
+ expect ( server . dependencies [ a . id ] . total_weight ) . to be == 30
345
+
346
+ # Remove the child with the highest weight:
347
+ server . delete ( d . id )
348
+
349
+ # Check that the weight of the remaining children has been updated:
350
+ expect ( server . dependencies [ a . id ] . total_weight ) . to be == 15
351
+
352
+ # Force the deletion logic to clean up `ordered_children`:
353
+ server . dependencies [ a . id ] . consume_window ( 15 )
354
+
355
+ # Check that the child has been removed:
356
+ expect ( ordered_children ) . to be == [ b . dependency , c . dependency ]
357
+ end
231
358
end
0 commit comments