github.com/metacubex/quic-go@v0.44.1-0.20240520163451-20b689a59136/internal/protocol/connection_id_test.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "io" 7 8 . "github.com/onsi/ginkgo/v2" 9 . "github.com/onsi/gomega" 10 ) 11 12 var _ = Describe("Connection ID generation", func() { 13 It("generates random connection IDs", func() { 14 c1, err := GenerateConnectionID(8) 15 Expect(err).ToNot(HaveOccurred()) 16 Expect(c1).ToNot(BeZero()) 17 c2, err := GenerateConnectionID(8) 18 Expect(err).ToNot(HaveOccurred()) 19 Expect(c1).ToNot(Equal(c2)) 20 }) 21 22 It("generates connection IDs with the requested length", func() { 23 c, err := GenerateConnectionID(5) 24 Expect(err).ToNot(HaveOccurred()) 25 Expect(c.Len()).To(Equal(5)) 26 }) 27 28 It("generates random length destination connection IDs", func() { 29 var has8ByteConnID, has20ByteConnID bool 30 for i := 0; i < 1000; i++ { 31 c, err := GenerateConnectionIDForInitial() 32 Expect(err).ToNot(HaveOccurred()) 33 Expect(c.Len()).To(BeNumerically(">=", 8)) 34 Expect(c.Len()).To(BeNumerically("<=", 20)) 35 if c.Len() == 8 { 36 has8ByteConnID = true 37 } 38 if c.Len() == 20 { 39 has20ByteConnID = true 40 } 41 } 42 Expect(has8ByteConnID).To(BeTrue()) 43 Expect(has20ByteConnID).To(BeTrue()) 44 }) 45 46 It("reads the connection ID", func() { 47 buf := bytes.NewBuffer([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}) 48 c, err := ReadConnectionID(buf, 9) 49 Expect(err).ToNot(HaveOccurred()) 50 Expect(c.Bytes()).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9})) 51 }) 52 53 It("returns io.EOF if there's not enough data to read", func() { 54 buf := bytes.NewBuffer([]byte{1, 2, 3, 4}) 55 _, err := ReadConnectionID(buf, 5) 56 Expect(err).To(MatchError(io.EOF)) 57 }) 58 59 It("returns a 0 length connection ID", func() { 60 buf := bytes.NewBuffer([]byte{1, 2, 3, 4}) 61 c, err := ReadConnectionID(buf, 0) 62 Expect(err).ToNot(HaveOccurred()) 63 Expect(c.Len()).To(BeZero()) 64 }) 65 66 It("errors when trying to read a too long connection ID", func() { 67 buf := bytes.NewBuffer(make([]byte, 21)) 68 _, err := ReadConnectionID(buf, 21) 69 Expect(err).To(MatchError(ErrInvalidConnectionIDLen)) 70 }) 71 72 It("returns the length", func() { 73 c := ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7}) 74 Expect(c.Len()).To(Equal(7)) 75 }) 76 77 It("has 0 length for the default value", func() { 78 var c ConnectionID 79 Expect(c.Len()).To(BeZero()) 80 }) 81 82 It("returns the bytes", func() { 83 c := ParseConnectionID([]byte{1, 2, 3, 4, 5, 6, 7}) 84 Expect(c.Bytes()).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7})) 85 }) 86 87 It("returns a nil byte slice for the default value", func() { 88 var c ConnectionID 89 Expect(c.Bytes()).To(HaveLen(0)) 90 }) 91 92 It("has a string representation", func() { 93 c := ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef, 0x42}) 94 Expect(c.String()).To(Equal("deadbeef42")) 95 }) 96 97 It("has a long string representation", func() { 98 c := ParseConnectionID([]byte{0x13, 0x37, 0, 0, 0xde, 0xca, 0xfb, 0xad}) 99 Expect(c.String()).To(Equal("13370000decafbad")) 100 }) 101 102 It("has a string representation for the default value", func() { 103 var c ConnectionID 104 Expect(c.String()).To(Equal("(empty)")) 105 }) 106 107 Context("arbitrary length connection IDs", func() { 108 It("returns the bytes", func() { 109 b := make([]byte, 30) 110 rand.Read(b) 111 c := ArbitraryLenConnectionID(b) 112 Expect(c.Bytes()).To(Equal(b)) 113 }) 114 115 It("returns the length", func() { 116 c := ArbitraryLenConnectionID(make([]byte, 156)) 117 Expect(c.Len()).To(Equal(156)) 118 }) 119 120 It("has a string representation", func() { 121 c := ArbitraryLenConnectionID([]byte{0xde, 0xad, 0xbe, 0xef, 0x42}) 122 Expect(c.String()).To(Equal("deadbeef42")) 123 }) 124 125 It("has a string representation for the default value", func() { 126 var c ArbitraryLenConnectionID 127 Expect(c.String()).To(Equal("(empty)")) 128 }) 129 }) 130 })