squash merge from dev branch

This commit is contained in:
Steve Brunton
2017-09-04 22:52:14 -04:00
parent 123cd935a3
commit ed916703c6
1058 changed files with 311598 additions and 3 deletions

View File

@@ -0,0 +1,8 @@
Before opening your pull request, please make sure that you've:
- [ ] [signed Uber's Contributor License Agreement](https://docs.google.com/a/uber.com/forms/d/1pAwS_-dA1KhPlfxzYLBqK6rsSWwRwH95OCCZrcsY5rk/viewform);
- [ ] added tests to cover your changes;
- [ ] run the test suite locally (`make test`); and finally,
- [ ] run the linters locally (`make lint`).
Thanks for your contribution!

21
vendor/go.uber.org/atomic/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,21 @@
sudo: false
language: go
go_import_path: go.uber.org/atomic
go:
- 1.5
- 1.6
- tip
cache:
directories:
- vendor
install:
- make install_ci
script:
- make test_ci
- scripts/test-ubergo.sh
- make lint
- travis_retry goveralls -coverprofile=cover.out -service=travis-ci

19
vendor/go.uber.org/atomic/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2016 Uber Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

64
vendor/go.uber.org/atomic/Makefile generated vendored Normal file
View File

@@ -0,0 +1,64 @@
PACKAGES := $(shell glide nv)
# Many Go tools take file globs or directories as arguments instead of packages.
PACKAGE_FILES ?= *.go
# The linting tools evolve with each Go version, so run them only on the latest
# stable release.
GO_VERSION := $(shell go version | cut -d " " -f 3)
GO_MINOR_VERSION := $(word 2,$(subst ., ,$(GO_VERSION)))
LINTABLE_MINOR_VERSIONS := 7 8
ifneq ($(filter $(LINTABLE_MINOR_VERSIONS),$(GO_MINOR_VERSION)),)
SHOULD_LINT := true
endif
export GO15VENDOREXPERIMENT=1
.PHONY: build
build:
go build -i $(PACKAGES)
.PHONY: install
install:
glide --version || go get github.com/Masterminds/glide
glide install
.PHONY: test
test:
go test -cover -race $(PACKAGES)
.PHONY: install_ci
install_ci: install
go get github.com/wadey/gocovmerge
go get github.com/mattn/goveralls
go get golang.org/x/tools/cmd/cover
ifdef SHOULD_LINT
go get github.com/golang/lint/golint
endif
.PHONY: lint
lint:
ifdef SHOULD_LINT
@rm -rf lint.log
@echo "Checking formatting..."
@gofmt -d -s $(PACKAGE_FILES) 2>&1 | tee lint.log
@echo "Checking vet..."
@$(foreach dir,$(PACKAGE_FILES),go tool vet $(dir) 2>&1 | tee -a lint.log;)
@echo "Checking lint..."
@$(foreach dir,$(PKGS),golint $(dir) 2>&1 | tee -a lint.log;)
@echo "Checking for unresolved FIXMEs..."
@git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log
@[ ! -s lint.log ]
else
@echo "Skipping linters on" $(GO_VERSION)
endif
.PHONY: test_ci
test_ci: install_ci build
./scripts/cover.sh $(shell go list $(PACKAGES))

34
vendor/go.uber.org/atomic/README.md generated vendored Normal file
View File

@@ -0,0 +1,34 @@
# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
Simple wrappers for primitive types to enforce atomic access.
## Installation
`go get -u go.uber.org/atomic`
## Usage
The standard library's `sync/atomic` is powerful, but it's easy to forget which
variables must be accessed atomically. `go.uber.org/atomic` preserves all the
functionality of the standard library, but wraps the primitive types to
provide a safer, more convenient API.
```go
var atom atomic.Uint32
atom.Store(42)
atom.Sub(2)
atom.CAS(40, 11)
```
See the [documentation][doc] for a complete API specification.
## Development Status
Stable.
<hr>
Released under the [MIT License](LICENSE.txt).
[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
[doc]: https://godoc.org/go.uber.org/atomic
[ci-img]: https://travis-ci.org/uber-go/atomic.svg?branch=master
[ci]: https://travis-ci.org/uber-go/atomic
[cov-img]: https://coveralls.io/repos/github/uber-go/atomic/badge.svg?branch=master
[cov]: https://coveralls.io/github/uber-go/atomic?branch=master

304
vendor/go.uber.org/atomic/atomic.go generated vendored Normal file
View File

@@ -0,0 +1,304 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package atomic provides simple wrappers around numerics to enforce atomic
// access.
package atomic
import (
"math"
"sync/atomic"
)
// Int32 is an atomic wrapper around an int32.
type Int32 struct{ v int32 }
// NewInt32 creates an Int32.
func NewInt32(i int32) *Int32 {
return &Int32{i}
}
// Load atomically loads the wrapped value.
func (i *Int32) Load() int32 {
return atomic.LoadInt32(&i.v)
}
// Add atomically adds to the wrapped int32 and returns the new value.
func (i *Int32) Add(n int32) int32 {
return atomic.AddInt32(&i.v, n)
}
// Sub atomically subtracts from the wrapped int32 and returns the new value.
func (i *Int32) Sub(n int32) int32 {
return atomic.AddInt32(&i.v, -n)
}
// Inc atomically increments the wrapped int32 and returns the new value.
func (i *Int32) Inc() int32 {
return i.Add(1)
}
// Dec atomically decrements the wrapped int32 and returns the new value.
func (i *Int32) Dec() int32 {
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
func (i *Int32) CAS(old, new int32) bool {
return atomic.CompareAndSwapInt32(&i.v, old, new)
}
// Store atomically stores the passed value.
func (i *Int32) Store(n int32) {
atomic.StoreInt32(&i.v, n)
}
// Swap atomically swaps the wrapped int32 and returns the old value.
func (i *Int32) Swap(n int32) int32 {
return atomic.SwapInt32(&i.v, n)
}
// Int64 is an atomic wrapper around an int64.
type Int64 struct{ v int64 }
// NewInt64 creates an Int64.
func NewInt64(i int64) *Int64 {
return &Int64{i}
}
// Load atomically loads the wrapped value.
func (i *Int64) Load() int64 {
return atomic.LoadInt64(&i.v)
}
// Add atomically adds to the wrapped int64 and returns the new value.
func (i *Int64) Add(n int64) int64 {
return atomic.AddInt64(&i.v, n)
}
// Sub atomically subtracts from the wrapped int64 and returns the new value.
func (i *Int64) Sub(n int64) int64 {
return atomic.AddInt64(&i.v, -n)
}
// Inc atomically increments the wrapped int64 and returns the new value.
func (i *Int64) Inc() int64 {
return i.Add(1)
}
// Dec atomically decrements the wrapped int64 and returns the new value.
func (i *Int64) Dec() int64 {
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
func (i *Int64) CAS(old, new int64) bool {
return atomic.CompareAndSwapInt64(&i.v, old, new)
}
// Store atomically stores the passed value.
func (i *Int64) Store(n int64) {
atomic.StoreInt64(&i.v, n)
}
// Swap atomically swaps the wrapped int64 and returns the old value.
func (i *Int64) Swap(n int64) int64 {
return atomic.SwapInt64(&i.v, n)
}
// Uint32 is an atomic wrapper around an uint32.
type Uint32 struct{ v uint32 }
// NewUint32 creates a Uint32.
func NewUint32(i uint32) *Uint32 {
return &Uint32{i}
}
// Load atomically loads the wrapped value.
func (i *Uint32) Load() uint32 {
return atomic.LoadUint32(&i.v)
}
// Add atomically adds to the wrapped uint32 and returns the new value.
func (i *Uint32) Add(n uint32) uint32 {
return atomic.AddUint32(&i.v, n)
}
// Sub atomically subtracts from the wrapped uint32 and returns the new value.
func (i *Uint32) Sub(n uint32) uint32 {
return atomic.AddUint32(&i.v, ^(n - 1))
}
// Inc atomically increments the wrapped uint32 and returns the new value.
func (i *Uint32) Inc() uint32 {
return i.Add(1)
}
// Dec atomically decrements the wrapped int32 and returns the new value.
func (i *Uint32) Dec() uint32 {
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
func (i *Uint32) CAS(old, new uint32) bool {
return atomic.CompareAndSwapUint32(&i.v, old, new)
}
// Store atomically stores the passed value.
func (i *Uint32) Store(n uint32) {
atomic.StoreUint32(&i.v, n)
}
// Swap atomically swaps the wrapped uint32 and returns the old value.
func (i *Uint32) Swap(n uint32) uint32 {
return atomic.SwapUint32(&i.v, n)
}
// Uint64 is an atomic wrapper around a uint64.
type Uint64 struct{ v uint64 }
// NewUint64 creates a Uint64.
func NewUint64(i uint64) *Uint64 {
return &Uint64{i}
}
// Load atomically loads the wrapped value.
func (i *Uint64) Load() uint64 {
return atomic.LoadUint64(&i.v)
}
// Add atomically adds to the wrapped uint64 and returns the new value.
func (i *Uint64) Add(n uint64) uint64 {
return atomic.AddUint64(&i.v, n)
}
// Sub atomically subtracts from the wrapped uint64 and returns the new value.
func (i *Uint64) Sub(n uint64) uint64 {
return atomic.AddUint64(&i.v, ^(n - 1))
}
// Inc atomically increments the wrapped uint64 and returns the new value.
func (i *Uint64) Inc() uint64 {
return i.Add(1)
}
// Dec atomically decrements the wrapped uint64 and returns the new value.
func (i *Uint64) Dec() uint64 {
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
func (i *Uint64) CAS(old, new uint64) bool {
return atomic.CompareAndSwapUint64(&i.v, old, new)
}
// Store atomically stores the passed value.
func (i *Uint64) Store(n uint64) {
atomic.StoreUint64(&i.v, n)
}
// Swap atomically swaps the wrapped uint64 and returns the old value.
func (i *Uint64) Swap(n uint64) uint64 {
return atomic.SwapUint64(&i.v, n)
}
// Bool is an atomic Boolean.
type Bool struct{ v uint32 }
// NewBool creates a Bool.
func NewBool(initial bool) *Bool {
return &Bool{boolToInt(initial)}
}
// Load atomically loads the Boolean.
func (b *Bool) Load() bool {
return truthy(atomic.LoadUint32(&b.v))
}
// Store atomically stores the passed value.
func (b *Bool) Store(new bool) {
atomic.StoreUint32(&b.v, boolToInt(new))
}
// Swap sets the given value and returns the previous value.
func (b *Bool) Swap(new bool) bool {
return truthy(atomic.SwapUint32(&b.v, boolToInt(new)))
}
// Toggle atomically negates the Boolean and returns the previous value.
func (b *Bool) Toggle() bool {
return truthy(atomic.AddUint32(&b.v, 1) - 1)
}
func truthy(n uint32) bool {
return n&1 == 1
}
func boolToInt(b bool) uint32 {
if b {
return 1
}
return 0
}
// Float64 is an atomic wrapper around float64.
type Float64 struct {
v uint64
}
// NewFloat64 creates a Float64.
func NewFloat64(f float64) *Float64 {
return &Float64{math.Float64bits(f)}
}
// Load atomically loads the wrapped value.
func (f *Float64) Load() float64 {
return math.Float64frombits(atomic.LoadUint64(&f.v))
}
// Store atomically stores the passed value.
func (f *Float64) Store(s float64) {
atomic.StoreUint64(&f.v, math.Float64bits(s))
}
// Add atomically adds to the wrapped float64 and returns the new value.
func (f *Float64) Add(s float64) float64 {
for {
old := f.Load()
new := old + s
if f.CAS(old, new) {
return new
}
}
}
// Sub atomically subtracts from the wrapped float64 and returns the new value.
func (f *Float64) Sub(s float64) float64 {
return f.Add(-s)
}
// CAS is an atomic compare-and-swap.
func (f *Float64) CAS(old, new float64) bool {
return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
}
// Value shadows the type of the same name from sync/atomic
// https://godoc.org/sync/atomic#Value
type Value struct{ atomic.Value }

147
vendor/go.uber.org/atomic/atomic_test.go generated vendored Normal file
View File

@@ -0,0 +1,147 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package atomic
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestInt32(t *testing.T) {
atom := NewInt32(42)
require.Equal(t, int32(42), atom.Load(), "Load didn't work.")
require.Equal(t, int32(46), atom.Add(4), "Add didn't work.")
require.Equal(t, int32(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, int32(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, int32(44), atom.Dec(), "Dec didn't work.")
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
require.Equal(t, int32(0), atom.Load(), "CAS didn't set the correct value.")
require.Equal(t, int32(0), atom.Swap(1), "Swap didn't return the old value.")
require.Equal(t, int32(1), atom.Load(), "Swap didn't set the correct value.")
atom.Store(42)
require.Equal(t, int32(42), atom.Load(), "Store didn't set the correct value.")
}
func TestInt64(t *testing.T) {
atom := NewInt64(42)
require.Equal(t, int64(42), atom.Load(), "Load didn't work.")
require.Equal(t, int64(46), atom.Add(4), "Add didn't work.")
require.Equal(t, int64(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, int64(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, int64(44), atom.Dec(), "Dec didn't work.")
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
require.Equal(t, int64(0), atom.Load(), "CAS didn't set the correct value.")
require.Equal(t, int64(0), atom.Swap(1), "Swap didn't return the old value.")
require.Equal(t, int64(1), atom.Load(), "Swap didn't set the correct value.")
atom.Store(42)
require.Equal(t, int64(42), atom.Load(), "Store didn't set the correct value.")
}
func TestUint32(t *testing.T) {
atom := NewUint32(42)
require.Equal(t, uint32(42), atom.Load(), "Load didn't work.")
require.Equal(t, uint32(46), atom.Add(4), "Add didn't work.")
require.Equal(t, uint32(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, uint32(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, uint32(44), atom.Dec(), "Dec didn't work.")
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
require.Equal(t, uint32(0), atom.Load(), "CAS didn't set the correct value.")
require.Equal(t, uint32(0), atom.Swap(1), "Swap didn't return the old value.")
require.Equal(t, uint32(1), atom.Load(), "Swap didn't set the correct value.")
atom.Store(42)
require.Equal(t, uint32(42), atom.Load(), "Store didn't set the correct value.")
}
func TestUint64(t *testing.T) {
atom := NewUint64(42)
require.Equal(t, uint64(42), atom.Load(), "Load didn't work.")
require.Equal(t, uint64(46), atom.Add(4), "Add didn't work.")
require.Equal(t, uint64(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, uint64(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, uint64(44), atom.Dec(), "Dec didn't work.")
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
require.Equal(t, uint64(0), atom.Load(), "CAS didn't set the correct value.")
require.Equal(t, uint64(0), atom.Swap(1), "Swap didn't return the old value.")
require.Equal(t, uint64(1), atom.Load(), "Swap didn't set the correct value.")
atom.Store(42)
require.Equal(t, uint64(42), atom.Load(), "Store didn't set the correct value.")
}
func TestBool(t *testing.T) {
atom := NewBool(false)
require.False(t, atom.Toggle(), "Expected swap to return previous value.")
require.True(t, atom.Load(), "Unexpected state after swap.")
atom.Store(false)
require.False(t, atom.Load(), "Unexpected state after store.")
prev := atom.Swap(false)
require.False(t, prev, "Expected Swap to return previous value.")
prev = atom.Swap(true)
require.False(t, prev, "Expected Swap to return previous value.")
}
func TestFloat64(t *testing.T) {
atom := NewFloat64(4.2)
require.Equal(t, float64(4.2), atom.Load(), "Load didn't work.")
require.True(t, atom.CAS(4.2, 0.5), "CAS didn't report a swap.")
require.Equal(t, float64(0.5), atom.Load(), "CAS didn't set the correct value.")
require.False(t, atom.CAS(0.0, 1.5), "CAS reported a swap.")
atom.Store(42.0)
require.Equal(t, float64(42.0), atom.Load(), "Store didn't set the correct value.")
require.Equal(t, float64(42.5), atom.Add(0.5), "Add didn't work.")
require.Equal(t, float64(42.0), atom.Sub(0.5), "Sub didn't work.")
}
func TestValue(t *testing.T) {
var v Value
assert.Nil(t, v.Load(), "initial Value is not nil")
v.Store(42)
assert.Equal(t, 42, v.Load())
v.Store(84)
assert.Equal(t, 84, v.Load())
assert.Panics(t, func() { v.Store("foo") })
}

43
vendor/go.uber.org/atomic/example_test.go generated vendored Normal file
View File

@@ -0,0 +1,43 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package atomic_test
import (
"fmt"
"go.uber.org/atomic"
)
func Example() {
// Uint32 is a thin wrapper around the primitive uint32 type.
var atom atomic.Uint32
// The wrapper ensures that all operations are atomic.
atom.Store(42)
fmt.Println(atom.Inc())
fmt.Println(atom.CAS(43, 0))
fmt.Println(atom.Load())
// Output:
// 43
// true
// 0
}

17
vendor/go.uber.org/atomic/glide.lock generated vendored Normal file
View File

@@ -0,0 +1,17 @@
hash: f14d51408e3e0e4f73b34e4039484c78059cd7fc5f4996fdd73db20dc8d24f53
updated: 2016-10-27T00:10:51.16960137-07:00
imports: []
testImports:
- name: github.com/davecgh/go-spew
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
subpackages:
- spew
- name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
subpackages:
- difflib
- name: github.com/stretchr/testify
version: d77da356e56a7428ad25149ca77381849a6a5232
subpackages:
- assert
- require

6
vendor/go.uber.org/atomic/glide.yaml generated vendored Normal file
View File

@@ -0,0 +1,6 @@
package: go.uber.org/atomic
testImport:
- package: github.com/stretchr/testify
subpackages:
- assert
- require

40
vendor/go.uber.org/atomic/scripts/cover.sh generated vendored Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
set -e
COVER=cover
ROOT_PKG=go.uber.org/atomic
if [[ -d "$COVER" ]]; then
rm -rf "$COVER"
fi
mkdir -p "$COVER"
i=0
for pkg in "$@"; do
i=$((i + 1))
extracoverpkg=""
if [[ -f "$GOPATH/src/$pkg/.extra-coverpkg" ]]; then
extracoverpkg=$( \
sed -e "s|^|$pkg/|g" < "$GOPATH/src/$pkg/.extra-coverpkg" \
| tr '\n' ',')
fi
coverpkg=$(go list -json "$pkg" | jq -r '
.Deps
| map(select(startswith("'"$ROOT_PKG"'")))
| map(select(contains("/vendor/") | not))
| . + ["'"$pkg"'"]
| join(",")
')
if [[ -n "$extracoverpkg" ]]; then
coverpkg="$extracoverpkg$coverpkg"
fi
go test \
-coverprofile "$COVER/cover.${i}.out" -coverpkg "$coverpkg" \
-v "$pkg"
done
gocovmerge "$COVER"/*.out > cover.out

26
vendor/go.uber.org/atomic/scripts/test-ubergo.sh generated vendored Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
set -euox pipefail
IFS=$'\n\t'
# This script creates a fake GOPATH, symlinks in the current
# directory as uber-go/atomic and verifies that tests still pass.
WORK_DIR=`mktemp -d`
function cleanup {
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
export GOPATH="$WORK_DIR"
PKG_PARENT="$WORK_DIR/src/github.com/uber-go"
PKG_DIR="$PKG_PARENT/atomic"
mkdir -p "$PKG_PARENT"
cp -R `pwd` "$PKG_DIR"
cd "$PKG_DIR"
# The example imports go.uber.org, fix the import.
sed -e 's/go.uber.org\/atomic/github.com\/uber-go\/atomic/' -i="" example_test.go
make test

140
vendor/go.uber.org/atomic/stress_test.go generated vendored Normal file
View File

@@ -0,0 +1,140 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package atomic
import (
"runtime"
"sync"
"testing"
)
const (
_parallelism = 4
_iterations = 1000
)
func runStress(f func()) {
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(_parallelism))
var wg sync.WaitGroup
wg.Add(_parallelism)
for i := 0; i < _parallelism; i++ {
go func() {
defer wg.Done()
for j := 0; j < _iterations; j++ {
f()
}
}()
}
wg.Wait()
}
func TestStressInt32(t *testing.T) {
var atom Int32
runStress(func() {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
atom.Swap(5)
atom.Store(1)
})
}
func TestStressInt64(t *testing.T) {
var atom Int64
runStress(func() {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
atom.Swap(5)
atom.Store(1)
})
}
func TestStressUint32(t *testing.T) {
var atom Uint32
runStress(func() {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
atom.Swap(5)
atom.Store(1)
})
}
func TestStressUint64(t *testing.T) {
var atom Uint64
runStress(func() {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
atom.Swap(5)
atom.Store(1)
})
}
func TestStressFloat64(t *testing.T) {
var atom Float64
runStress(func() {
atom.Load()
atom.CAS(1.0, 0.1)
atom.Add(1.1)
atom.Sub(0.2)
atom.Store(1.0)
})
}
func TestStressBool(t *testing.T) {
var atom Bool
runStress(func() {
atom.Load()
atom.Store(false)
atom.Swap(true)
atom.Load()
atom.Toggle()
atom.Toggle()
})
}
func TestStressString(t *testing.T) {
var atom String
runStress(func() {
atom.Load()
atom.Store("abc")
atom.Load()
atom.Store("def")
})
}

51
vendor/go.uber.org/atomic/string.go generated vendored Normal file
View File

@@ -0,0 +1,51 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package atomic
import "sync/atomic"
// String is an atomic type-safe wrapper around atomic.Value for strings.
type String struct{ v atomic.Value }
// NewString creates a String.
func NewString(str string) *String {
s := &String{}
if str != "" {
s.Store(str)
}
return s
}
// Load atomically loads the wrapped string.
func (s *String) Load() string {
v := s.v.Load()
if v == nil {
return ""
}
return v.(string)
}
// Store atomically stores the passed string.
// Note: Converting the string to an interface{} to store in the atomic.Value
// requires an allocation.
func (s *String) Store(str string) {
s.v.Store(str)
}

43
vendor/go.uber.org/atomic/string_test.go generated vendored Normal file
View File

@@ -0,0 +1,43 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package atomic
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestStringNoInitialValue(t *testing.T) {
atom := &String{}
require.Equal(t, "", atom.Load(), "Initial value should be blank string")
}
func TestString(t *testing.T) {
atom := NewString("")
require.Equal(t, "", atom.Load(), "Expected Load to return initialized value")
atom.Store("abc")
require.Equal(t, "abc", atom.Load(), "Unexpected value after Store")
atom = NewString("bcd")
require.Equal(t, "bcd", atom.Load(), "Expected Load to return initialized value")
}

15
vendor/go.uber.org/multierr/.codecov.yml generated vendored Normal file
View File

@@ -0,0 +1,15 @@
coverage:
range: 80..100
round: down
precision: 2
status:
project: # measuring the overall project coverage
default: # context, you can create multiple ones with custom titles
enabled: yes # must be yes|true to enable this status
target: 100 # specify the target coverage for each commit status
# option: "auto" (must increase from parent commit or pull request base)
# option: "X%" a static target percentage to hit
if_not_found: success # if parent is not found report status as success, error, or failure
if_ci_failed: error # if ci fails report status as success, error, or failure

33
vendor/go.uber.org/multierr/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,33 @@
sudo: false
language: go
go_import_path: go.uber.org/multierr
env:
global:
- GO15VENDOREXPERIMENT=1
go:
- 1.7
- 1.8
- tip
cache:
directories:
- vendor
before_install:
- go version
install:
- |
set -e
make install_ci
script:
- |
set -e
make lint
make test_ci
after_success:
- bash <(curl -s https://codecov.io/bash)

28
vendor/go.uber.org/multierr/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,28 @@
Releases
========
v1.1.0 (2017-06-30)
===================
- Added an `Errors(error) []error` function to extract the underlying list of
errors for a multierr error.
v1.0.0 (2017-05-31)
===================
No changes since v0.2.0. This release is committing to making no breaking
changes to the current API in the 1.X series.
v0.2.0 (2017-04-11)
===================
- Repeatedly appending to the same error is now faster due to fewer
allocations.
v0.1.0 (2017-31-03)
===================
- Initial release

19
vendor/go.uber.org/multierr/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2017 Uber Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

74
vendor/go.uber.org/multierr/Makefile generated vendored Normal file
View File

@@ -0,0 +1,74 @@
export GO15VENDOREXPERIMENT=1
PACKAGES := $(shell glide nv)
GO_FILES := $(shell \
find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
-o -name '*.go' -print | cut -b3-)
.PHONY: install
install:
glide --version || go get github.com/Masterminds/glide
glide install
.PHONY: build
build:
go build -i $(PACKAGES)
.PHONY: test
test:
go test -cover -race $(PACKAGES)
.PHONY: gofmt
gofmt:
$(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX))
@gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true
@[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false)
.PHONY: govet
govet:
$(eval VET_LOG := $(shell mktemp -t govet.XXXXX))
@go vet $(PACKAGES) 2>&1 \
| grep -v '^exit status' > $(VET_LOG) || true
@[ ! -s "$(VET_LOG)" ] || (echo "govet failed:" | cat - $(VET_LOG) && false)
.PHONY: golint
golint:
@go get github.com/golang/lint/golint
$(eval LINT_LOG := $(shell mktemp -t golint.XXXXX))
@cat /dev/null > $(LINT_LOG)
@$(foreach pkg, $(PACKAGES), golint $(pkg) >> $(LINT_LOG) || true;)
@[ ! -s "$(LINT_LOG)" ] || (echo "golint failed:" | cat - $(LINT_LOG) && false)
.PHONY: staticcheck
staticcheck:
@go get honnef.co/go/tools/cmd/staticcheck
$(eval STATICCHECK_LOG := $(shell mktemp -t staticcheck.XXXXX))
@staticcheck $(PACKAGES) 2>&1 > $(STATICCHECK_LOG) || true
@[ ! -s "$(STATICCHECK_LOG)" ] || (echo "staticcheck failed:" | cat - $(STATICCHECK_LOG) && false)
.PHONY: lint
lint: gofmt govet golint staticcheck
.PHONY: cover
cover:
./scripts/cover.sh $(shell go list $(PACKAGES))
go tool cover -html=cover.out -o cover.html
update-license:
@go get go.uber.org/tools/update-license
@update-license \
$(shell go list -json $(PACKAGES) | \
jq -r '.Dir + "/" + (.GoFiles | .[])')
##############################################################################
.PHONY: install_ci
install_ci: install
go get github.com/wadey/gocovmerge
go get github.com/mattn/goveralls
go get golang.org/x/tools/cmd/cover
.PHONY: test_ci
test_ci: install_ci
./scripts/cover.sh $(shell go list $(PACKAGES))

23
vendor/go.uber.org/multierr/README.md generated vendored Normal file
View File

@@ -0,0 +1,23 @@
# multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
`multierr` allows combining one or more Go `error`s together.
## Installation
go get -u go.uber.org/multierr
## Status
Stable: No breaking changes will be made before 2.0.
-------------------------------------------------------------------------------
Released under the [MIT License].
[MIT License]: LICENSE.txt
[doc-img]: https://godoc.org/go.uber.org/multierr?status.svg
[doc]: https://godoc.org/go.uber.org/multierr
[ci-img]: https://travis-ci.org/uber-go/multierr.svg?branch=master
[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
[ci]: https://travis-ci.org/uber-go/multierr
[cov]: https://codecov.io/gh/uber-go/multierr

62
vendor/go.uber.org/multierr/benchmarks_test.go generated vendored Normal file
View File

@@ -0,0 +1,62 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package multierr
import (
"errors"
"fmt"
"testing"
)
func BenchmarkAppend(b *testing.B) {
errorTypes := []struct {
name string
err error
}{
{
name: "nil",
err: nil,
},
{
name: "single error",
err: errors.New("test"),
},
{
name: "multiple errors",
err: appendN(nil, errors.New("err"), 10),
},
}
for _, initial := range errorTypes {
for _, v := range errorTypes {
msg := fmt.Sprintf("append %v to %v", v.name, initial.name)
b.Run(msg, func(b *testing.B) {
for _, appends := range []int{1, 2, 10} {
b.Run(fmt.Sprint(appends), func(b *testing.B) {
for i := 0; i < b.N; i++ {
appendN(initial.err, v.err, appends)
}
})
}
})
}
}
}

401
vendor/go.uber.org/multierr/error.go generated vendored Normal file
View File

@@ -0,0 +1,401 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package multierr allows combining one or more errors together.
//
// Overview
//
// Errors can be combined with the use of the Combine function.
//
// multierr.Combine(
// reader.Close(),
// writer.Close(),
// conn.Close(),
// )
//
// If only two errors are being combined, the Append function may be used
// instead.
//
// err = multierr.Combine(reader.Close(), writer.Close())
//
// This makes it possible to record resource cleanup failures from deferred
// blocks with the help of named return values.
//
// func sendRequest(req Request) (err error) {
// conn, err := openConnection()
// if err != nil {
// return err
// }
// defer func() {
// err = multierr.Append(err, conn.Close())
// }()
// // ...
// }
//
// The underlying list of errors for a returned error object may be retrieved
// with the Errors function.
//
// errors := multierr.Errors(err)
// if len(errors) > 0 {
// fmt.Println("The following errors occurred:")
// }
//
// Advanced Usage
//
// Errors returned by Combine and Append MAY implement the following
// interface.
//
// type errorGroup interface {
// // Returns a slice containing the underlying list of errors.
// //
// // This slice MUST NOT be modified by the caller.
// Errors() []error
// }
//
// Note that if you need access to list of errors behind a multierr error, you
// should prefer using the Errors function. That said, if you need cheap
// read-only access to the underlying errors slice, you can attempt to cast
// the error to this interface. You MUST handle the failure case gracefully
// because errors returned by Combine and Append are not guaranteed to
// implement this interface.
//
// var errors []error
// group, ok := err.(errorGroup)
// if ok {
// errors = group.Errors()
// } else {
// errors = []error{err}
// }
package multierr // import "go.uber.org/multierr"
import (
"bytes"
"fmt"
"io"
"strings"
"sync"
"go.uber.org/atomic"
)
var (
// Separator for single-line error messages.
_singlelineSeparator = []byte("; ")
_newline = []byte("\n")
// Prefix for multi-line messages
_multilinePrefix = []byte("the following errors occurred:")
// Prefix for the first and following lines of an item in a list of
// multi-line error messages.
//
// For example, if a single item is:
//
// foo
// bar
//
// It will become,
//
// - foo
// bar
_multilineSeparator = []byte("\n - ")
_multilineIndent = []byte(" ")
)
// _bufferPool is a pool of bytes.Buffers.
var _bufferPool = sync.Pool{
New: func() interface{} {
return &bytes.Buffer{}
},
}
type errorGroup interface {
Errors() []error
}
// Errors returns a slice containing zero or more errors that the supplied
// error is composed of. If the error is nil, the returned slice is empty.
//
// err := multierr.Append(r.Close(), w.Close())
// errors := multierr.Errors(err)
//
// If the error is not composed of other errors, the returned slice contains
// just the error that was passed in.
//
// Callers of this function are free to modify the returned slice.
func Errors(err error) []error {
if err == nil {
return nil
}
// Note that we're casting to multiError, not errorGroup. Our contract is
// that returned errors MAY implement errorGroup. Errors, however, only
// has special behavior for multierr-specific error objects.
//
// This behavior can be expanded in the future but I think it's prudent to
// start with as little as possible in terms of contract and possibility
// of misuse.
eg, ok := err.(*multiError)
if !ok {
return []error{err}
}
errors := eg.Errors()
result := make([]error, len(errors))
copy(result, errors)
return result
}
// multiError is an error that holds one or more errors.
//
// An instance of this is guaranteed to be non-empty and flattened. That is,
// none of the errors inside multiError are other multiErrors.
//
// multiError formats to a semi-colon delimited list of error messages with
// %v and with a more readable multi-line format with %+v.
type multiError struct {
copyNeeded atomic.Bool
errors []error
}
var _ errorGroup = (*multiError)(nil)
// Errors returns the list of underlying errors.
//
// This slice MUST NOT be modified.
func (merr *multiError) Errors() []error {
if merr == nil {
return nil
}
return merr.errors
}
func (merr *multiError) Error() string {
if merr == nil {
return ""
}
buff := _bufferPool.Get().(*bytes.Buffer)
buff.Reset()
merr.writeSingleline(buff)
result := buff.String()
_bufferPool.Put(buff)
return result
}
func (merr *multiError) Format(f fmt.State, c rune) {
if c == 'v' && f.Flag('+') {
merr.writeMultiline(f)
} else {
merr.writeSingleline(f)
}
}
func (merr *multiError) writeSingleline(w io.Writer) {
first := true
for _, item := range merr.errors {
if first {
first = false
} else {
w.Write(_singlelineSeparator)
}
io.WriteString(w, item.Error())
}
}
func (merr *multiError) writeMultiline(w io.Writer) {
w.Write(_multilinePrefix)
for _, item := range merr.errors {
w.Write(_multilineSeparator)
writePrefixLine(w, _multilineIndent, fmt.Sprintf("%+v", item))
}
}
// Writes s to the writer with the given prefix added before each line after
// the first.
func writePrefixLine(w io.Writer, prefix []byte, s string) {
first := true
for len(s) > 0 {
if first {
first = false
} else {
w.Write(prefix)
}
idx := strings.IndexByte(s, '\n')
if idx < 0 {
idx = len(s) - 1
}
io.WriteString(w, s[:idx+1])
s = s[idx+1:]
}
}
type inspectResult struct {
// Number of top-level non-nil errors
Count int
// Total number of errors including multiErrors
Capacity int
// Index of the first non-nil error in the list. Value is meaningless if
// Count is zero.
FirstErrorIdx int
// Whether the list contains at least one multiError
ContainsMultiError bool
}
// Inspects the given slice of errors so that we can efficiently allocate
// space for it.
func inspect(errors []error) (res inspectResult) {
first := true
for i, err := range errors {
if err == nil {
continue
}
res.Count++
if first {
first = false
res.FirstErrorIdx = i
}
if merr, ok := err.(*multiError); ok {
res.Capacity += len(merr.errors)
res.ContainsMultiError = true
} else {
res.Capacity++
}
}
return
}
// fromSlice converts the given list of errors into a single error.
func fromSlice(errors []error) error {
res := inspect(errors)
switch res.Count {
case 0:
return nil
case 1:
// only one non-nil entry
return errors[res.FirstErrorIdx]
case len(errors):
if !res.ContainsMultiError {
// already flat
return &multiError{errors: errors}
}
}
nonNilErrs := make([]error, 0, res.Capacity)
for _, err := range errors[res.FirstErrorIdx:] {
if err == nil {
continue
}
if nested, ok := err.(*multiError); ok {
nonNilErrs = append(nonNilErrs, nested.errors...)
} else {
nonNilErrs = append(nonNilErrs, err)
}
}
return &multiError{errors: nonNilErrs}
}
// Combine combines the passed errors into a single error.
//
// If zero arguments were passed or if all items are nil, a nil error is
// returned.
//
// Combine(nil, nil) // == nil
//
// If only a single error was passed, it is returned as-is.
//
// Combine(err) // == err
//
// Combine skips over nil arguments so this function may be used to combine
// together errors from operations that fail independently of each other.
//
// multierr.Combine(
// reader.Close(),
// writer.Close(),
// pipe.Close(),
// )
//
// If any of the passed errors is a multierr error, it will be flattened along
// with the other errors.
//
// multierr.Combine(multierr.Combine(err1, err2), err3)
// // is the same as
// multierr.Combine(err1, err2, err3)
//
// The returned error formats into a readable multi-line error message if
// formatted with %+v.
//
// fmt.Sprintf("%+v", multierr.Combine(err1, err2))
func Combine(errors ...error) error {
return fromSlice(errors)
}
// Append appends the given errors together. Either value may be nil.
//
// This function is a specialization of Combine for the common case where
// there are only two errors.
//
// err = multierr.Append(reader.Close(), writer.Close())
//
// The following pattern may also be used to record failure of deferred
// operations without losing information about the original error.
//
// func doSomething(..) (err error) {
// f := acquireResource()
// defer func() {
// err = multierr.Append(err, f.Close())
// }()
func Append(left error, right error) error {
switch {
case left == nil:
return right
case right == nil:
return left
}
if _, ok := right.(*multiError); !ok {
if l, ok := left.(*multiError); ok && !l.copyNeeded.Swap(true) {
// Common case where the error on the left is constantly being
// appended to.
errs := append(l.errors, right)
return &multiError{errors: errs}
} else if !ok {
// Both errors are single errors.
return &multiError{errors: []error{left, right}}
}
}
// Either right or both, left and right, are multiErrors. Rely on usual
// expensive logic.
errors := [2]error{left, right}
return fromSlice(errors[0:])
}

511
vendor/go.uber.org/multierr/error_test.go generated vendored Normal file
View File

@@ -0,0 +1,511 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package multierr
import (
"errors"
"fmt"
"io"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// richFormatError is an error that prints a different output depending on
// whether %v or %+v was used.
type richFormatError struct{}
func (r richFormatError) Error() string {
return fmt.Sprint(r)
}
func (richFormatError) Format(f fmt.State, c rune) {
if c == 'v' && f.Flag('+') {
io.WriteString(f, "multiline\nmessage\nwith plus")
} else {
io.WriteString(f, "without plus")
}
}
func appendN(initial, err error, n int) error {
errs := initial
for i := 0; i < n; i++ {
errs = Append(errs, err)
}
return errs
}
func newMultiErr(errors ...error) error {
return &multiError{errors: errors}
}
func TestCombine(t *testing.T) {
tests := []struct {
// Input
giveErrors []error
// Resulting error
wantError error
// %+v and %v string representations
wantMultiline string
wantSingleline string
}{
{
giveErrors: nil,
wantError: nil,
},
{
giveErrors: []error{},
wantError: nil,
},
{
giveErrors: []error{
errors.New("foo"),
nil,
newMultiErr(
errors.New("bar"),
),
nil,
},
wantError: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - bar",
wantSingleline: "foo; bar",
},
{
giveErrors: []error{
errors.New("foo"),
newMultiErr(
errors.New("bar"),
),
},
wantError: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - bar",
wantSingleline: "foo; bar",
},
{
giveErrors: []error{errors.New("great sadness")},
wantError: errors.New("great sadness"),
wantMultiline: "great sadness",
wantSingleline: "great sadness",
},
{
giveErrors: []error{
errors.New("foo"),
errors.New("bar"),
},
wantError: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - bar",
wantSingleline: "foo; bar",
},
{
giveErrors: []error{
errors.New("great sadness"),
errors.New("multi\n line\nerror message"),
errors.New("single line error message"),
},
wantError: newMultiErr(
errors.New("great sadness"),
errors.New("multi\n line\nerror message"),
errors.New("single line error message"),
),
wantMultiline: "the following errors occurred:\n" +
" - great sadness\n" +
" - multi\n" +
" line\n" +
" error message\n" +
" - single line error message",
wantSingleline: "great sadness; " +
"multi\n line\nerror message; " +
"single line error message",
},
{
giveErrors: []error{
errors.New("foo"),
newMultiErr(
errors.New("bar"),
errors.New("baz"),
),
errors.New("qux"),
},
wantError: newMultiErr(
errors.New("foo"),
errors.New("bar"),
errors.New("baz"),
errors.New("qux"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - bar\n" +
" - baz\n" +
" - qux",
wantSingleline: "foo; bar; baz; qux",
},
{
giveErrors: []error{
errors.New("foo"),
nil,
newMultiErr(
errors.New("bar"),
),
nil,
},
wantError: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - bar",
wantSingleline: "foo; bar",
},
{
giveErrors: []error{
errors.New("foo"),
newMultiErr(
errors.New("bar"),
),
},
wantError: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - bar",
wantSingleline: "foo; bar",
},
{
giveErrors: []error{
errors.New("foo"),
richFormatError{},
errors.New("bar"),
},
wantError: newMultiErr(
errors.New("foo"),
richFormatError{},
errors.New("bar"),
),
wantMultiline: "the following errors occurred:\n" +
" - foo\n" +
" - multiline\n" +
" message\n" +
" with plus\n" +
" - bar",
wantSingleline: "foo; without plus; bar",
},
}
for i, tt := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
err := Combine(tt.giveErrors...)
require.Equal(t, tt.wantError, err)
if tt.wantMultiline != "" {
t.Run("Sprintf/multiline", func(t *testing.T) {
assert.Equal(t, tt.wantMultiline, fmt.Sprintf("%+v", err))
})
}
if tt.wantSingleline != "" {
t.Run("Sprintf/singleline", func(t *testing.T) {
assert.Equal(t, tt.wantSingleline, fmt.Sprintf("%v", err))
})
t.Run("Error()", func(t *testing.T) {
assert.Equal(t, tt.wantSingleline, err.Error())
})
if s, ok := err.(fmt.Stringer); ok {
t.Run("String()", func(t *testing.T) {
assert.Equal(t, tt.wantSingleline, s.String())
})
}
}
})
}
}
func TestCombineDoesNotModifySlice(t *testing.T) {
errors := []error{
errors.New("foo"),
nil,
errors.New("bar"),
}
assert.NotNil(t, Combine(errors...))
assert.Len(t, errors, 3)
assert.Nil(t, errors[1], 3)
}
func TestAppend(t *testing.T) {
tests := []struct {
left error
right error
want error
}{
{
left: nil,
right: nil,
want: nil,
},
{
left: nil,
right: errors.New("great sadness"),
want: errors.New("great sadness"),
},
{
left: errors.New("great sadness"),
right: nil,
want: errors.New("great sadness"),
},
{
left: errors.New("foo"),
right: errors.New("bar"),
want: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
},
{
left: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
right: errors.New("baz"),
want: newMultiErr(
errors.New("foo"),
errors.New("bar"),
errors.New("baz"),
),
},
{
left: errors.New("baz"),
right: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
want: newMultiErr(
errors.New("baz"),
errors.New("foo"),
errors.New("bar"),
),
},
{
left: newMultiErr(
errors.New("foo"),
),
right: newMultiErr(
errors.New("bar"),
),
want: newMultiErr(
errors.New("foo"),
errors.New("bar"),
),
},
}
for _, tt := range tests {
assert.Equal(t, tt.want, Append(tt.left, tt.right))
}
}
type notMultiErr struct{}
var _ errorGroup = notMultiErr{}
func (notMultiErr) Error() string {
return "great sadness"
}
func (notMultiErr) Errors() []error {
return []error{errors.New("great sadness")}
}
func TestErrors(t *testing.T) {
tests := []struct {
give error
want []error
// Don't attempt to cast to errorGroup or *multiError
dontCast bool
}{
{dontCast: true}, // nil
{
give: errors.New("hi"),
want: []error{errors.New("hi")},
dontCast: true,
},
{
// We don't yet support non-multierr errors.
give: notMultiErr{},
want: []error{notMultiErr{}},
dontCast: true,
},
{
give: Combine(
errors.New("foo"),
errors.New("bar"),
),
want: []error{
errors.New("foo"),
errors.New("bar"),
},
},
{
give: Append(
errors.New("foo"),
errors.New("bar"),
),
want: []error{
errors.New("foo"),
errors.New("bar"),
},
},
{
give: Append(
errors.New("foo"),
Combine(
errors.New("bar"),
),
),
want: []error{
errors.New("foo"),
errors.New("bar"),
},
},
{
give: Combine(
errors.New("foo"),
Append(
errors.New("bar"),
errors.New("baz"),
),
errors.New("qux"),
),
want: []error{
errors.New("foo"),
errors.New("bar"),
errors.New("baz"),
errors.New("qux"),
},
},
}
for i, tt := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
t.Run("Errors()", func(t *testing.T) {
require.Equal(t, tt.want, Errors(tt.give))
})
if tt.dontCast {
return
}
t.Run("multiError", func(t *testing.T) {
require.Equal(t, tt.want, tt.give.(*multiError).Errors())
})
t.Run("errorGroup", func(t *testing.T) {
require.Equal(t, tt.want, tt.give.(errorGroup).Errors())
})
})
}
}
func createMultiErrWithCapacity() error {
// Create a multiError that has capacity for more errors so Append will
// modify the underlying array that may be shared.
return appendN(nil, errors.New("append"), 50)
}
func TestAppendDoesNotModify(t *testing.T) {
initial := createMultiErrWithCapacity()
err1 := Append(initial, errors.New("err1"))
err2 := Append(initial, errors.New("err2"))
// Make sure the error messages match, since we do modify the copyNeeded
// atomic, the values cannot be compared.
assert.EqualError(t, initial, createMultiErrWithCapacity().Error(), "Initial should not be modified")
assert.EqualError(t, err1, Append(createMultiErrWithCapacity(), errors.New("err1")).Error())
assert.EqualError(t, err2, Append(createMultiErrWithCapacity(), errors.New("err2")).Error())
}
func TestAppendRace(t *testing.T) {
initial := createMultiErrWithCapacity()
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
err := initial
for j := 0; j < 10; j++ {
err = Append(err, errors.New("err"))
}
}()
}
wg.Wait()
}
func TestErrorsSliceIsImmutable(t *testing.T) {
err1 := errors.New("err1")
err2 := errors.New("err2")
err := Append(err1, err2)
gotErrors := Errors(err)
require.Equal(t, []error{err1, err2}, gotErrors, "errors must match")
gotErrors[0] = nil
gotErrors[1] = errors.New("err3")
require.Equal(t, []error{err1, err2}, Errors(err),
"errors must match after modification")
}
func TestNilMultierror(t *testing.T) {
// For safety, all operations on multiError should be safe even if it is
// nil.
var err *multiError
require.Empty(t, err.Error())
require.Empty(t, err.Errors())
}

72
vendor/go.uber.org/multierr/example_test.go generated vendored Normal file
View File

@@ -0,0 +1,72 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package multierr_test
import (
"errors"
"fmt"
"go.uber.org/multierr"
)
func ExampleCombine() {
err := multierr.Combine(
errors.New("call 1 failed"),
nil, // successful request
errors.New("call 3 failed"),
nil, // successful request
errors.New("call 5 failed"),
)
fmt.Printf("%+v", err)
// Output:
// the following errors occurred:
// - call 1 failed
// - call 3 failed
// - call 5 failed
}
func ExampleAppend() {
var err error
err = multierr.Append(err, errors.New("call 1 failed"))
err = multierr.Append(err, errors.New("call 2 failed"))
fmt.Println(err)
// Output:
// call 1 failed; call 2 failed
}
func ExampleErrors() {
err := multierr.Combine(
nil, // successful request
errors.New("call 2 failed"),
errors.New("call 3 failed"),
)
err = multierr.Append(err, nil) // successful request
err = multierr.Append(err, errors.New("call 5 failed"))
errors := multierr.Errors(err)
for _, err := range errors {
fmt.Println(err)
}
// Output:
// call 2 failed
// call 3 failed
// call 5 failed
}

19
vendor/go.uber.org/multierr/glide.lock generated vendored Normal file
View File

@@ -0,0 +1,19 @@
hash: b53b5e9a84b9cb3cc4b2d0499e23da2feca1eec318ce9bb717ecf35bf24bf221
updated: 2017-04-10T13:34:45.671678062-07:00
imports:
- name: go.uber.org/atomic
version: 3b8db5e93c4c02efbc313e17b2e796b0914a01fb
testImports:
- name: github.com/davecgh/go-spew
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
subpackages:
- spew
- name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
subpackages:
- difflib
- name: github.com/stretchr/testify
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
subpackages:
- assert
- require

8
vendor/go.uber.org/multierr/glide.yaml generated vendored Normal file
View File

@@ -0,0 +1,8 @@
package: go.uber.org/multierr
import:
- package: go.uber.org/atomic
version: ^1
testImport:
- package: github.com/stretchr/testify
subpackages:
- assert

40
vendor/go.uber.org/multierr/scripts/cover.sh generated vendored Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash -e
COVER=cover
ROOT_PKG=go.uber.org/multierr
if [[ -d "$COVER" ]]; then
rm -rf "$COVER"
fi
mkdir -p "$COVER"
i=0
for pkg in "$@"; do
i=$((i + 1))
extracoverpkg=""
if [[ -f "$GOPATH/src/$pkg/.extra-coverpkg" ]]; then
extracoverpkg=$( \
sed -e "s|^|$pkg/|g" < "$GOPATH/src/$pkg/.extra-coverpkg" \
| tr '\n' ',')
fi
coverpkg=$(go list -json "$pkg" | jq -r '
.Deps
| . + ["'"$pkg"'"]
| map
( select(startswith("'"$ROOT_PKG"'"))
| select(contains("/vendor/") | not)
)
| join(",")
')
if [[ -n "$extracoverpkg" ]]; then
coverpkg="$extracoverpkg$coverpkg"
fi
go test \
-coverprofile "$COVER/cover.${i}.out" -coverpkg "$coverpkg" \
-v "$pkg"
done
gocovmerge "$COVER"/*.out > cover.out