github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/frame_sorter_test.go (about)

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