From 0b46617fdb2f15ee280d1221c3c48946f1794300 Mon Sep 17 00:00:00 2001 From: Chris Molozian Date: Sat, 29 Dec 2018 22:07:16 +0000 Subject: [PATCH] Update 'uuid' dependency. --- Gopkg.lock | 6 +- Gopkg.toml | 2 +- vendor/github.com/gofrs/uuid/.gitignore | 13 + vendor/github.com/gofrs/uuid/.travis.yml | 28 +- vendor/github.com/gofrs/uuid/README.md | 2 +- vendor/github.com/gofrs/uuid/codec.go | 8 +- vendor/github.com/gofrs/uuid/generator.go | 66 +++-- .../github.com/gofrs/uuid/generator_test.go | 43 ++- vendor/github.com/gofrs/uuid/go.mod | 1 + vendor/github.com/gofrs/uuid/sql.go | 31 +++ vendor/github.com/gofrs/uuid/sql_test.go | 260 ++++++++++++++---- vendor/github.com/gofrs/uuid/uuid.go | 38 ++- vendor/github.com/gofrs/uuid/uuid_test.go | 57 +++- 13 files changed, 440 insertions(+), 115 deletions(-) create mode 100644 vendor/github.com/gofrs/uuid/go.mod diff --git a/Gopkg.lock b/Gopkg.lock index 13d3d389d..81a29f3a3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -168,12 +168,12 @@ version = "v1.12.0" [[projects]] - digest = "1:181fe10dcb708edd7c68c5781928b6657612771f81dd1773287386b6982c94e2" + digest = "1:660175e70abad3868119f2c29f43339608d7d3b93c8eb178b812ed330be6c07b" name = "github.com/gofrs/uuid" packages = ["."] pruneopts = "" - revision = "3a54a6416087bae7aa0ac32dd79fe1bf87bc99e4" - version = "v2.1.0" + revision = "7077aa61129615a0d7f45c49101cd011ab221c27" + version = "v3.1.2" [[projects]] digest = "1:f958a1c137db276e52f0b50efee41a1a389dcdded59a69711f3e872757dab34b" diff --git a/Gopkg.toml b/Gopkg.toml index 55e38bed8..48988e0aa 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -12,7 +12,7 @@ [[constraint]] name = "github.com/gofrs/uuid" - version = "~2.1.0" + version = "~3.1.2" [[constraint]] name = "github.com/rubenv/sql-migrate" diff --git a/vendor/github.com/gofrs/uuid/.gitignore b/vendor/github.com/gofrs/uuid/.gitignore index 3dd14d71f..666dbbb5b 100644 --- a/vendor/github.com/gofrs/uuid/.gitignore +++ b/vendor/github.com/gofrs/uuid/.gitignore @@ -1,2 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + # binary bundle generated by go-fuzz uuid-fuzz.zip diff --git a/vendor/github.com/gofrs/uuid/.travis.yml b/vendor/github.com/gofrs/uuid/.travis.yml index bb43fd29c..27df964c6 100644 --- a/vendor/github.com/gofrs/uuid/.travis.yml +++ b/vendor/github.com/gofrs/uuid/.travis.yml @@ -1,19 +1,23 @@ language: go sudo: false go: - - 1.7 - - 1.8 - - 1.9 - - "1.10" - - tip + - 1.7 + - 1.8 + - 1.9 + - "1.10" + - 1.11 + - tip matrix: - allow_failures: - - go: tip - fast_finish: true + allow_failures: + - go: tip + fast_finish: true +env: + - GO111MODULE=on before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover + - go get golang.org/x/tools/cmd/cover script: - - $HOME/gopath/bin/goveralls -service=travis-ci + - go test ./... -race -coverprofile=coverage.txt -covermode=atomic +after_success: + - bash <(curl -s https://codecov.io/bash) notifications: - email: false + email: false diff --git a/vendor/github.com/gofrs/uuid/README.md b/vendor/github.com/gofrs/uuid/README.md index e1e2b2eb3..1a381da7f 100644 --- a/vendor/github.com/gofrs/uuid/README.md +++ b/vendor/github.com/gofrs/uuid/README.md @@ -3,7 +3,7 @@ [![License](https://img.shields.io/github/license/gofrs/uuid.svg)](https://github.com/gofrs/uuid/blob/master/LICENSE) [![Build Status](https://travis-ci.org/gofrs/uuid.svg?branch=master)](https://travis-ci.org/gofrs/uuid) [![GoDoc](http://godoc.org/github.com/gofrs/uuid?status.svg)](http://godoc.org/github.com/gofrs/uuid) -[![Coverage Status](https://coveralls.io/repos/github/gofrs/uuid/badge.svg?branch=master)](https://coveralls.io/github/gofrs/uuid) +[![Coverage Status](https://codecov.io/gh/gofrs/uuid/branch/master/graphs/badge.svg?branch=master)](https://codecov.io/gh/gofrs/uuid/) [![Go Report Card](https://goreportcard.com/badge/github.com/gofrs/uuid)](https://goreportcard.com/report/github.com/gofrs/uuid) Package uuid provides a pure Go implementation of Universally Unique Identifiers diff --git a/vendor/github.com/gofrs/uuid/codec.go b/vendor/github.com/gofrs/uuid/codec.go index 2f03b976e..4e06d8ac8 100644 --- a/vendor/github.com/gofrs/uuid/codec.go +++ b/vendor/github.com/gofrs/uuid/codec.go @@ -125,7 +125,7 @@ func (u *UUID) decodeCanonical(t []byte) error { return fmt.Errorf("uuid: incorrect UUID format %s", t) } - src := t[:] + src := t dst := u[:] for i, byteGroup := range byteGroups { @@ -149,10 +149,8 @@ func (u *UUID) decodeHashLike(t []byte) error { src := t[:] dst := u[:] - if _, err := hex.Decode(dst, src); err != nil { - return err - } - return nil + _, err := hex.Decode(dst, src) + return err } // decodeBraced decodes UUID strings that are using the following formats: diff --git a/vendor/github.com/gofrs/uuid/generator.go b/vendor/github.com/gofrs/uuid/generator.go index 92ae02549..4257761f1 100644 --- a/vendor/github.com/gofrs/uuid/generator.go +++ b/vendor/github.com/gofrs/uuid/generator.go @@ -40,10 +40,12 @@ import ( const epochStart = 122192928000000000 type epochFunc func() time.Time -type hwAddrFunc func() (net.HardwareAddr, error) -// DefaultGenerator is the default Generator used. -var DefaultGenerator = newRFC4122Generator() +// HWAddrFunc is the function type used to provide hardware (MAC) addresses. +type HWAddrFunc func() (net.HardwareAddr, error) + +// DefaultGenerator is the default UUID Generator used by this package. +var DefaultGenerator Generator = NewGen() var ( posixUID = uint32(os.Getuid()) @@ -84,8 +86,18 @@ type Generator interface { NewV5(ns UUID, name string) UUID } -// Default generator implementation. -type rfc4122Generator struct { +// Gen is a reference UUID generator based on the specifications laid out in +// RFC-4122 and DCE 1.1: Authentication and Security Services. This type +// satisfies the Generator interface as defined in this package. +// +// For consumers who are generating V1 UUIDs, but don't want to expose the MAC +// address of the node generating the UUIDs, the NewGenWithHWAF() function has been +// provided as a convenience. See the function's documentation for more info. +// +// The authors of this package do not feel that the majority of users will need +// to obfuscate their MAC address, and so we recommend using NewGen() to create +// a new generator. +type Gen struct { clockSequenceOnce sync.Once hardwareAddrOnce sync.Once storageMutex sync.Mutex @@ -93,22 +105,42 @@ type rfc4122Generator struct { rand io.Reader epochFunc epochFunc - hwAddrFunc hwAddrFunc + hwAddrFunc HWAddrFunc lastTime uint64 clockSequence uint16 hardwareAddr [6]byte } -func newRFC4122Generator() Generator { - return &rfc4122Generator{ +// interface check -- build will fail if *Gen doesn't satisfy Generator +var _ Generator = (*Gen)(nil) + +// NewGen returns a new instance of Gen with some default values set. Most +// people should use this. +func NewGen() *Gen { + return NewGenWithHWAF(defaultHWAddrFunc) +} + +// NewGenWithHWAF builds a new UUID generator with the HWAddrFunc provided. Most +// consumers should use NewGen() instead. +// +// This is used so that consumers can generate their own MAC addresses, for use +// in the generated UUIDs, if there is some concern about exposing the physical +// address of the machine generating the UUID. +// +// The Gen generator will only invoke the HWAddrFunc once, and cache that MAC +// address for all the future UUIDs generated by it. If you'd like to switch the +// MAC address being used, you'll need to create a new generator using this +// function. +func NewGenWithHWAF(hwaf HWAddrFunc) *Gen { + return &Gen{ epochFunc: time.Now, - hwAddrFunc: defaultHWAddrFunc, + hwAddrFunc: hwaf, rand: rand.Reader, } } // NewV1 returns a UUID based on the current timestamp and MAC address. -func (g *rfc4122Generator) NewV1() (UUID, error) { +func (g *Gen) NewV1() (UUID, error) { u := UUID{} timeNow, clockSeq, err := g.getClockSequence() @@ -133,7 +165,7 @@ func (g *rfc4122Generator) NewV1() (UUID, error) { } // NewV2 returns a DCE Security UUID based on the POSIX UID/GID. -func (g *rfc4122Generator) NewV2(domain byte) (UUID, error) { +func (g *Gen) NewV2(domain byte) (UUID, error) { u, err := g.NewV1() if err != nil { return Nil, err @@ -155,7 +187,7 @@ func (g *rfc4122Generator) NewV2(domain byte) (UUID, error) { } // NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name. -func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID { +func (g *Gen) NewV3(ns UUID, name string) UUID { u := newFromHash(md5.New(), ns, name) u.SetVersion(V3) u.SetVariant(VariantRFC4122) @@ -164,7 +196,7 @@ func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID { } // NewV4 returns a randomly generated UUID. -func (g *rfc4122Generator) NewV4() (UUID, error) { +func (g *Gen) NewV4() (UUID, error) { u := UUID{} if _, err := io.ReadFull(g.rand, u[:]); err != nil { return Nil, err @@ -176,7 +208,7 @@ func (g *rfc4122Generator) NewV4() (UUID, error) { } // NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name. -func (g *rfc4122Generator) NewV5(ns UUID, name string) UUID { +func (g *Gen) NewV5(ns UUID, name string) UUID { u := newFromHash(sha1.New(), ns, name) u.SetVersion(V5) u.SetVariant(VariantRFC4122) @@ -185,7 +217,7 @@ func (g *rfc4122Generator) NewV5(ns UUID, name string) UUID { } // Returns the epoch and clock sequence. -func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) { +func (g *Gen) getClockSequence() (uint64, uint16, error) { var err error g.clockSequenceOnce.Do(func() { buf := make([]byte, 2) @@ -213,7 +245,7 @@ func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) { } // Returns the hardware address. -func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) { +func (g *Gen) getHardwareAddr() ([]byte, error) { var err error g.hardwareAddrOnce.Do(func() { var hwAddr net.HardwareAddr @@ -238,7 +270,7 @@ func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) { // Returns the difference between UUID epoch (October 15, 1582) // and current time in 100-nanosecond intervals. -func (g *rfc4122Generator) getEpoch() uint64 { +func (g *Gen) getEpoch() uint64 { return epochStart + uint64(g.epochFunc().UnixNano()/100) } diff --git a/vendor/github.com/gofrs/uuid/generator_test.go b/vendor/github.com/gofrs/uuid/generator_test.go index c5c62df57..35b59b78a 100644 --- a/vendor/github.com/gofrs/uuid/generator_test.go +++ b/vendor/github.com/gofrs/uuid/generator_test.go @@ -47,6 +47,35 @@ func testNewV1(t *testing.T) { t.Run("MissingNetworkFaultyRand", testNewV1MissingNetworkFaultyRand) } +func TestNewGenWithHWAF(t *testing.T) { + addr := []byte{0, 1, 2, 3, 4, 42} + + fn := func() (net.HardwareAddr, error) { + return addr, nil + } + + var g *Gen + var err error + var uuid UUID + + g = NewGenWithHWAF(fn) + + if g == nil { + t.Fatal("g is unexpectedly nil") + } + + uuid, err = g.NewV1() + if err != nil { + t.Fatalf("g.NewV1() err = %v, want ", err) + } + + node := uuid[10:] + + if !bytes.Equal(addr, node) { + t.Fatalf("node = %v, want %v", node, addr) + } +} + func testNewV1Basic(t *testing.T) { u, err := NewV1() if err != nil { @@ -75,7 +104,7 @@ func testNewV1DifferentAcrossCalls(t *testing.T) { } func testNewV1StaleEpoch(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: func() time.Time { return time.Unix(0, 0) }, @@ -96,7 +125,7 @@ func testNewV1StaleEpoch(t *testing.T) { } func testNewV1FaultyRand(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: time.Now, hwAddrFunc: defaultHWAddrFunc, rand: &faultyReader{ @@ -113,7 +142,7 @@ func testNewV1FaultyRand(t *testing.T) { } func testNewV1MissingNetwork(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: time.Now, hwAddrFunc: func() (net.HardwareAddr, error) { return []byte{}, fmt.Errorf("uuid: no hw address found") @@ -127,7 +156,7 @@ func testNewV1MissingNetwork(t *testing.T) { } func testNewV1MissingNetworkFaultyRand(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: time.Now, hwAddrFunc: func() (net.HardwareAddr, error) { return []byte{}, fmt.Errorf("uuid: no hw address found") @@ -183,7 +212,7 @@ func testNewV2DifferentAcrossCalls(t *testing.T) { } func testNewV2FaultyRand(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: time.Now, hwAddrFunc: defaultHWAddrFunc, rand: &faultyReader{ @@ -277,7 +306,7 @@ func testNewV4DifferentAcrossCalls(t *testing.T) { } func testNewV4FaultyRand(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: time.Now, hwAddrFunc: defaultHWAddrFunc, rand: &faultyReader{ @@ -291,7 +320,7 @@ func testNewV4FaultyRand(t *testing.T) { } func testNewV4ShortRandomRead(t *testing.T) { - g := &rfc4122Generator{ + g := &Gen{ epochFunc: time.Now, hwAddrFunc: func() (net.HardwareAddr, error) { return []byte{}, fmt.Errorf("uuid: no hw address found") diff --git a/vendor/github.com/gofrs/uuid/go.mod b/vendor/github.com/gofrs/uuid/go.mod new file mode 100644 index 000000000..1fd817707 --- /dev/null +++ b/vendor/github.com/gofrs/uuid/go.mod @@ -0,0 +1 @@ +module github.com/gofrs/uuid/v3 diff --git a/vendor/github.com/gofrs/uuid/sql.go b/vendor/github.com/gofrs/uuid/sql.go index 41219b769..6f254a4fd 100644 --- a/vendor/github.com/gofrs/uuid/sql.go +++ b/vendor/github.com/gofrs/uuid/sql.go @@ -22,7 +22,9 @@ package uuid import ( + "bytes" "database/sql/driver" + "encoding/json" "fmt" ) @@ -36,6 +38,10 @@ func (u UUID) Value() (driver.Value, error) { // a longer byte slice or a string will be handled by UnmarshalText. func (u *UUID) Scan(src interface{}) error { switch src := src.(type) { + case UUID: // support gorm convert from UUID to NullUUID + *u = src + return nil + case []byte: if len(src) == Size { return u.UnmarshalBinary(src) @@ -76,3 +82,28 @@ func (u *NullUUID) Scan(src interface{}) error { u.Valid = true return u.UUID.Scan(src) } + +// MarshalJSON marshals the NullUUID as null or the nested UUID +func (u NullUUID) MarshalJSON() ([]byte, error) { + if !u.Valid { + return json.Marshal(nil) + } + + return json.Marshal(u.UUID) +} + +// UnmarshalJSON unmarshals a NullUUID +func (u *NullUUID) UnmarshalJSON(b []byte) error { + if bytes.Equal(b, []byte("null")) { + u.UUID, u.Valid = Nil, false + return nil + } + + if err := json.Unmarshal(b, &u.UUID); err != nil { + return err + } + + u.Valid = true + + return nil +} diff --git a/vendor/github.com/gofrs/uuid/sql_test.go b/vendor/github.com/gofrs/uuid/sql_test.go index cf2757cc9..4aa22f7d1 100644 --- a/vendor/github.com/gofrs/uuid/sql_test.go +++ b/vendor/github.com/gofrs/uuid/sql_test.go @@ -21,7 +21,11 @@ package uuid -import "testing" +import ( + "encoding/json" + "fmt" + "testing" +) func TestSQL(t *testing.T) { t.Run("Value", testSQLValue) @@ -106,59 +110,211 @@ func testSQLScanNil(t *testing.T) { } func TestNullUUID(t *testing.T) { - t.Run("NilValue", func(t *testing.T) { - nu := NullUUID{} - got, err := nu.Value() - if got != nil { - t.Errorf("null NullUUID.Value returned non-nil driver.Value") - } - if err != nil { - t.Errorf("null NullUUID.Value returned non-nil error") - } + t.Run("Value", func(t *testing.T) { + t.Run("Nil", testNullUUIDValueNil) + t.Run("Valid", testNullUUIDValueValid) }) - t.Run("ValidValue", func(t *testing.T) { - nu := NullUUID{ - Valid: true, - UUID: codecTestUUID, - } - got, err := nu.Value() - if err != nil { - t.Fatal(err) - } - s, ok := got.(string) - if !ok { - t.Errorf("Value() returned %T, want string", got) - } - want := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" - if s != want { - t.Errorf("%v.Value() == %s, want %s", nu, s, want) - } + + t.Run("Scan", func(t *testing.T) { + t.Run("Nil", testNullUUIDScanNil) + t.Run("Valid", testNullUUIDScanValid) + t.Run("UUID", testNullUUIDScanUUID) }) - t.Run("ScanValid", func(t *testing.T) { - s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" - u := NullUUID{} - err := u.Scan(s) - if err != nil { - t.Fatal(err) - } - if !u.Valid { - t.Errorf("Valid == false after Scan(%q)", s) - } - if u.UUID != codecTestUUID { - t.Errorf("UUID == %v after Scan(%q), want %v", u.UUID, s, codecTestUUID) - } + + t.Run("MarshalJSON", func(t *testing.T) { + t.Run("Nil", testNullUUIDMarshalJSONNil) + t.Run("Null", testNullUUIDMarshalJSONNull) + t.Run("Valid", testNullUUIDMarshalJSONValid) }) - t.Run("ScanNil", func(t *testing.T) { - u := NullUUID{} - err := u.Scan(nil) - if err != nil { - t.Fatal(err) - } - if u.Valid { - t.Error("NullUUID is valid after Scan(nil)") - } - if u.UUID != Nil { - t.Errorf("NullUUID.UUID is %v after Scan(nil) want Nil", u.UUID) - } + + t.Run("UnmarshalJSON", func(t *testing.T) { + t.Run("Nil", testNullUUIDUnmarshalJSONNil) + t.Run("Null", testNullUUIDUnmarshalJSONNull) + t.Run("Valid", testNullUUIDUnmarshalJSONValid) + t.Run("Malformed", testNullUUIDUnmarshalJSONMalformed) }) } + +func testNullUUIDValueNil(t *testing.T) { + nu := NullUUID{} + got, err := nu.Value() + if got != nil { + t.Errorf("null NullUUID.Value returned non-nil driver.Value") + } + if err != nil { + t.Errorf("null NullUUID.Value returned non-nil error") + } +} + +func testNullUUIDValueValid(t *testing.T) { + nu := NullUUID{ + Valid: true, + UUID: codecTestUUID, + } + got, err := nu.Value() + if err != nil { + t.Fatal(err) + } + s, ok := got.(string) + if !ok { + t.Errorf("Value() returned %T, want string", got) + } + want := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + if s != want { + t.Errorf("%v.Value() == %s, want %s", nu, s, want) + } +} + +func testNullUUIDScanNil(t *testing.T) { + u := NullUUID{} + err := u.Scan(nil) + if err != nil { + t.Fatal(err) + } + if u.Valid { + t.Error("NullUUID is valid after Scan(nil)") + } + if u.UUID != Nil { + t.Errorf("NullUUID.UUID is %v after Scan(nil) want Nil", u.UUID) + } +} + +func testNullUUIDScanValid(t *testing.T) { + s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + u := NullUUID{} + err := u.Scan(s) + if err != nil { + t.Fatal(err) + } + if !u.Valid { + t.Errorf("Valid == false after Scan(%q)", s) + } + if u.UUID != codecTestUUID { + t.Errorf("UUID == %v after Scan(%q), want %v", u.UUID, s, codecTestUUID) + } +} + +func testNullUUIDScanUUID(t *testing.T) { + u := NullUUID{} + err := u.Scan(codecTestUUID) + if err != nil { + t.Fatal(err) + } + if !u.Valid { + t.Errorf("Valid == false after scan(%v)", codecTestUUID) + } + if u.UUID != codecTestUUID { + t.Errorf("UUID == %v after Scan(%v), want %v", u.UUID, codecTestUUID, codecTestUUID) + } +} + +func testNullUUIDMarshalJSONNil(t *testing.T) { + u := NullUUID{Valid: true} + + data, err := u.MarshalJSON() + if err != nil { + t.Fatalf("(%#v).MarshalJSON err want: , got: %v", u, err) + } + + dataStr := string(data) + + if dataStr != fmt.Sprintf("%q", Nil) { + t.Fatalf("(%#v).MarshalJSON value want: %s, got: %s", u, Nil, dataStr) + } +} + +func testNullUUIDMarshalJSONValid(t *testing.T) { + u := NullUUID{ + Valid: true, + UUID: codecTestUUID, + } + + data, err := u.MarshalJSON() + if err != nil { + t.Fatalf("(%#v).MarshalJSON err want: , got: %v", u, err) + } + + dataStr := string(data) + + if dataStr != fmt.Sprintf("%q", codecTestUUID) { + t.Fatalf("(%#v).MarshalJSON value want: %s, got: %s", u, codecTestUUID, dataStr) + } +} + +func testNullUUIDMarshalJSONNull(t *testing.T) { + u := NullUUID{} + + data, err := u.MarshalJSON() + if err != nil { + t.Fatalf("(%#v).MarshalJSON err want: , got: %v", u, err) + } + + dataStr := string(data) + + if dataStr != "null" { + t.Fatalf("(%#v).MarshalJSON value want: %s, got: %s", u, "null", dataStr) + } +} + +func testNullUUIDUnmarshalJSONNil(t *testing.T) { + var u NullUUID + + data := []byte(`"00000000-0000-0000-0000-000000000000"`) + + if err := json.Unmarshal(data, &u); err != nil { + t.Fatalf("json.Unmarshal err = %v, want ", err) + } + + if !u.Valid { + t.Fatalf("u.Valid = false, want true") + } + + if u.UUID != Nil { + t.Fatalf("u.UUID = %v, want %v", u.UUID, Nil) + } +} + +func testNullUUIDUnmarshalJSONNull(t *testing.T) { + var u NullUUID + + data := []byte(`null`) + + if err := json.Unmarshal(data, &u); err != nil { + t.Fatalf("json.Unmarshal err = %v, want ", err) + } + + if u.Valid { + t.Fatalf("u.Valid = true, want false") + } + + if u.UUID != Nil { + t.Fatalf("u.UUID = %v, want %v", u.UUID, Nil) + } +} +func testNullUUIDUnmarshalJSONValid(t *testing.T) { + var u NullUUID + + data := []byte(`"6ba7b810-9dad-11d1-80b4-00c04fd430c8"`) + + if err := json.Unmarshal(data, &u); err != nil { + t.Fatalf("json.Unmarshal err = %v, want ", err) + } + + if !u.Valid { + t.Fatalf("u.Valid = false, want true") + } + + if u.UUID != codecTestUUID { + t.Fatalf("u.UUID = %v, want %v", u.UUID, Nil) + } +} + +func testNullUUIDUnmarshalJSONMalformed(t *testing.T) { + var u NullUUID + + data := []byte(`257`) + + if err := json.Unmarshal(data, &u); err == nil { + t.Fatal("json.Unmarshal err = , want error") + } +} diff --git a/vendor/github.com/gofrs/uuid/uuid.go b/vendor/github.com/gofrs/uuid/uuid.go index bc08b7a14..29ef44059 100644 --- a/vendor/github.com/gofrs/uuid/uuid.go +++ b/vendor/github.com/gofrs/uuid/uuid.go @@ -30,7 +30,10 @@ package uuid import ( + "encoding/binary" "encoding/hex" + "fmt" + "time" ) // Size of a UUID in bytes. @@ -64,6 +67,33 @@ const ( DomainOrg ) +// Timestamp is the count of 100-nanosecond intervals since 00:00:00.00, +// 15 October 1582 within a V1 UUID. This type has no meaning for V2-V5 +// UUIDs since they don't have an embedded timestamp. +type Timestamp uint64 + +const _100nsPerSecond = 10000000 + +// Time returns the UTC time.Time representation of a Timestamp +func (t Timestamp) Time() (time.Time, error) { + secs := uint64(t) / _100nsPerSecond + nsecs := 100 * (uint64(t) % _100nsPerSecond) + return time.Unix(int64(secs)-(epochStart/_100nsPerSecond), int64(nsecs)), nil +} + +// TimestampFromV1 returns the Timestamp embedded within a V1 UUID. +// Returns an error if the UUID is any version other than 1. +func TimestampFromV1(u UUID) (Timestamp, error) { + if u.Version() != 1 { + err := fmt.Errorf("uuid: %s is version %d, not version 1", u, u.Version()) + return 0, err + } + low := binary.BigEndian.Uint32(u[0:4]) + mid := binary.BigEndian.Uint16(u[4:6]) + hi := binary.BigEndian.Uint16(u[6:8]) & 0xfff + return Timestamp(uint64(low) + (uint64(mid) << 32) + (uint64(hi) << 48)), nil +} + // String parse helpers. var ( urnPrefix = []byte("urn:uuid:") @@ -82,14 +112,6 @@ var ( NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) ) -// Equal returns true if a and b are equivalent. -// -// Deprecated: this function is deprecated and will be removed in a future major -// version, as values of type UUID are directly comparable using `==`. -func Equal(a UUID, b UUID) bool { - return a == b -} - // Version returns the algorithm version used to generate the UUID. func (u UUID) Version() byte { return u[6] >> 4 diff --git a/vendor/github.com/gofrs/uuid/uuid_test.go b/vendor/github.com/gofrs/uuid/uuid_test.go index b0cda6aee..8bb13faa9 100644 --- a/vendor/github.com/gofrs/uuid/uuid_test.go +++ b/vendor/github.com/gofrs/uuid/uuid_test.go @@ -25,6 +25,7 @@ import ( "bytes" "fmt" "testing" + "time" ) func TestUUID(t *testing.T) { @@ -113,15 +114,6 @@ func testUUIDSetVariant(t *testing.T) { } } -func TestEqual(t *testing.T) { - if !Equal(NamespaceDNS, NamespaceDNS) { - t.Errorf("NamespaceDNS (%v) != NamespaceDNS (%v)", NamespaceDNS, NamespaceDNS) - } - if Equal(NamespaceDNS, NamespaceURL) { - t.Errorf("NamespaceDNS (%v) == NamespaceURL (%v)", NamespaceDNS, NamespaceURL) - } -} - func TestMust(t *testing.T) { sentinel := fmt.Errorf("uuid: sentinel error") defer func() { @@ -142,3 +134,50 @@ func TestMust(t *testing.T) { } Must(fn()) } + +func TestTimeFromTimestamp(t *testing.T) { + tests := []struct { + t Timestamp + want time.Time + }{ + // a zero timestamp represents October 15, 1582 at midnight UTC + {t: Timestamp(0), want: time.Date(1582, 10, 15, 0, 0, 0, 0, time.UTC)}, + // a one value is 100ns later + {t: Timestamp(1), want: time.Date(1582, 10, 15, 0, 0, 0, 100, time.UTC)}, + // 10 million 100ns intervals later is one second + {t: Timestamp(10000000), want: time.Date(1582, 10, 15, 0, 0, 1, 0, time.UTC)}, + {t: Timestamp(60 * 10000000), want: time.Date(1582, 10, 15, 0, 1, 0, 0, time.UTC)}, + {t: Timestamp(60 * 60 * 10000000), want: time.Date(1582, 10, 15, 1, 0, 0, 0, time.UTC)}, + {t: Timestamp(24 * 60 * 60 * 10000000), want: time.Date(1582, 10, 16, 0, 0, 0, 0, time.UTC)}, + {t: Timestamp(365 * 24 * 60 * 60 * 10000000), want: time.Date(1583, 10, 15, 0, 0, 0, 0, time.UTC)}, + // maximum timestamp value in a UUID is the year 5236 + {t: Timestamp(uint64(1<<60 - 1)), want: time.Date(5236, 03, 31, 21, 21, 0, 684697500, time.UTC)}, + } + for _, tt := range tests { + got, _ := tt.t.Time() + if !got.Equal(tt.want) { + t.Errorf("%v.Time() == %v, want %v", tt.t, got, tt.want) + } + } +} + +func TestTimestampFromV1(t *testing.T) { + tests := []struct { + u UUID + want Timestamp + wanterr bool + }{ + {u: Must(NewV4()), wanterr: true}, + {u: Must(FromString("00000000-0000-1000-0000-000000000000")), want: 0}, + {u: Must(FromString("424f137e-a2aa-11e8-98d0-529269fb1459")), want: 137538640775418750}, + {u: Must(FromString("ffffffff-ffff-1fff-ffff-ffffffffffff")), want: Timestamp(1<<60 - 1)}, + } + for _, tt := range tests { + got, goterr := TimestampFromV1(tt.u) + if tt.wanterr && goterr == nil { + t.Errorf("TimestampFromV1(%v) want error, got %v", tt.u, got) + } else if tt.want != got { + t.Errorf("TimestampFromV1(%v) got %v, want %v", tt.u, got, tt.want) + } + } +} -- GitLab