github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/protocol/version_test.go (about)

     1  package protocol
     2  
     3  import (
     4  	. "github.com/onsi/ginkgo/v2"
     5  	. "github.com/onsi/gomega"
     6  )
     7  
     8  var _ = Describe("Version", func() {
     9  	isReservedVersion := func(v Version) bool {
    10  		return v&0x0f0f0f0f == 0x0a0a0a0a
    11  	}
    12  
    13  	It("says if a version is valid", func() {
    14  		Expect(IsValidVersion(VersionUnknown)).To(BeFalse())
    15  		Expect(IsValidVersion(versionDraft29)).To(BeFalse())
    16  		Expect(IsValidVersion(Version1)).To(BeTrue())
    17  		Expect(IsValidVersion(Version2)).To(BeTrue())
    18  		Expect(IsValidVersion(1234)).To(BeFalse())
    19  	})
    20  
    21  	It("has the right string representation", func() {
    22  		Expect(VersionUnknown.String()).To(Equal("unknown"))
    23  		Expect(versionDraft29.String()).To(Equal("draft-29"))
    24  		Expect(Version1.String()).To(Equal("v1"))
    25  		Expect(Version2.String()).To(Equal("v2"))
    26  		// check with unsupported version numbers from the wiki
    27  		Expect(Version(0x51303039).String()).To(Equal("gQUIC 9"))
    28  		Expect(Version(0x51303133).String()).To(Equal("gQUIC 13"))
    29  		Expect(Version(0x51303235).String()).To(Equal("gQUIC 25"))
    30  		Expect(Version(0x51303438).String()).To(Equal("gQUIC 48"))
    31  		Expect(Version(0x01234567).String()).To(Equal("0x1234567"))
    32  	})
    33  
    34  	It("recognizes supported versions", func() {
    35  		Expect(IsSupportedVersion(SupportedVersions, 0)).To(BeFalse())
    36  		Expect(IsSupportedVersion(SupportedVersions, SupportedVersions[0])).To(BeTrue())
    37  		Expect(IsSupportedVersion(SupportedVersions, SupportedVersions[len(SupportedVersions)-1])).To(BeTrue())
    38  	})
    39  
    40  	Context("highest supported version", func() {
    41  		It("finds the supported version", func() {
    42  			supportedVersions := []Version{1, 2, 3}
    43  			other := []Version{6, 5, 4, 3}
    44  			ver, ok := ChooseSupportedVersion(supportedVersions, other)
    45  			Expect(ok).To(BeTrue())
    46  			Expect(ver).To(Equal(Version(3)))
    47  		})
    48  
    49  		It("picks the preferred version", func() {
    50  			supportedVersions := []Version{2, 1, 3}
    51  			other := []Version{3, 6, 1, 8, 2, 10}
    52  			ver, ok := ChooseSupportedVersion(supportedVersions, other)
    53  			Expect(ok).To(BeTrue())
    54  			Expect(ver).To(Equal(Version(2)))
    55  		})
    56  
    57  		It("says when no matching version was found", func() {
    58  			_, ok := ChooseSupportedVersion([]Version{1}, []Version{2})
    59  			Expect(ok).To(BeFalse())
    60  		})
    61  
    62  		It("handles empty inputs", func() {
    63  			_, ok := ChooseSupportedVersion([]Version{102, 101}, []Version{})
    64  			Expect(ok).To(BeFalse())
    65  			_, ok = ChooseSupportedVersion([]Version{}, []Version{1, 2})
    66  			Expect(ok).To(BeFalse())
    67  			_, ok = ChooseSupportedVersion([]Version{}, []Version{})
    68  			Expect(ok).To(BeFalse())
    69  		})
    70  	})
    71  
    72  	Context("reserved versions", func() {
    73  		It("adds a greased version if passed an empty slice", func() {
    74  			greased := GetGreasedVersions([]Version{})
    75  			Expect(greased).To(HaveLen(1))
    76  			Expect(isReservedVersion(greased[0])).To(BeTrue())
    77  		})
    78  
    79  		It("creates greased lists of version numbers", func() {
    80  			supported := []Version{10, 18, 29}
    81  			for _, v := range supported {
    82  				Expect(isReservedVersion(v)).To(BeFalse())
    83  			}
    84  			var greasedVersionFirst, greasedVersionLast, greasedVersionMiddle int
    85  			// check that
    86  			// 1. the greased version sometimes appears first
    87  			// 2. the greased version sometimes appears in the middle
    88  			// 3. the greased version sometimes appears last
    89  			// 4. the supported versions are kept in order
    90  			for i := 0; i < 100; i++ {
    91  				greased := GetGreasedVersions(supported)
    92  				Expect(greased).To(HaveLen(4))
    93  				var j int
    94  				for i, v := range greased {
    95  					if isReservedVersion(v) {
    96  						if i == 0 {
    97  							greasedVersionFirst++
    98  						}
    99  						if i == len(greased)-1 {
   100  							greasedVersionLast++
   101  						}
   102  						greasedVersionMiddle++
   103  						continue
   104  					}
   105  					Expect(supported[j]).To(Equal(v))
   106  					j++
   107  				}
   108  			}
   109  			Expect(greasedVersionFirst).ToNot(BeZero())
   110  			Expect(greasedVersionLast).ToNot(BeZero())
   111  			Expect(greasedVersionMiddle).ToNot(BeZero())
   112  		})
   113  	})
   114  })