github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/uuid/uuid_test.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru> 12 // Use of this source code is governed by a MIT-style 13 // license that can be found in licenses/MIT-gofrs.txt. 14 15 // This code originated in github.com/gofrs/uuid. 16 17 package uuid 18 19 import ( 20 "bytes" 21 "fmt" 22 "math" 23 "testing" 24 "time" 25 26 "github.com/cockroachdb/errors" 27 ) 28 29 func TestUUID(t *testing.T) { 30 t.Run("Bytes", testUUIDBytes) 31 t.Run("String", testUUIDString) 32 t.Run("Version", testUUIDVersion) 33 t.Run("Variant", testUUIDVariant) 34 t.Run("SetVersion", testUUIDSetVersion) 35 t.Run("SetVariant", testUUIDSetVariant) 36 } 37 38 func testUUIDBytes(t *testing.T) { 39 got := codecTestUUID.GetBytes() 40 want := codecTestData 41 if !bytes.Equal(got, want) { 42 t.Errorf("%v.GetBytes() = %x, want %x", codecTestUUID, got, want) 43 } 44 } 45 46 func testUUIDString(t *testing.T) { 47 got := NamespaceDNS.String() 48 want := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 49 if got != want { 50 t.Errorf("%v.String() = %q, want %q", NamespaceDNS, got, want) 51 } 52 } 53 54 func testUUIDVersion(t *testing.T) { 55 u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 56 if got, want := u.Version(), V1; got != want { 57 t.Errorf("%v.Version() == %d, want %d", u, got, want) 58 } 59 } 60 61 func testUUIDVariant(t *testing.T) { 62 tests := []struct { 63 u UUID 64 want byte 65 }{ 66 { 67 u: UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 68 want: VariantNCS, 69 }, 70 { 71 u: UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 72 want: VariantRFC4122, 73 }, 74 { 75 u: UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 76 want: VariantMicrosoft, 77 }, 78 { 79 u: UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 80 want: VariantFuture, 81 }, 82 } 83 for _, tt := range tests { 84 if got := tt.u.Variant(); got != tt.want { 85 t.Errorf("%v.Variant() == %d, want %d", tt.u, got, tt.want) 86 } 87 } 88 } 89 90 func testUUIDSetVersion(t *testing.T) { 91 u := UUID{} 92 want := V4 93 u.SetVersion(want) 94 if got := u.Version(); got != want { 95 t.Errorf("%v.Version() == %d after SetVersion(%d)", u, got, want) 96 } 97 } 98 99 func testUUIDSetVariant(t *testing.T) { 100 variants := []byte{ 101 VariantNCS, 102 VariantRFC4122, 103 VariantMicrosoft, 104 VariantFuture, 105 } 106 for _, want := range variants { 107 u := UUID{} 108 u.SetVariant(want) 109 if got := u.Variant(); got != want { 110 t.Errorf("%v.Variant() == %d after SetVariant(%d)", u, got, want) 111 } 112 } 113 } 114 115 func TestMust(t *testing.T) { 116 sentinel := fmt.Errorf("uuid: sentinel error") 117 defer func() { 118 r := recover() 119 if r == nil { 120 t.Fatalf("did not panic, want %v", sentinel) 121 } 122 err, ok := r.(error) 123 if !ok { 124 t.Fatalf("panicked with %T, want error (%v)", r, sentinel) 125 } 126 if !errors.Is(err, sentinel) { 127 t.Fatalf("panicked with %v, want %v", err, sentinel) 128 } 129 }() 130 fn := func() (UUID, error) { 131 return Nil, sentinel 132 } 133 Must(fn()) 134 } 135 136 func TestTimeFromTimestamp(t *testing.T) { 137 tests := []struct { 138 t Timestamp 139 want time.Time 140 }{ 141 // a zero timestamp represents October 15, 1582 at midnight UTC 142 {t: Timestamp(0), want: time.Date(1582, 10, 15, 0, 0, 0, 0, time.UTC)}, 143 // a one value is 100ns later 144 {t: Timestamp(1), want: time.Date(1582, 10, 15, 0, 0, 0, 100, time.UTC)}, 145 // 10 million 100ns intervals later is one second 146 {t: Timestamp(10000000), want: time.Date(1582, 10, 15, 0, 0, 1, 0, time.UTC)}, 147 {t: Timestamp(60 * 10000000), want: time.Date(1582, 10, 15, 0, 1, 0, 0, time.UTC)}, 148 {t: Timestamp(60 * 60 * 10000000), want: time.Date(1582, 10, 15, 1, 0, 0, 0, time.UTC)}, 149 {t: Timestamp(24 * 60 * 60 * 10000000), want: time.Date(1582, 10, 16, 0, 0, 0, 0, time.UTC)}, 150 {t: Timestamp(365 * 24 * 60 * 60 * 10000000), want: time.Date(1583, 10, 15, 0, 0, 0, 0, time.UTC)}, 151 // maximum timestamp value in a UUID is the year 5236 152 {t: Timestamp(uint64(1<<60 - 1)), want: time.Date(5236, 03, 31, 21, 21, 0, 684697500, time.UTC)}, 153 } 154 for _, tt := range tests { 155 got, _ := tt.t.Time() 156 if !got.Equal(tt.want) { 157 t.Errorf("%v.Time() == %v, want %v", tt.t, got, tt.want) 158 } 159 } 160 } 161 162 func TestTimestampFromV1(t *testing.T) { 163 tests := []struct { 164 u UUID 165 want Timestamp 166 wanterr bool 167 }{ 168 {u: Must(NewV4()), wanterr: true}, 169 {u: Must(FromString("00000000-0000-1000-0000-000000000000")), want: 0}, 170 {u: Must(FromString("424f137e-a2aa-11e8-98d0-529269fb1459")), want: 137538640775418750}, 171 {u: Must(FromString("ffffffff-ffff-1fff-ffff-ffffffffffff")), want: Timestamp(1<<60 - 1)}, 172 } 173 for _, tt := range tests { 174 got, goterr := TimestampFromV1(tt.u) 175 if tt.wanterr && goterr == nil { 176 t.Errorf("TimestampFromV1(%v) want error, got %v", tt.u, got) 177 } else if tt.want != got { 178 t.Errorf("TimestampFromV1(%v) got %v, want %v", tt.u, got, tt.want) 179 } 180 } 181 } 182 183 func TestDeterministicV4(t *testing.T) { 184 // Test sortedness by enumerating everything in a small `n`. 185 var previous, current UUID 186 for i := 0; i < 10; i++ { 187 current.DeterministicV4(uint64(i), uint64(10)) 188 if bytes.Compare(previous[:], current[:]) >= 0 { 189 t.Errorf(`%s should be less than %s`, previous, current) 190 } 191 copy(previous[:], current[:]) 192 } 193 194 // Test uniqueness by enumerating adjacent `i`s in a big `n`. 195 previous, current = UUID{}, UUID{} 196 for i := 0; i < 10; i++ { 197 current.DeterministicV4(uint64(i), math.MaxUint64) 198 if bytes.Compare(previous[:], current[:]) >= 0 { 199 t.Errorf(`%s should be less than %s`, previous, current) 200 } 201 copy(previous[:], current[:]) 202 } 203 }