github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/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/apernet/quic-go/internal/protocol"
    12  	"github.com/apernet/quic-go/internal/utils"
    13  	"github.com/apernet/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  })