github.com/mikelsr/quic-go@v0.36.1-0.20230701132136-1d9415b66898/frame_sorter_test.go (about)

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