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