github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/retransmission_queue_test.go (about)

     1  package quic
     2  
     3  import (
     4  	"github.com/TugasAkhir-QUIC/quic-go/internal/protocol"
     5  	"github.com/TugasAkhir-QUIC/quic-go/internal/wire"
     6  
     7  	. "github.com/onsi/ginkgo/v2"
     8  	. "github.com/onsi/gomega"
     9  )
    10  
    11  var _ = Describe("Retransmission queue", func() {
    12  	var q *retransmissionQueue
    13  
    14  	BeforeEach(func() {
    15  		q = newRetransmissionQueue()
    16  	})
    17  
    18  	Context("Initial data", func() {
    19  		It("doesn't dequeue anything when it's empty", func() {
    20  			Expect(q.HasInitialData()).To(BeFalse())
    21  			Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil())
    22  		})
    23  
    24  		It("queues and retrieves a control frame", func() {
    25  			f := &wire.MaxDataFrame{MaximumData: 0x42}
    26  			q.addInitial(f)
    27  			Expect(q.HasInitialData()).To(BeTrue())
    28  			Expect(q.GetInitialFrame(f.Length(protocol.Version1)-1, protocol.Version1)).To(BeNil())
    29  			Expect(q.GetInitialFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f))
    30  			Expect(q.HasInitialData()).To(BeFalse())
    31  		})
    32  
    33  		It("queues and retrieves a CRYPTO frame", func() {
    34  			f := &wire.CryptoFrame{Data: []byte("foobar")}
    35  			q.addInitial(f)
    36  			Expect(q.HasInitialData()).To(BeTrue())
    37  			Expect(q.GetInitialFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f))
    38  			Expect(q.HasInitialData()).To(BeFalse())
    39  		})
    40  
    41  		It("returns split CRYPTO frames", func() {
    42  			f := &wire.CryptoFrame{
    43  				Offset: 100,
    44  				Data:   []byte("foobar"),
    45  			}
    46  			q.addInitial(f)
    47  			Expect(q.HasInitialData()).To(BeTrue())
    48  			f1 := q.GetInitialFrame(f.Length(protocol.Version1)-3, protocol.Version1)
    49  			Expect(f1).ToNot(BeNil())
    50  			Expect(f1).To(BeAssignableToTypeOf(&wire.CryptoFrame{}))
    51  			Expect(f1.(*wire.CryptoFrame).Data).To(Equal([]byte("foo")))
    52  			Expect(f1.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(100)))
    53  			Expect(q.HasInitialData()).To(BeTrue())
    54  			f2 := q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)
    55  			Expect(f2).ToNot(BeNil())
    56  			Expect(f2).To(BeAssignableToTypeOf(&wire.CryptoFrame{}))
    57  			Expect(f2.(*wire.CryptoFrame).Data).To(Equal([]byte("bar")))
    58  			Expect(f2.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(103)))
    59  			Expect(q.HasInitialData()).To(BeFalse())
    60  		})
    61  
    62  		It("returns other frames when a CRYPTO frame wouldn't fit", func() {
    63  			f := &wire.CryptoFrame{Data: []byte("foobar")}
    64  			q.addInitial(f)
    65  			q.addInitial(&wire.PingFrame{})
    66  			f1 := q.GetInitialFrame(2, protocol.Version1) // too small for a CRYPTO frame
    67  			Expect(f1).ToNot(BeNil())
    68  			Expect(f1).To(BeAssignableToTypeOf(&wire.PingFrame{}))
    69  			Expect(q.HasInitialData()).To(BeTrue())
    70  			f2 := q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)
    71  			Expect(f2).To(Equal(f))
    72  		})
    73  
    74  		It("retrieves both a CRYPTO frame and a control frame", func() {
    75  			cf := &wire.MaxDataFrame{MaximumData: 0x42}
    76  			f := &wire.CryptoFrame{Data: []byte("foobar")}
    77  			q.addInitial(f)
    78  			q.addInitial(cf)
    79  			Expect(q.HasInitialData()).To(BeTrue())
    80  			Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f))
    81  			Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(cf))
    82  			Expect(q.HasInitialData()).To(BeFalse())
    83  		})
    84  
    85  		It("drops all Initial frames", func() {
    86  			q.addInitial(&wire.CryptoFrame{Data: []byte("foobar")})
    87  			q.addInitial(&wire.MaxDataFrame{MaximumData: 0x42})
    88  			q.DropPackets(protocol.EncryptionInitial)
    89  			Expect(q.HasInitialData()).To(BeFalse())
    90  			Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil())
    91  		})
    92  
    93  		It("retransmits a frame", func() {
    94  			f := &wire.MaxDataFrame{MaximumData: 0x42}
    95  			q.InitialAckHandler().OnLost(f)
    96  			Expect(q.HasInitialData()).To(BeTrue())
    97  			Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f))
    98  		})
    99  
   100  		It("adds a PING", func() {
   101  			q.AddPing(protocol.EncryptionInitial)
   102  			Expect(q.HasInitialData()).To(BeTrue())
   103  			Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(&wire.PingFrame{}))
   104  		})
   105  	})
   106  
   107  	Context("Handshake data", func() {
   108  		It("doesn't dequeue anything when it's empty", func() {
   109  			Expect(q.HasHandshakeData()).To(BeFalse())
   110  			Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil())
   111  		})
   112  
   113  		It("queues and retrieves a control frame", func() {
   114  			f := &wire.MaxDataFrame{MaximumData: 0x42}
   115  			q.addHandshake(f)
   116  			Expect(q.HasHandshakeData()).To(BeTrue())
   117  			Expect(q.GetHandshakeFrame(f.Length(protocol.Version1)-1, protocol.Version1)).To(BeNil())
   118  			Expect(q.GetHandshakeFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f))
   119  			Expect(q.HasHandshakeData()).To(BeFalse())
   120  		})
   121  
   122  		It("queues and retrieves a CRYPTO frame", func() {
   123  			f := &wire.CryptoFrame{Data: []byte("foobar")}
   124  			q.addHandshake(f)
   125  			Expect(q.HasHandshakeData()).To(BeTrue())
   126  			Expect(q.GetHandshakeFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f))
   127  			Expect(q.HasHandshakeData()).To(BeFalse())
   128  		})
   129  
   130  		It("returns split CRYPTO frames", func() {
   131  			f := &wire.CryptoFrame{
   132  				Offset: 100,
   133  				Data:   []byte("foobar"),
   134  			}
   135  			q.addHandshake(f)
   136  			Expect(q.HasHandshakeData()).To(BeTrue())
   137  			f1 := q.GetHandshakeFrame(f.Length(protocol.Version1)-3, protocol.Version1)
   138  			Expect(f1).ToNot(BeNil())
   139  			Expect(f1).To(BeAssignableToTypeOf(&wire.CryptoFrame{}))
   140  			Expect(f1.(*wire.CryptoFrame).Data).To(Equal([]byte("foo")))
   141  			Expect(f1.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(100)))
   142  			Expect(q.HasHandshakeData()).To(BeTrue())
   143  			f2 := q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)
   144  			Expect(f2).ToNot(BeNil())
   145  			Expect(f2).To(BeAssignableToTypeOf(&wire.CryptoFrame{}))
   146  			Expect(f2.(*wire.CryptoFrame).Data).To(Equal([]byte("bar")))
   147  			Expect(f2.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(103)))
   148  			Expect(q.HasHandshakeData()).To(BeFalse())
   149  		})
   150  
   151  		It("returns other frames when a CRYPTO frame wouldn't fit", func() {
   152  			f := &wire.CryptoFrame{Data: []byte("foobar")}
   153  			q.addHandshake(f)
   154  			q.addHandshake(&wire.PingFrame{})
   155  			f1 := q.GetHandshakeFrame(2, protocol.Version1) // too small for a CRYPTO frame
   156  			Expect(f1).ToNot(BeNil())
   157  			Expect(f1).To(BeAssignableToTypeOf(&wire.PingFrame{}))
   158  			Expect(q.HasHandshakeData()).To(BeTrue())
   159  			f2 := q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)
   160  			Expect(f2).To(Equal(f))
   161  		})
   162  
   163  		It("retrieves both a CRYPTO frame and a control frame", func() {
   164  			cf := &wire.MaxDataFrame{MaximumData: 0x42}
   165  			f := &wire.CryptoFrame{Data: []byte("foobar")}
   166  			q.addHandshake(f)
   167  			q.addHandshake(cf)
   168  			Expect(q.HasHandshakeData()).To(BeTrue())
   169  			Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f))
   170  			Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(cf))
   171  			Expect(q.HasHandshakeData()).To(BeFalse())
   172  		})
   173  
   174  		It("drops all Handshake frames", func() {
   175  			q.addHandshake(&wire.CryptoFrame{Data: []byte("foobar")})
   176  			q.addHandshake(&wire.MaxDataFrame{MaximumData: 0x42})
   177  			q.DropPackets(protocol.EncryptionHandshake)
   178  			Expect(q.HasHandshakeData()).To(BeFalse())
   179  			Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil())
   180  		})
   181  
   182  		It("retransmits a frame", func() {
   183  			f := &wire.MaxDataFrame{MaximumData: 0x42}
   184  			q.HandshakeAckHandler().OnLost(f)
   185  			Expect(q.HasHandshakeData()).To(BeTrue())
   186  			Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f))
   187  		})
   188  
   189  		It("adds a PING", func() {
   190  			q.AddPing(protocol.EncryptionHandshake)
   191  			Expect(q.HasHandshakeData()).To(BeTrue())
   192  			Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(&wire.PingFrame{}))
   193  		})
   194  	})
   195  
   196  	Context("Application data", func() {
   197  		It("doesn't dequeue anything when it's empty", func() {
   198  			Expect(q.GetAppDataFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil())
   199  		})
   200  
   201  		It("queues and retrieves a control frame", func() {
   202  			f := &wire.MaxDataFrame{MaximumData: 0x42}
   203  			Expect(q.HasAppData()).To(BeFalse())
   204  			q.addAppData(f)
   205  			Expect(q.HasAppData()).To(BeTrue())
   206  			Expect(q.GetAppDataFrame(f.Length(protocol.Version1)-1, protocol.Version1)).To(BeNil())
   207  			Expect(q.GetAppDataFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f))
   208  			Expect(q.HasAppData()).To(BeFalse())
   209  		})
   210  
   211  		It("retransmits a frame", func() {
   212  			f := &wire.MaxDataFrame{MaximumData: 0x42}
   213  			q.AppDataAckHandler().OnLost(f)
   214  			Expect(q.HasAppData()).To(BeTrue())
   215  			Expect(q.GetAppDataFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f))
   216  		})
   217  
   218  		It("adds a PING", func() {
   219  			q.AddPing(protocol.Encryption1RTT)
   220  			Expect(q.HasAppData()).To(BeTrue())
   221  			Expect(q.GetAppDataFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(&wire.PingFrame{}))
   222  		})
   223  	})
   224  })