github.com/metacubex/quic-go@v0.44.1-0.20240520163451-20b689a59136/frame_sorter_test.go (about) 1 package quic 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "time" 8 9 "golang.org/x/exp/rand" 10 11 "github.com/metacubex/quic-go/internal/protocol" 12 "github.com/metacubex/quic-go/internal/utils" 13 "github.com/metacubex/quic-go/internal/utils/tree" 14 15 . "github.com/onsi/ginkgo/v2" 16 . "github.com/onsi/gomega" 17 ) 18 19 var _ = Describe("frame sorter", func() { 20 var s *frameSorter 21 22 checkGaps := func(expectedGaps []byteInterval) { 23 if s.gapTree.Len() != len(expectedGaps) { 24 fmt.Println("Gaps:") 25 s.gapTree.Ascend(func(n *tree.Node[utils.ByteInterval], i int) bool { 26 gap := n.Value 27 fmt.Printf("\t%d - %d\n", gap.Start, gap.End) 28 return true 29 }) 30 ExpectWithOffset(1, s.gapTree.Len()).To(Equal(len(expectedGaps))) 31 } 32 var i int 33 s.gapTree.Ascend(func(n *tree.Node[utils.ByteInterval], _ int) bool { 34 gap := n.Value 35 ExpectWithOffset(1, gap).To(Equal(utils.ByteInterval{ 36 Start: expectedGaps[i].Start, 37 End: expectedGaps[i].End, 38 })) 39 i++ 40 return true 41 }) 42 } 43 44 type callbackTracker struct { 45 called *bool 46 cb func() 47 } 48 49 getCallback := func() (func(), callbackTracker) { 50 var called bool 51 cb := func() { 52 if called { 53 panic("double free") 54 } 55 called = true 56 } 57 return cb, callbackTracker{ 58 cb: cb, 59 called: &called, 60 } 61 } 62 63 checkCallbackCalled := func(t callbackTracker) { 64 ExpectWithOffset(1, *t.called).To(BeTrue()) 65 } 66 67 checkCallbackNotCalled := func(t callbackTracker) { 68 ExpectWithOffset(1, *t.called).To(BeFalse()) 69 t.cb() 70 ExpectWithOffset(1, *t.called).To(BeTrue()) 71 } 72 73 BeforeEach(func() { 74 s = newFrameSorter() 75 }) 76 77 It("returns nil when empty", func() { 78 _, data, doneCb := s.Pop() 79 Expect(data).To(BeNil()) 80 Expect(doneCb).To(BeNil()) 81 }) 82 83 It("inserts and pops a single frame", func() { 84 cb, t := getCallback() 85 Expect(s.Push([]byte("foobar"), 0, cb)).To(Succeed()) 86 offset, data, doneCb := s.Pop() 87 Expect(offset).To(BeZero()) 88 Expect(data).To(Equal([]byte("foobar"))) 89 Expect(doneCb).ToNot(BeNil()) 90 checkCallbackNotCalled(t) 91 offset, data, doneCb = s.Pop() 92 Expect(offset).To(Equal(protocol.ByteCount(6))) 93 Expect(data).To(BeNil()) 94 Expect(doneCb).To(BeNil()) 95 }) 96 97 It("inserts and pops two consecutive frame", func() { 98 cb1, t1 := getCallback() 99 cb2, t2 := getCallback() 100 Expect(s.Push([]byte("bar"), 3, cb2)).To(Succeed()) 101 Expect(s.Push([]byte("foo"), 0, cb1)).To(Succeed()) 102 offset, data, doneCb := s.Pop() 103 Expect(offset).To(BeZero()) 104 Expect(data).To(Equal([]byte("foo"))) 105 Expect(doneCb).ToNot(BeNil()) 106 doneCb() 107 checkCallbackCalled(t1) 108 offset, data, doneCb = s.Pop() 109 Expect(offset).To(Equal(protocol.ByteCount(3))) 110 Expect(data).To(Equal([]byte("bar"))) 111 Expect(doneCb).ToNot(BeNil()) 112 doneCb() 113 checkCallbackCalled(t2) 114 offset, data, doneCb = s.Pop() 115 Expect(offset).To(Equal(protocol.ByteCount(6))) 116 Expect(data).To(BeNil()) 117 Expect(doneCb).To(BeNil()) 118 }) 119 120 It("ignores empty frames", func() { 121 Expect(s.Push(nil, 0, nil)).To(Succeed()) 122 _, data, doneCb := s.Pop() 123 Expect(data).To(BeNil()) 124 Expect(doneCb).To(BeNil()) 125 }) 126 127 It("says if has more data", func() { 128 Expect(s.HasMoreData()).To(BeFalse()) 129 Expect(s.Push([]byte("foo"), 0, nil)).To(Succeed()) 130 Expect(s.HasMoreData()).To(BeTrue()) 131 _, data, _ := s.Pop() 132 Expect(data).To(Equal([]byte("foo"))) 133 Expect(s.HasMoreData()).To(BeFalse()) 134 }) 135 136 Context("Gap handling", func() { 137 var dataCounter uint8 138 139 BeforeEach(func() { 140 dataCounter = 0 141 }) 142 143 checkQueue := func(m map[protocol.ByteCount][]byte) { 144 ExpectWithOffset(1, s.queue).To(HaveLen(len(m))) 145 for offset, data := range m { 146 ExpectWithOffset(1, s.queue).To(HaveKey(offset)) 147 ExpectWithOffset(1, s.queue[offset].Data).To(Equal(data)) 148 } 149 } 150 151 getData := func(l protocol.ByteCount) []byte { 152 dataCounter++ 153 return bytes.Repeat([]byte{dataCounter}, int(l)) 154 } 155 156 // ---xxx-------------- 157 // ++++++ 158 // => 159 // ---xxx++++++-------- 160 It("case 1", func() { 161 f1 := getData(3) 162 cb1, t1 := getCallback() 163 f2 := getData(5) 164 cb2, t2 := getCallback() 165 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 166 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 11 167 checkQueue(map[protocol.ByteCount][]byte{ 168 3: f1, 169 6: f2, 170 }) 171 checkGaps([]byteInterval{ 172 {Start: 0, End: 3}, 173 {Start: 11, End: protocol.MaxByteCount}, 174 }) 175 checkCallbackNotCalled(t1) 176 checkCallbackNotCalled(t2) 177 }) 178 179 // ---xxx----------------- 180 // +++++++ 181 // => 182 // ---xxx---+++++++-------- 183 It("case 2", func() { 184 f1 := getData(3) 185 cb1, t1 := getCallback() 186 f2 := getData(5) 187 cb2, t2 := getCallback() 188 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 189 Expect(s.Push(f2, 10, cb2)).To(Succeed()) // 10 -15 190 checkQueue(map[protocol.ByteCount][]byte{ 191 3: f1, 192 10: f2, 193 }) 194 checkGaps([]byteInterval{ 195 {Start: 0, End: 3}, 196 {Start: 6, End: 10}, 197 {Start: 15, End: protocol.MaxByteCount}, 198 }) 199 checkCallbackNotCalled(t1) 200 checkCallbackNotCalled(t2) 201 }) 202 203 // ---xxx----xxxxxx------- 204 // ++++ 205 // => 206 // ---xxx++++xxxxx-------- 207 It("case 3", func() { 208 f1 := getData(3) 209 cb1, t1 := getCallback() 210 f2 := getData(4) 211 cb2, t2 := getCallback() 212 f3 := getData(5) 213 cb3, t3 := getCallback() 214 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 215 Expect(s.Push(f3, 10, cb2)).To(Succeed()) // 10 - 15 216 Expect(s.Push(f2, 6, cb3)).To(Succeed()) // 6 - 10 217 checkQueue(map[protocol.ByteCount][]byte{ 218 3: f1, 219 6: f2, 220 10: f3, 221 }) 222 checkGaps([]byteInterval{ 223 {Start: 0, End: 3}, 224 {Start: 15, End: protocol.MaxByteCount}, 225 }) 226 checkCallbackNotCalled(t1) 227 checkCallbackNotCalled(t2) 228 checkCallbackNotCalled(t3) 229 }) 230 231 // ----xxxx------- 232 // ++++ 233 // => 234 // ----xxxx++----- 235 It("case 4", func() { 236 f1 := getData(4) 237 cb1, t1 := getCallback() 238 f2 := getData(4) 239 cb2, t2 := getCallback() 240 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 7 241 Expect(s.Push(f2, 5, cb2)).To(Succeed()) // 5 - 9 242 checkQueue(map[protocol.ByteCount][]byte{ 243 3: f1, 244 7: f2[2:], 245 }) 246 checkGaps([]byteInterval{ 247 {Start: 0, End: 3}, 248 {Start: 9, End: protocol.MaxByteCount}, 249 }) 250 checkCallbackNotCalled(t1) 251 checkCallbackCalled(t2) 252 }) 253 254 It("case 4, for long frames", func() { 255 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 2)) 256 f1 := getData(4 * mult) 257 cb1, t1 := getCallback() 258 f2 := getData(4 * mult) 259 cb2, t2 := getCallback() 260 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 7 261 Expect(s.Push(f2, 5*mult, cb2)).To(Succeed()) // 5 - 9 262 checkQueue(map[protocol.ByteCount][]byte{ 263 3 * mult: f1, 264 7 * mult: f2[2*mult:], 265 }) 266 checkGaps([]byteInterval{ 267 {Start: 0, End: 3 * mult}, 268 {Start: 9 * mult, End: protocol.MaxByteCount}, 269 }) 270 checkCallbackNotCalled(t1) 271 checkCallbackNotCalled(t2) 272 }) 273 274 // xxxx------- 275 // ++++ 276 // => 277 // xxxx+++----- 278 It("case 5", func() { 279 f1 := getData(4) 280 cb1, t1 := getCallback() 281 f2 := getData(4) 282 cb2, t2 := getCallback() 283 Expect(s.Push(f1, 0, cb1)).To(Succeed()) // 0 - 4 284 Expect(s.Push(f2, 3, cb2)).To(Succeed()) // 3 - 7 285 checkQueue(map[protocol.ByteCount][]byte{ 286 0: f1, 287 4: f2[1:], 288 }) 289 checkGaps([]byteInterval{ 290 {Start: 7, End: protocol.MaxByteCount}, 291 }) 292 checkCallbackNotCalled(t1) 293 checkCallbackCalled(t2) 294 }) 295 296 It("case 5, for long frames", func() { 297 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 2)) 298 f1 := getData(4 * mult) 299 cb1, t1 := getCallback() 300 f2 := getData(4 * mult) 301 cb2, t2 := getCallback() 302 Expect(s.Push(f1, 0, cb1)).To(Succeed()) // 0 - 4 303 Expect(s.Push(f2, 3*mult, cb2)).To(Succeed()) // 3 - 7 304 checkQueue(map[protocol.ByteCount][]byte{ 305 0: f1, 306 4 * mult: f2[mult:], 307 }) 308 checkGaps([]byteInterval{ 309 {Start: 7 * mult, End: protocol.MaxByteCount}, 310 }) 311 checkCallbackNotCalled(t1) 312 checkCallbackNotCalled(t2) 313 }) 314 315 // ----xxxx------- 316 // ++++ 317 // => 318 // --++xxxx------- 319 It("case 6", func() { 320 f1 := getData(4) 321 cb1, t1 := getCallback() 322 f2 := getData(4) 323 cb2, t2 := getCallback() 324 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 9 325 Expect(s.Push(f2, 3, cb2)).To(Succeed()) // 3 - 7 326 checkQueue(map[protocol.ByteCount][]byte{ 327 3: f2[:2], 328 5: f1, 329 }) 330 checkGaps([]byteInterval{ 331 {Start: 0, End: 3}, 332 {Start: 9, End: protocol.MaxByteCount}, 333 }) 334 checkCallbackNotCalled(t1) 335 checkCallbackCalled(t2) 336 }) 337 338 It("case 6, for long frames", func() { 339 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 2)) 340 f1 := getData(4 * mult) 341 cb1, t1 := getCallback() 342 f2 := getData(4 * mult) 343 cb2, t2 := getCallback() 344 Expect(s.Push(f1, 5*mult, cb1)).To(Succeed()) // 5 - 9 345 Expect(s.Push(f2, 3*mult, cb2)).To(Succeed()) // 3 - 7 346 checkQueue(map[protocol.ByteCount][]byte{ 347 3 * mult: f2[:2*mult], 348 5 * mult: f1, 349 }) 350 checkGaps([]byteInterval{ 351 {Start: 0, End: 3 * mult}, 352 {Start: 9 * mult, End: protocol.MaxByteCount}, 353 }) 354 checkCallbackNotCalled(t1) 355 checkCallbackNotCalled(t2) 356 }) 357 358 // ---xxx----xxxxxx------- 359 // ++ 360 // => 361 // ---xxx++--xxxxx-------- 362 It("case 7", func() { 363 f1 := getData(3) 364 cb1, t1 := getCallback() 365 f2 := getData(2) 366 cb2, t2 := getCallback() 367 f3 := getData(5) 368 cb3, t3 := getCallback() 369 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 370 Expect(s.Push(f3, 10, cb2)).To(Succeed()) // 10 - 15 371 Expect(s.Push(f2, 6, cb3)).To(Succeed()) // 6 - 8 372 checkQueue(map[protocol.ByteCount][]byte{ 373 3: f1, 374 6: f2, 375 10: f3, 376 }) 377 checkGaps([]byteInterval{ 378 {Start: 0, End: 3}, 379 {Start: 8, End: 10}, 380 {Start: 15, End: protocol.MaxByteCount}, 381 }) 382 checkCallbackNotCalled(t1) 383 checkCallbackNotCalled(t2) 384 checkCallbackNotCalled(t3) 385 }) 386 387 // ---xxx---------xxxxxx-- 388 // ++ 389 // => 390 // ---xxx---++----xxxxx-- 391 It("case 8", func() { 392 f1 := getData(3) 393 cb1, t1 := getCallback() 394 f2 := getData(2) 395 cb2, t2 := getCallback() 396 f3 := getData(5) 397 cb3, t3 := getCallback() 398 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 399 Expect(s.Push(f3, 15, cb2)).To(Succeed()) // 15 - 20 400 Expect(s.Push(f2, 10, cb3)).To(Succeed()) // 10 - 12 401 checkQueue(map[protocol.ByteCount][]byte{ 402 3: f1, 403 10: f2, 404 15: f3, 405 }) 406 checkGaps([]byteInterval{ 407 {Start: 0, End: 3}, 408 {Start: 6, End: 10}, 409 {Start: 12, End: 15}, 410 {Start: 20, End: protocol.MaxByteCount}, 411 }) 412 checkCallbackNotCalled(t1) 413 checkCallbackNotCalled(t2) 414 checkCallbackNotCalled(t3) 415 }) 416 417 // ---xxx----xxxxxx------- 418 // ++ 419 // => 420 // ---xxx--++xxxxx-------- 421 It("case 9", func() { 422 f1 := getData(3) 423 cb1, t1 := getCallback() 424 f2 := getData(2) 425 cb2, t2 := getCallback() 426 cb3, t3 := getCallback() 427 f3 := getData(5) 428 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 429 Expect(s.Push(f3, 10, cb2)).To(Succeed()) // 10 - 15 430 Expect(s.Push(f2, 8, cb3)).To(Succeed()) // 8 - 10 431 checkQueue(map[protocol.ByteCount][]byte{ 432 3: f1, 433 8: f2, 434 10: f3, 435 }) 436 checkGaps([]byteInterval{ 437 {Start: 0, End: 3}, 438 {Start: 6, End: 8}, 439 {Start: 15, End: protocol.MaxByteCount}, 440 }) 441 checkCallbackNotCalled(t1) 442 checkCallbackNotCalled(t2) 443 checkCallbackNotCalled(t3) 444 }) 445 446 // ---xxx----=====------- 447 // +++++++ 448 // => 449 // ---xxx++++=====-------- 450 It("case 10", func() { 451 f1 := getData(3) 452 cb1, t1 := getCallback() 453 f2 := getData(5) 454 cb2, t2 := getCallback() 455 f3 := getData(6) 456 cb3, t3 := getCallback() 457 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 458 Expect(s.Push(f2, 10, cb2)).To(Succeed()) // 10 - 15 459 Expect(s.Push(f3, 5, cb3)).To(Succeed()) // 5 - 11 460 checkQueue(map[protocol.ByteCount][]byte{ 461 3: f1, 462 6: f3[1:5], 463 10: f2, 464 }) 465 checkGaps([]byteInterval{ 466 {Start: 0, End: 3}, 467 {Start: 15, End: protocol.MaxByteCount}, 468 }) 469 checkCallbackNotCalled(t1) 470 checkCallbackNotCalled(t2) 471 checkCallbackCalled(t3) 472 }) 473 474 It("case 10, for long frames", func() { 475 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 4)) 476 f1 := getData(3 * mult) 477 cb1, t1 := getCallback() 478 f2 := getData(5 * mult) 479 cb2, t2 := getCallback() 480 f3 := getData(6 * mult) 481 cb3, t3 := getCallback() 482 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 483 Expect(s.Push(f2, 10*mult, cb2)).To(Succeed()) // 10 - 15 484 Expect(s.Push(f3, 5*mult, cb3)).To(Succeed()) // 5 - 11 485 checkQueue(map[protocol.ByteCount][]byte{ 486 3 * mult: f1, 487 6 * mult: f3[mult : 5*mult], 488 10 * mult: f2, 489 }) 490 checkGaps([]byteInterval{ 491 {Start: 0, End: 3 * mult}, 492 {Start: 15 * mult, End: protocol.MaxByteCount}, 493 }) 494 checkCallbackNotCalled(t1) 495 checkCallbackNotCalled(t2) 496 checkCallbackNotCalled(t3) 497 }) 498 499 // ---xxxx----=====------- 500 // ++++++ 501 // => 502 // ---xxx++++=====-------- 503 It("case 11", func() { 504 f1 := getData(4) 505 cb1, t1 := getCallback() 506 f2 := getData(5) 507 cb2, t2 := getCallback() 508 f3 := getData(5) 509 cb3, t3 := getCallback() 510 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 7 511 Expect(s.Push(f2, 10, cb2)).To(Succeed()) // 10 - 15 512 Expect(s.Push(f3, 5, cb3)).To(Succeed()) // 5 - 10 513 checkQueue(map[protocol.ByteCount][]byte{ 514 3: f1, 515 7: f3[2:], 516 10: f2, 517 }) 518 checkGaps([]byteInterval{ 519 {Start: 0, End: 3}, 520 {Start: 15, End: protocol.MaxByteCount}, 521 }) 522 checkCallbackNotCalled(t1) 523 checkCallbackNotCalled(t2) 524 checkCallbackCalled(t3) 525 }) 526 527 // ---xxxx----=====------- 528 // ++++++ 529 // => 530 // ---xxx++++=====-------- 531 It("case 11, for long frames", func() { 532 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 3)) 533 f1 := getData(4 * mult) 534 cb1, t1 := getCallback() 535 f2 := getData(5 * mult) 536 cb2, t2 := getCallback() 537 f3 := getData(5 * mult) 538 cb3, t3 := getCallback() 539 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 7 540 Expect(s.Push(f2, 10*mult, cb2)).To(Succeed()) // 10 - 15 541 Expect(s.Push(f3, 5*mult, cb3)).To(Succeed()) // 5 - 10 542 checkQueue(map[protocol.ByteCount][]byte{ 543 3 * mult: f1, 544 7 * mult: f3[2*mult:], 545 10 * mult: f2, 546 }) 547 checkGaps([]byteInterval{ 548 {Start: 0, End: 3 * mult}, 549 {Start: 15 * mult, End: protocol.MaxByteCount}, 550 }) 551 checkCallbackNotCalled(t1) 552 checkCallbackNotCalled(t2) 553 checkCallbackNotCalled(t3) 554 }) 555 556 // ----xxxx------- 557 // +++++++ 558 // => 559 // ----+++++++----- 560 It("case 12", func() { 561 f1 := getData(4) 562 cb1, t1 := getCallback() 563 f2 := getData(7) 564 cb2, t2 := getCallback() 565 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 7 566 Expect(s.Push(f2, 3, cb2)).To(Succeed()) // 3 - 10 567 checkQueue(map[protocol.ByteCount][]byte{ 568 3: f2, 569 }) 570 checkGaps([]byteInterval{ 571 {Start: 0, End: 3}, 572 {Start: 10, End: protocol.MaxByteCount}, 573 }) 574 checkCallbackCalled(t1) 575 checkCallbackNotCalled(t2) 576 }) 577 578 // ----xxx===------- 579 // +++++++ 580 // => 581 // ----+++++++----- 582 It("case 13", func() { 583 f1 := getData(3) 584 cb1, t1 := getCallback() 585 f2 := getData(3) 586 cb2, t2 := getCallback() 587 f3 := getData(7) 588 cb3, t3 := getCallback() 589 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 590 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 9 591 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 10 592 checkQueue(map[protocol.ByteCount][]byte{ 593 3: f3, 594 }) 595 checkGaps([]byteInterval{ 596 {Start: 0, End: 3}, 597 {Start: 10, End: protocol.MaxByteCount}, 598 }) 599 checkCallbackCalled(t1) 600 checkCallbackCalled(t2) 601 checkCallbackNotCalled(t3) 602 }) 603 604 // ----xxx====------- 605 // +++++ 606 // => 607 // ----+++====----- 608 It("case 14", func() { 609 f1 := getData(3) 610 cb1, t1 := getCallback() 611 f2 := getData(4) 612 cb2, t2 := getCallback() 613 f3 := getData(5) 614 cb3, t3 := getCallback() 615 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 616 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 10 617 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 8 618 checkQueue(map[protocol.ByteCount][]byte{ 619 3: f3[:3], 620 6: f2, 621 }) 622 checkGaps([]byteInterval{ 623 {Start: 0, End: 3}, 624 {Start: 10, End: protocol.MaxByteCount}, 625 }) 626 checkCallbackCalled(t1) 627 checkCallbackNotCalled(t2) 628 checkCallbackCalled(t3) 629 }) 630 631 It("case 14, for long frames", func() { 632 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 3)) 633 f1 := getData(3 * mult) 634 cb1, t1 := getCallback() 635 f2 := getData(4 * mult) 636 cb2, t2 := getCallback() 637 f3 := getData(5 * mult) 638 cb3, t3 := getCallback() 639 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 640 Expect(s.Push(f2, 6*mult, cb2)).To(Succeed()) // 6 - 10 641 Expect(s.Push(f3, 3*mult, cb3)).To(Succeed()) // 3 - 8 642 checkQueue(map[protocol.ByteCount][]byte{ 643 3 * mult: f3[:3*mult], 644 6 * mult: f2, 645 }) 646 checkGaps([]byteInterval{ 647 {Start: 0, End: 3 * mult}, 648 {Start: 10 * mult, End: protocol.MaxByteCount}, 649 }) 650 checkCallbackCalled(t1) 651 checkCallbackNotCalled(t2) 652 checkCallbackNotCalled(t3) 653 }) 654 655 // ----xxx===------- 656 // ++++++ 657 // => 658 // ----++++++----- 659 It("case 15", func() { 660 f1 := getData(3) 661 cb1, t1 := getCallback() 662 f2 := getData(3) 663 cb2, t2 := getCallback() 664 f3 := getData(6) 665 cb3, t3 := getCallback() 666 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 667 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 9 668 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 9 669 checkQueue(map[protocol.ByteCount][]byte{ 670 3: f3, 671 }) 672 checkGaps([]byteInterval{ 673 {Start: 0, End: 3}, 674 {Start: 9, End: protocol.MaxByteCount}, 675 }) 676 checkCallbackCalled(t1) 677 checkCallbackCalled(t2) 678 checkCallbackNotCalled(t3) 679 }) 680 681 // ---xxxx------- 682 // ++++ 683 // => 684 // ---xxxx----- 685 It("case 16", func() { 686 f1 := getData(4) 687 cb1, t1 := getCallback() 688 f2 := getData(4) 689 cb2, t2 := getCallback() 690 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 9 691 Expect(s.Push(f2, 5, cb2)).To(Succeed()) // 5 - 9 692 checkQueue(map[protocol.ByteCount][]byte{ 693 5: f1, 694 }) 695 checkGaps([]byteInterval{ 696 {Start: 0, End: 5}, 697 {Start: 9, End: protocol.MaxByteCount}, 698 }) 699 checkCallbackNotCalled(t1) 700 checkCallbackCalled(t2) 701 }) 702 703 // ----xxx===------- 704 // +++ 705 // => 706 // ----xxx===----- 707 It("case 17", func() { 708 f1 := getData(3) 709 cb1, t1 := getCallback() 710 f2 := getData(3) 711 cb2, t2 := getCallback() 712 f3 := getData(3) 713 cb3, t3 := getCallback() 714 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 715 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 9 716 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 6 717 checkQueue(map[protocol.ByteCount][]byte{ 718 3: f1, 719 6: f2, 720 }) 721 checkGaps([]byteInterval{ 722 {Start: 0, End: 3}, 723 {Start: 9, End: protocol.MaxByteCount}, 724 }) 725 checkCallbackNotCalled(t1) 726 checkCallbackNotCalled(t2) 727 checkCallbackCalled(t3) 728 }) 729 730 // ---xxxx------- 731 // ++ 732 // => 733 // ---xxxx----- 734 It("case 18", func() { 735 f1 := getData(4) 736 cb1, t1 := getCallback() 737 f2 := getData(2) 738 cb2, t2 := getCallback() 739 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 9 740 Expect(s.Push(f2, 5, cb2)).To(Succeed()) // 5 - 7 741 checkQueue(map[protocol.ByteCount][]byte{ 742 5: f1, 743 }) 744 checkGaps([]byteInterval{ 745 {Start: 0, End: 5}, 746 {Start: 9, End: protocol.MaxByteCount}, 747 }) 748 checkCallbackNotCalled(t1) 749 checkCallbackCalled(t2) 750 }) 751 752 // ---xxxxx------ 753 // ++ 754 // => 755 // ---xxxxx---- 756 It("case 19", func() { 757 f1 := getData(5) 758 cb1, t1 := getCallback() 759 f2 := getData(2) 760 cb2, t2 := getCallback() 761 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 10 762 checkQueue(map[protocol.ByteCount][]byte{ 763 5: f1, 764 }) 765 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 8 766 checkQueue(map[protocol.ByteCount][]byte{ 767 5: f1, 768 }) 769 checkGaps([]byteInterval{ 770 {Start: 0, End: 5}, 771 {Start: 10, End: protocol.MaxByteCount}, 772 }) 773 checkCallbackNotCalled(t1) 774 checkCallbackCalled(t2) 775 }) 776 777 // xxxxx------ 778 // ++ 779 // => 780 // xxxxx------ 781 It("case 20", func() { 782 f1 := getData(10) 783 cb1, t1 := getCallback() 784 f2 := getData(4) 785 cb2, t2 := getCallback() 786 Expect(s.Push(f1, 0, cb1)).To(Succeed()) // 0 - 10 787 Expect(s.Push(f2, 5, cb2)).To(Succeed()) // 5 - 9 788 checkQueue(map[protocol.ByteCount][]byte{ 789 0: f1, 790 }) 791 checkGaps([]byteInterval{ 792 {Start: 10, End: protocol.MaxByteCount}, 793 }) 794 checkCallbackNotCalled(t1) 795 checkCallbackCalled(t2) 796 }) 797 798 // ---xxxxx--- 799 // +++ 800 // => 801 // ---xxxxx--- 802 It("case 21", func() { 803 f1 := getData(5) 804 cb1, t1 := getCallback() 805 f2 := getData(3) 806 cb2, t2 := getCallback() 807 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 10 808 Expect(s.Push(f2, 7, cb2)).To(Succeed()) // 7 - 10 809 checkGaps([]byteInterval{ 810 {Start: 0, End: 5}, 811 {Start: 10, End: protocol.MaxByteCount}, 812 }) 813 checkQueue(map[protocol.ByteCount][]byte{ 814 5: f1, 815 }) 816 checkCallbackNotCalled(t1) 817 checkCallbackCalled(t2) 818 }) 819 820 // ----xxx------ 821 // +++++ 822 // => 823 // --+++++---- 824 It("case 22", func() { 825 f1 := getData(3) 826 cb1, t1 := getCallback() 827 f2 := getData(5) 828 cb2, t2 := getCallback() 829 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 8 830 Expect(s.Push(f2, 3, cb2)).To(Succeed()) // 3 - 8 831 checkQueue(map[protocol.ByteCount][]byte{ 832 3: f2, 833 }) 834 checkGaps([]byteInterval{ 835 {Start: 0, End: 3}, 836 {Start: 8, End: protocol.MaxByteCount}, 837 }) 838 checkCallbackCalled(t1) 839 checkCallbackNotCalled(t2) 840 }) 841 842 // ----xxx===------ 843 // ++++++++ 844 // => 845 // --++++++++---- 846 It("case 23", func() { 847 f1 := getData(3) 848 cb1, t1 := getCallback() 849 f2 := getData(3) 850 cb2, t2 := getCallback() 851 f3 := getData(8) 852 cb3, t3 := getCallback() 853 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 8 854 Expect(s.Push(f2, 8, cb2)).To(Succeed()) // 8 - 11 855 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 11 856 checkQueue(map[protocol.ByteCount][]byte{ 857 3: f3, 858 }) 859 checkGaps([]byteInterval{ 860 {Start: 0, End: 3}, 861 {Start: 11, End: protocol.MaxByteCount}, 862 }) 863 checkCallbackCalled(t1) 864 checkCallbackCalled(t2) 865 checkCallbackNotCalled(t3) 866 }) 867 868 // --xxx---===--- 869 // ++++++ 870 // => 871 // --xxx++++++---- 872 It("case 24", func() { 873 f1 := getData(3) 874 cb1, t1 := getCallback() 875 f2 := getData(3) 876 cb2, t2 := getCallback() 877 f3 := getData(6) 878 cb3, t3 := getCallback() 879 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 880 Expect(s.Push(f2, 9, cb2)).To(Succeed()) // 9 - 12 881 Expect(s.Push(f3, 6, cb3)).To(Succeed()) // 6 - 12 882 checkQueue(map[protocol.ByteCount][]byte{ 883 3: f1, 884 6: f3, 885 }) 886 checkGaps([]byteInterval{ 887 {Start: 0, End: 3}, 888 {Start: 12, End: protocol.MaxByteCount}, 889 }) 890 checkCallbackNotCalled(t1) 891 checkCallbackCalled(t2) 892 checkCallbackNotCalled(t3) 893 }) 894 895 // --xxx---===---### 896 // +++++++++ 897 // => 898 // --xxx+++++++++### 899 It("case 25", func() { 900 f1 := getData(3) 901 cb1, t1 := getCallback() 902 f2 := getData(3) 903 cb2, t2 := getCallback() 904 f3 := getData(3) 905 cb3, t3 := getCallback() 906 f4 := getData(9) 907 cb4, t4 := getCallback() 908 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 909 Expect(s.Push(f2, 9, cb2)).To(Succeed()) // 9 - 12 910 Expect(s.Push(f3, 15, cb3)).To(Succeed()) // 15 - 18 911 Expect(s.Push(f4, 6, cb4)).To(Succeed()) // 6 - 15 912 checkQueue(map[protocol.ByteCount][]byte{ 913 3: f1, 914 6: f4, 915 15: f3, 916 }) 917 checkGaps([]byteInterval{ 918 {Start: 0, End: 3}, 919 {Start: 18, End: protocol.MaxByteCount}, 920 }) 921 checkCallbackNotCalled(t1) 922 checkCallbackCalled(t2) 923 checkCallbackNotCalled(t3) 924 checkCallbackNotCalled(t4) 925 }) 926 927 // ----xxx------ 928 // +++++++ 929 // => 930 // --+++++++--- 931 It("case 26", func() { 932 f1 := getData(3) 933 cb1, t1 := getCallback() 934 f2 := getData(10) 935 cb2, t2 := getCallback() 936 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 8 937 Expect(s.Push(f2, 3, cb2)).To(Succeed()) // 3 - 13 938 checkQueue(map[protocol.ByteCount][]byte{ 939 3: f2, 940 }) 941 checkGaps([]byteInterval{ 942 {Start: 0, End: 3}, 943 {Start: 13, End: protocol.MaxByteCount}, 944 }) 945 checkCallbackCalled(t1) 946 checkCallbackNotCalled(t2) 947 }) 948 949 // ---xxx====--- 950 // ++++ 951 // => 952 // --+xxx====--- 953 It("case 27", func() { 954 f1 := getData(3) 955 cb1, t1 := getCallback() 956 f2 := getData(4) 957 cb2, t2 := getCallback() 958 f3 := getData(4) 959 cb3, t3 := getCallback() 960 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 961 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 10 962 Expect(s.Push(f3, 2, cb3)).To(Succeed()) // 2 - 6 963 checkQueue(map[protocol.ByteCount][]byte{ 964 2: f3[:1], 965 3: f1, 966 6: f2, 967 }) 968 checkGaps([]byteInterval{ 969 {Start: 0, End: 2}, 970 {Start: 10, End: protocol.MaxByteCount}, 971 }) 972 checkCallbackNotCalled(t1) 973 checkCallbackNotCalled(t2) 974 checkCallbackCalled(t3) 975 }) 976 977 It("case 27, for long frames", func() { 978 const mult = protocol.MinStreamFrameSize 979 f1 := getData(3 * mult) 980 cb1, t1 := getCallback() 981 f2 := getData(4 * mult) 982 cb2, t2 := getCallback() 983 f3 := getData(4 * mult) 984 cb3, t3 := getCallback() 985 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 986 Expect(s.Push(f2, 6*mult, cb2)).To(Succeed()) // 6 - 10 987 Expect(s.Push(f3, 2*mult, cb3)).To(Succeed()) // 2 - 6 988 checkQueue(map[protocol.ByteCount][]byte{ 989 2 * mult: f3[:mult], 990 3 * mult: f1, 991 6 * mult: f2, 992 }) 993 checkGaps([]byteInterval{ 994 {Start: 0, End: 2 * mult}, 995 {Start: 10 * mult, End: protocol.MaxByteCount}, 996 }) 997 checkCallbackNotCalled(t1) 998 checkCallbackNotCalled(t2) 999 checkCallbackNotCalled(t3) 1000 }) 1001 1002 // ---xxx====--- 1003 // ++++++ 1004 // => 1005 // --+xxx====--- 1006 It("case 28", func() { 1007 f1 := getData(3) 1008 cb1, t1 := getCallback() 1009 f2 := getData(4) 1010 cb2, t2 := getCallback() 1011 f3 := getData(6) 1012 cb3, t3 := getCallback() 1013 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1014 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 10 1015 Expect(s.Push(f3, 2, cb3)).To(Succeed()) // 2 - 8 1016 checkQueue(map[protocol.ByteCount][]byte{ 1017 2: f3[:1], 1018 3: f1, 1019 6: f2, 1020 }) 1021 checkGaps([]byteInterval{ 1022 {Start: 0, End: 2}, 1023 {Start: 10, End: protocol.MaxByteCount}, 1024 }) 1025 checkCallbackNotCalled(t1) 1026 checkCallbackNotCalled(t2) 1027 checkCallbackCalled(t3) 1028 }) 1029 1030 It("case 28, for long frames", func() { 1031 const mult = protocol.MinStreamFrameSize 1032 f1 := getData(3 * mult) 1033 cb1, t1 := getCallback() 1034 f2 := getData(4 * mult) 1035 cb2, t2 := getCallback() 1036 f3 := getData(6 * mult) 1037 cb3, t3 := getCallback() 1038 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 1039 Expect(s.Push(f2, 6*mult, cb2)).To(Succeed()) // 6 - 10 1040 Expect(s.Push(f3, 2*mult, cb3)).To(Succeed()) // 2 - 8 1041 checkQueue(map[protocol.ByteCount][]byte{ 1042 2 * mult: f3[:mult], 1043 3 * mult: f1, 1044 6 * mult: f2, 1045 }) 1046 checkGaps([]byteInterval{ 1047 {Start: 0, End: 2 * mult}, 1048 {Start: 10 * mult, End: protocol.MaxByteCount}, 1049 }) 1050 checkCallbackNotCalled(t1) 1051 checkCallbackNotCalled(t2) 1052 checkCallbackNotCalled(t3) 1053 }) 1054 1055 // ---xxx===----- 1056 // +++++ 1057 // => 1058 // ---xxx+++++--- 1059 It("case 29", func() { 1060 f1 := getData(3) 1061 cb1, t1 := getCallback() 1062 f2 := getData(3) 1063 cb2, t2 := getCallback() 1064 f3 := getData(5) 1065 cb3, t3 := getCallback() 1066 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1067 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 9 1068 Expect(s.Push(f3, 6, cb3)).To(Succeed()) // 6 - 11 1069 checkQueue(map[protocol.ByteCount][]byte{ 1070 3: f1, 1071 6: f3, 1072 }) 1073 checkGaps([]byteInterval{ 1074 {Start: 0, End: 3}, 1075 {Start: 11, End: protocol.MaxByteCount}, 1076 }) 1077 checkCallbackNotCalled(t1) 1078 checkCallbackCalled(t2) 1079 checkCallbackNotCalled(t3) 1080 }) 1081 1082 // ---xxx===---- 1083 // ++++++ 1084 // => 1085 // ---xxx===++-- 1086 It("case 30", func() { 1087 f1 := getData(3) 1088 cb1, t1 := getCallback() 1089 f2 := getData(3) 1090 cb2, t2 := getCallback() 1091 f3 := getData(6) 1092 cb3, t3 := getCallback() 1093 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1094 Expect(s.Push(f2, 6, cb2)).To(Succeed()) // 6 - 9 1095 Expect(s.Push(f3, 5, cb3)).To(Succeed()) // 5 - 11 1096 checkQueue(map[protocol.ByteCount][]byte{ 1097 3: f1, 1098 6: f2, 1099 9: f3[4:], 1100 }) 1101 checkGaps([]byteInterval{ 1102 {Start: 0, End: 3}, 1103 {Start: 11, End: protocol.MaxByteCount}, 1104 }) 1105 checkCallbackNotCalled(t1) 1106 checkCallbackNotCalled(t2) 1107 checkCallbackCalled(t3) 1108 }) 1109 1110 It("case 30, for long frames", func() { 1111 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 2)) 1112 f1 := getData(3 * mult) 1113 cb1, t1 := getCallback() 1114 f2 := getData(3 * mult) 1115 cb2, t2 := getCallback() 1116 f3 := getData(6 * mult) 1117 cb3, t3 := getCallback() 1118 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 1119 Expect(s.Push(f2, 6*mult, cb2)).To(Succeed()) // 6 - 9 1120 Expect(s.Push(f3, 5*mult, cb3)).To(Succeed()) // 5 - 11 1121 checkQueue(map[protocol.ByteCount][]byte{ 1122 3 * mult: f1, 1123 6 * mult: f2, 1124 9 * mult: f3[4*mult:], 1125 }) 1126 checkGaps([]byteInterval{ 1127 {Start: 0, End: 3 * mult}, 1128 {Start: 11 * mult, End: protocol.MaxByteCount}, 1129 }) 1130 checkCallbackNotCalled(t1) 1131 checkCallbackNotCalled(t2) 1132 checkCallbackNotCalled(t3) 1133 }) 1134 1135 // ---xxx---===----- 1136 // ++++++++++ 1137 // => 1138 // ---xxx++++++++--- 1139 It("case 31", func() { 1140 f1 := getData(3) 1141 cb1, t1 := getCallback() 1142 f2 := getData(3) 1143 cb2, t2 := getCallback() 1144 f3 := getData(10) 1145 cb3, t3 := getCallback() 1146 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1147 Expect(s.Push(f2, 9, cb2)).To(Succeed()) // 9 - 12 1148 Expect(s.Push(f3, 5, cb3)).To(Succeed()) // 5 - 15 1149 checkQueue(map[protocol.ByteCount][]byte{ 1150 3: f1, 1151 6: f3[1:], 1152 }) 1153 checkGaps([]byteInterval{ 1154 {Start: 0, End: 3}, 1155 {Start: 15, End: protocol.MaxByteCount}, 1156 }) 1157 checkCallbackNotCalled(t1) 1158 checkCallbackCalled(t2) 1159 checkCallbackCalled(t3) 1160 }) 1161 1162 It("case 31, for long frames", func() { 1163 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 9)) 1164 f1 := getData(3 * mult) 1165 cb1, t1 := getCallback() 1166 f2 := getData(3 * mult) 1167 cb2, t2 := getCallback() 1168 f3 := getData(10 * mult) 1169 cb3, t3 := getCallback() 1170 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 1171 Expect(s.Push(f2, 9*mult, cb2)).To(Succeed()) // 9 - 12 1172 Expect(s.Push(f3, 5*mult, cb3)).To(Succeed()) // 5 - 15 1173 checkQueue(map[protocol.ByteCount][]byte{ 1174 3 * mult: f1, 1175 6 * mult: f3[mult:], 1176 }) 1177 checkGaps([]byteInterval{ 1178 {Start: 0, End: 3 * mult}, 1179 {Start: 15 * mult, End: protocol.MaxByteCount}, 1180 }) 1181 checkCallbackNotCalled(t1) 1182 checkCallbackCalled(t2) 1183 checkCallbackNotCalled(t3) 1184 }) 1185 1186 // ---xxx---===----- 1187 // +++++++++ 1188 // => 1189 // ---+++++++++--- 1190 It("case 32", func() { 1191 f1 := getData(3) 1192 cb1, t1 := getCallback() 1193 f2 := getData(3) 1194 cb2, t2 := getCallback() 1195 f3 := getData(9) 1196 cb3, t3 := getCallback() 1197 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1198 Expect(s.Push(f2, 9, cb2)).To(Succeed()) // 9 - 12 1199 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 12 1200 checkQueue(map[protocol.ByteCount][]byte{ 1201 3: f3, 1202 }) 1203 checkGaps([]byteInterval{ 1204 {Start: 0, End: 3}, 1205 {Start: 12, End: protocol.MaxByteCount}, 1206 }) 1207 checkCallbackCalled(t1) 1208 checkCallbackCalled(t2) 1209 checkCallbackNotCalled(t3) 1210 }) 1211 1212 // ---xxx---===###----- 1213 // ++++++++++++ 1214 // => 1215 // ---xxx++++++++++--- 1216 It("case 33", func() { 1217 f1 := getData(3) 1218 cb1, t1 := getCallback() 1219 f2 := getData(3) 1220 cb2, t2 := getCallback() 1221 f3 := getData(3) 1222 cb3, t3 := getCallback() 1223 f4 := getData(12) 1224 cb4, t4 := getCallback() 1225 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1226 Expect(s.Push(f2, 9, cb2)).To(Succeed()) // 9 - 12 1227 Expect(s.Push(f3, 9, cb3)).To(Succeed()) // 12 - 15 1228 Expect(s.Push(f4, 5, cb4)).To(Succeed()) // 5 - 17 1229 checkQueue(map[protocol.ByteCount][]byte{ 1230 3: f1, 1231 6: f4[1:], 1232 }) 1233 checkGaps([]byteInterval{ 1234 {Start: 0, End: 3}, 1235 {Start: 17, End: protocol.MaxByteCount}, 1236 }) 1237 checkCallbackNotCalled(t1) 1238 checkCallbackCalled(t2) 1239 checkCallbackCalled(t3) 1240 checkCallbackCalled(t4) 1241 }) 1242 1243 It("case 33, for long frames", func() { 1244 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 11)) 1245 f1 := getData(3 * mult) 1246 cb1, t1 := getCallback() 1247 f2 := getData(3 * mult) 1248 cb2, t2 := getCallback() 1249 f3 := getData(3 * mult) 1250 cb3, t3 := getCallback() 1251 f4 := getData(12 * mult) 1252 cb4, t4 := getCallback() 1253 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 1254 Expect(s.Push(f2, 9*mult, cb2)).To(Succeed()) // 9 - 12 1255 Expect(s.Push(f3, 9*mult, cb3)).To(Succeed()) // 12 - 15 1256 Expect(s.Push(f4, 5*mult, cb4)).To(Succeed()) // 5 - 17 1257 checkQueue(map[protocol.ByteCount][]byte{ 1258 3 * mult: f1, 1259 6 * mult: f4[mult:], 1260 }) 1261 checkGaps([]byteInterval{ 1262 {Start: 0, End: 3 * mult}, 1263 {Start: 17 * mult, End: protocol.MaxByteCount}, 1264 }) 1265 checkCallbackNotCalled(t1) 1266 checkCallbackCalled(t2) 1267 checkCallbackCalled(t3) 1268 checkCallbackNotCalled(t4) 1269 }) 1270 1271 // ---xxx===---### 1272 // ++++++ 1273 // => 1274 // ---xxx++++++### 1275 It("case 34", func() { 1276 f1 := getData(5) 1277 cb1, t1 := getCallback() 1278 f2 := getData(5) 1279 cb2, t2 := getCallback() 1280 f3 := getData(10) 1281 cb3, t3 := getCallback() 1282 f4 := getData(5) 1283 cb4, t4 := getCallback() 1284 Expect(s.Push(f1, 5, cb1)).To(Succeed()) // 5 - 10 1285 Expect(s.Push(f2, 10, cb2)).To(Succeed()) // 10 - 15 1286 Expect(s.Push(f4, 20, cb3)).To(Succeed()) // 20 - 25 1287 Expect(s.Push(f3, 10, cb4)).To(Succeed()) // 10 - 20 1288 checkQueue(map[protocol.ByteCount][]byte{ 1289 5: f1, 1290 10: f3, 1291 20: f4, 1292 }) 1293 checkGaps([]byteInterval{ 1294 {Start: 0, End: 5}, 1295 {Start: 25, End: protocol.MaxByteCount}, 1296 }) 1297 checkCallbackNotCalled(t1) 1298 checkCallbackCalled(t2) 1299 checkCallbackNotCalled(t3) 1300 checkCallbackNotCalled(t4) 1301 }) 1302 1303 // ---xxx---####--- 1304 // ++++++++ 1305 // => 1306 // ---++++++####--- 1307 It("case 35", func() { 1308 f1 := getData(3) 1309 cb1, t1 := getCallback() 1310 f2 := getData(4) 1311 cb2, t2 := getCallback() 1312 f3 := getData(8) 1313 cb3, t3 := getCallback() 1314 Expect(s.Push(f1, 3, cb1)).To(Succeed()) // 3 - 6 1315 Expect(s.Push(f2, 9, cb2)).To(Succeed()) // 9 - 13 1316 Expect(s.Push(f3, 3, cb3)).To(Succeed()) // 3 - 11 1317 checkGaps([]byteInterval{ 1318 {Start: 0, End: 3}, 1319 {Start: 13, End: protocol.MaxByteCount}, 1320 }) 1321 checkQueue(map[protocol.ByteCount][]byte{ 1322 3: f3[:6], 1323 9: f2, 1324 }) 1325 checkCallbackCalled(t1) 1326 checkCallbackNotCalled(t2) 1327 checkCallbackCalled(t3) 1328 }) 1329 1330 It("case 35, for long frames", func() { 1331 mult := protocol.ByteCount(math.Ceil(float64(protocol.MinStreamFrameSize) / 6)) 1332 f1 := getData(3 * mult) 1333 cb1, t1 := getCallback() 1334 f2 := getData(4 * mult) 1335 cb2, t2 := getCallback() 1336 f3 := getData(8 * mult) 1337 cb3, t3 := getCallback() 1338 Expect(s.Push(f1, 3*mult, cb1)).To(Succeed()) // 3 - 6 1339 Expect(s.Push(f2, 9*mult, cb2)).To(Succeed()) // 9 - 13 1340 Expect(s.Push(f3, 3*mult, cb3)).To(Succeed()) // 3 - 11 1341 checkGaps([]byteInterval{ 1342 {Start: 0, End: 3 * mult}, 1343 {Start: 13 * mult, End: protocol.MaxByteCount}, 1344 }) 1345 checkQueue(map[protocol.ByteCount][]byte{ 1346 3 * mult: f3[:6*mult], 1347 9 * mult: f2, 1348 }) 1349 checkCallbackCalled(t1) 1350 checkCallbackNotCalled(t2) 1351 checkCallbackNotCalled(t3) 1352 }) 1353 1354 Context("receiving data after reads", func() { 1355 It("ignores duplicate frames", func() { 1356 Expect(s.Push([]byte("foobar"), 0, nil)).To(Succeed()) 1357 offset, data, _ := s.Pop() 1358 Expect(offset).To(BeZero()) 1359 Expect(data).To(Equal([]byte("foobar"))) 1360 // now receive the duplicate 1361 Expect(s.Push([]byte("foobar"), 0, nil)).To(Succeed()) 1362 Expect(s.queue).To(BeEmpty()) 1363 checkGaps([]byteInterval{ 1364 {Start: 6, End: protocol.MaxByteCount}, 1365 }) 1366 }) 1367 1368 It("ignores parts of frames that have already been read", func() { 1369 Expect(s.Push([]byte("foo"), 0, nil)).To(Succeed()) 1370 offset, data, _ := s.Pop() 1371 Expect(offset).To(BeZero()) 1372 Expect(data).To(Equal([]byte("foo"))) 1373 // now receive the duplicate 1374 Expect(s.Push([]byte("foobar"), 0, nil)).To(Succeed()) 1375 offset, data, _ = s.Pop() 1376 Expect(offset).To(Equal(protocol.ByteCount(3))) 1377 Expect(data).To(Equal([]byte("bar"))) 1378 Expect(s.queue).To(BeEmpty()) 1379 checkGaps([]byteInterval{ 1380 {Start: 6, End: protocol.MaxByteCount}, 1381 }) 1382 }) 1383 }) 1384 1385 Context("DoS protection", func() { 1386 It("errors when too many gaps are created", func() { 1387 for i := 0; i < protocol.MaxStreamFrameSorterGaps; i++ { 1388 Expect(s.Push([]byte("foobar"), protocol.ByteCount(i*7), nil)).To(Succeed()) 1389 } 1390 Expect(s.gapTree.Len()).To(Equal(protocol.MaxStreamFrameSorterGaps)) 1391 err := s.Push([]byte("foobar"), protocol.ByteCount(protocol.MaxStreamFrameSorterGaps*7)+100, nil) 1392 Expect(err).To(MatchError("too many gaps in received data")) 1393 }) 1394 }) 1395 }) 1396 1397 Context("stress testing", func() { 1398 type frame struct { 1399 offset protocol.ByteCount 1400 data []byte 1401 } 1402 1403 for _, lf := range []bool{true, false} { 1404 longFrames := lf 1405 1406 const num = 1000 1407 1408 name := "short" 1409 if longFrames { 1410 name = "long" 1411 } 1412 1413 Context(fmt.Sprintf("using %s frames", name), func() { 1414 var data []byte 1415 var dataLen protocol.ByteCount 1416 var callbacks []callbackTracker 1417 1418 BeforeEach(func() { 1419 seed := time.Now().UnixNano() 1420 fmt.Fprintf(GinkgoWriter, "Seed: %d\n", seed) 1421 rand.Seed(uint64(seed)) 1422 1423 callbacks = nil 1424 dataLen = 25 1425 if longFrames { 1426 dataLen = 2 * protocol.MinStreamFrameSize 1427 } 1428 1429 data = make([]byte, num*dataLen) 1430 for i := 0; i < num; i++ { 1431 for j := protocol.ByteCount(0); j < dataLen; j++ { 1432 data[protocol.ByteCount(i)*dataLen+j] = uint8(i) 1433 } 1434 } 1435 }) 1436 1437 getRandomFrames := func() []frame { 1438 frames := make([]frame, num) 1439 for i := protocol.ByteCount(0); i < num; i++ { 1440 b := make([]byte, dataLen) 1441 Expect(copy(b, data[i*dataLen:])).To(BeEquivalentTo(dataLen)) 1442 frames[i] = frame{ 1443 offset: i * dataLen, 1444 data: b, 1445 } 1446 } 1447 rand.Shuffle(len(frames), func(i, j int) { frames[i], frames[j] = frames[j], frames[i] }) 1448 return frames 1449 } 1450 1451 getData := func() []byte { 1452 var data []byte 1453 for { 1454 offset, b, cb := s.Pop() 1455 if b == nil { 1456 break 1457 } 1458 Expect(offset).To(BeEquivalentTo(len(data))) 1459 data = append(data, b...) 1460 if cb != nil { 1461 cb() 1462 } 1463 } 1464 return data 1465 } 1466 1467 // push pushes data to the frame sorter 1468 // It creates a new callback and adds the 1469 push := func(data []byte, offset protocol.ByteCount) { 1470 cb, t := getCallback() 1471 ExpectWithOffset(1, s.Push(data, offset, cb)).To(Succeed()) 1472 callbacks = append(callbacks, t) 1473 } 1474 1475 checkCallbacks := func() { 1476 ExpectWithOffset(1, callbacks).ToNot(BeEmpty()) 1477 for _, t := range callbacks { 1478 checkCallbackCalled(t) 1479 } 1480 } 1481 1482 It("inserting frames in a random order", func() { 1483 frames := getRandomFrames() 1484 1485 for _, f := range frames { 1486 push(f.data, f.offset) 1487 } 1488 checkGaps([]byteInterval{{Start: num * dataLen, End: protocol.MaxByteCount}}) 1489 1490 Expect(getData()).To(Equal(data)) 1491 Expect(s.queue).To(BeEmpty()) 1492 checkCallbacks() 1493 }) 1494 1495 It("inserting frames in a random order, with some duplicates", func() { 1496 frames := getRandomFrames() 1497 1498 for _, f := range frames { 1499 push(f.data, f.offset) 1500 if rand.Intn(10) < 5 { 1501 df := frames[rand.Intn(len(frames))] 1502 push(df.data, df.offset) 1503 } 1504 } 1505 checkGaps([]byteInterval{{Start: num * dataLen, End: protocol.MaxByteCount}}) 1506 1507 Expect(getData()).To(Equal(data)) 1508 Expect(s.queue).To(BeEmpty()) 1509 checkCallbacks() 1510 }) 1511 1512 It("inserting frames in a random order, with randomly cut retransmissions", func() { 1513 frames := getRandomFrames() 1514 1515 for _, f := range frames { 1516 push(f.data, f.offset) 1517 if rand.Intn(10) < 5 { 1518 length := protocol.ByteCount(1 + rand.Intn(int(4*dataLen))) 1519 if length >= num*dataLen { 1520 length = num*dataLen - 1 1521 } 1522 b := make([]byte, length) 1523 offset := protocol.ByteCount(rand.Intn(int(num*dataLen - length))) 1524 Expect(copy(b, data[offset:offset+length])).To(BeEquivalentTo(length)) 1525 push(b, offset) 1526 } 1527 } 1528 checkGaps([]byteInterval{{Start: num * dataLen, End: protocol.MaxByteCount}}) 1529 1530 Expect(getData()).To(Equal(data)) 1531 Expect(s.queue).To(BeEmpty()) 1532 checkCallbacks() 1533 }) 1534 }) 1535 } 1536 }) 1537 })