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  }