add prune and remove unused packages
This commit is contained in:
44
vendor/github.com/golang/glog/README
generated
vendored
44
vendor/github.com/golang/glog/README
generated
vendored
@@ -1,44 +0,0 @@
|
||||
glog
|
||||
====
|
||||
|
||||
Leveled execution logs for Go.
|
||||
|
||||
This is an efficient pure Go implementation of leveled logs in the
|
||||
manner of the open source C++ package
|
||||
https://github.com/google/glog
|
||||
|
||||
By binding methods to booleans it is possible to use the log package
|
||||
without paying the expense of evaluating the arguments to the log.
|
||||
Through the -vmodule flag, the package also provides fine-grained
|
||||
control over logging at the file level.
|
||||
|
||||
The comment from glog.go introduces the ideas:
|
||||
|
||||
Package glog implements logging analogous to the Google-internal
|
||||
C++ INFO/ERROR/V setup. It provides functions Info, Warning,
|
||||
Error, Fatal, plus formatting variants such as Infof. It
|
||||
also provides V-style logging controlled by the -v and
|
||||
-vmodule=file=2 flags.
|
||||
|
||||
Basic examples:
|
||||
|
||||
glog.Info("Prepare to repel boarders")
|
||||
|
||||
glog.Fatalf("Initialization failed: %s", err)
|
||||
|
||||
See the documentation for the V function for an explanation
|
||||
of these examples:
|
||||
|
||||
if glog.V(2) {
|
||||
glog.Info("Starting transaction...")
|
||||
}
|
||||
|
||||
glog.V(2).Infoln("Processed", nItems, "elements")
|
||||
|
||||
|
||||
The repository contains an open source version of the log package
|
||||
used inside Google. The master copy of the source lives inside
|
||||
Google, not here. The code in this repo is for export only and is not itself
|
||||
under development. Feature requests will be ignored.
|
||||
|
||||
Send bug reports to golang-nuts@googlegroups.com.
|
415
vendor/github.com/golang/glog/glog_test.go
generated
vendored
415
vendor/github.com/golang/glog/glog_test.go
generated
vendored
@@ -1,415 +0,0 @@
|
||||
// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
|
||||
//
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package glog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
stdLog "log"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Test that shortHostname works as advertised.
|
||||
func TestShortHostname(t *testing.T) {
|
||||
for hostname, expect := range map[string]string{
|
||||
"": "",
|
||||
"host": "host",
|
||||
"host.google.com": "host",
|
||||
} {
|
||||
if got := shortHostname(hostname); expect != got {
|
||||
t.Errorf("shortHostname(%q): expected %q, got %q", hostname, expect, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flushBuffer wraps a bytes.Buffer to satisfy flushSyncWriter.
|
||||
type flushBuffer struct {
|
||||
bytes.Buffer
|
||||
}
|
||||
|
||||
func (f *flushBuffer) Flush() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *flushBuffer) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// swap sets the log writers and returns the old array.
|
||||
func (l *loggingT) swap(writers [numSeverity]flushSyncWriter) (old [numSeverity]flushSyncWriter) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
old = l.file
|
||||
for i, w := range writers {
|
||||
logging.file[i] = w
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// newBuffers sets the log writers to all new byte buffers and returns the old array.
|
||||
func (l *loggingT) newBuffers() [numSeverity]flushSyncWriter {
|
||||
return l.swap([numSeverity]flushSyncWriter{new(flushBuffer), new(flushBuffer), new(flushBuffer), new(flushBuffer)})
|
||||
}
|
||||
|
||||
// contents returns the specified log value as a string.
|
||||
func contents(s severity) string {
|
||||
return logging.file[s].(*flushBuffer).String()
|
||||
}
|
||||
|
||||
// contains reports whether the string is contained in the log.
|
||||
func contains(s severity, str string, t *testing.T) bool {
|
||||
return strings.Contains(contents(s), str)
|
||||
}
|
||||
|
||||
// setFlags configures the logging flags how the test expects them.
|
||||
func setFlags() {
|
||||
logging.toStderr = false
|
||||
}
|
||||
|
||||
// Test that Info works as advertised.
|
||||
func TestInfo(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
Info("test")
|
||||
if !contains(infoLog, "I", t) {
|
||||
t.Errorf("Info has wrong character: %q", contents(infoLog))
|
||||
}
|
||||
if !contains(infoLog, "test", t) {
|
||||
t.Error("Info failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfoDepth(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
|
||||
f := func() { InfoDepth(1, "depth-test1") }
|
||||
|
||||
// The next three lines must stay together
|
||||
_, _, wantLine, _ := runtime.Caller(0)
|
||||
InfoDepth(0, "depth-test0")
|
||||
f()
|
||||
|
||||
msgs := strings.Split(strings.TrimSuffix(contents(infoLog), "\n"), "\n")
|
||||
if len(msgs) != 2 {
|
||||
t.Fatalf("Got %d lines, expected 2", len(msgs))
|
||||
}
|
||||
|
||||
for i, m := range msgs {
|
||||
if !strings.HasPrefix(m, "I") {
|
||||
t.Errorf("InfoDepth[%d] has wrong character: %q", i, m)
|
||||
}
|
||||
w := fmt.Sprintf("depth-test%d", i)
|
||||
if !strings.Contains(m, w) {
|
||||
t.Errorf("InfoDepth[%d] missing %q: %q", i, w, m)
|
||||
}
|
||||
|
||||
// pull out the line number (between : and ])
|
||||
msg := m[strings.LastIndex(m, ":")+1:]
|
||||
x := strings.Index(msg, "]")
|
||||
if x < 0 {
|
||||
t.Errorf("InfoDepth[%d]: missing ']': %q", i, m)
|
||||
continue
|
||||
}
|
||||
line, err := strconv.Atoi(msg[:x])
|
||||
if err != nil {
|
||||
t.Errorf("InfoDepth[%d]: bad line number: %q", i, m)
|
||||
continue
|
||||
}
|
||||
wantLine++
|
||||
if wantLine != line {
|
||||
t.Errorf("InfoDepth[%d]: got line %d, want %d", i, line, wantLine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
CopyStandardLogTo("INFO")
|
||||
}
|
||||
|
||||
// Test that CopyStandardLogTo panics on bad input.
|
||||
func TestCopyStandardLogToPanic(t *testing.T) {
|
||||
defer func() {
|
||||
if s, ok := recover().(string); !ok || !strings.Contains(s, "LOG") {
|
||||
t.Errorf(`CopyStandardLogTo("LOG") should have panicked: %v`, s)
|
||||
}
|
||||
}()
|
||||
CopyStandardLogTo("LOG")
|
||||
}
|
||||
|
||||
// Test that using the standard log package logs to INFO.
|
||||
func TestStandardLog(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
stdLog.Print("test")
|
||||
if !contains(infoLog, "I", t) {
|
||||
t.Errorf("Info has wrong character: %q", contents(infoLog))
|
||||
}
|
||||
if !contains(infoLog, "test", t) {
|
||||
t.Error("Info failed")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the header has the correct format.
|
||||
func TestHeader(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
defer func(previous func() time.Time) { timeNow = previous }(timeNow)
|
||||
timeNow = func() time.Time {
|
||||
return time.Date(2006, 1, 2, 15, 4, 5, .067890e9, time.Local)
|
||||
}
|
||||
pid = 1234
|
||||
Info("test")
|
||||
var line int
|
||||
format := "I0102 15:04:05.067890 1234 glog_test.go:%d] test\n"
|
||||
n, err := fmt.Sscanf(contents(infoLog), format, &line)
|
||||
if n != 1 || err != nil {
|
||||
t.Errorf("log format error: %d elements, error %s:\n%s", n, err, contents(infoLog))
|
||||
}
|
||||
// Scanf treats multiple spaces as equivalent to a single space,
|
||||
// so check for correct space-padding also.
|
||||
want := fmt.Sprintf(format, line)
|
||||
if contents(infoLog) != want {
|
||||
t.Errorf("log format error: got:\n\t%q\nwant:\t%q", contents(infoLog), want)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that an Error log goes to Warning and Info.
|
||||
// Even in the Info log, the source character will be E, so the data should
|
||||
// all be identical.
|
||||
func TestError(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
Error("test")
|
||||
if !contains(errorLog, "E", t) {
|
||||
t.Errorf("Error has wrong character: %q", contents(errorLog))
|
||||
}
|
||||
if !contains(errorLog, "test", t) {
|
||||
t.Error("Error failed")
|
||||
}
|
||||
str := contents(errorLog)
|
||||
if !contains(warningLog, str, t) {
|
||||
t.Error("Warning failed")
|
||||
}
|
||||
if !contains(infoLog, str, t) {
|
||||
t.Error("Info failed")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a Warning log goes to Info.
|
||||
// Even in the Info log, the source character will be W, so the data should
|
||||
// all be identical.
|
||||
func TestWarning(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
Warning("test")
|
||||
if !contains(warningLog, "W", t) {
|
||||
t.Errorf("Warning has wrong character: %q", contents(warningLog))
|
||||
}
|
||||
if !contains(warningLog, "test", t) {
|
||||
t.Error("Warning failed")
|
||||
}
|
||||
str := contents(warningLog)
|
||||
if !contains(infoLog, str, t) {
|
||||
t.Error("Info failed")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a V log goes to Info.
|
||||
func TestV(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
logging.verbosity.Set("2")
|
||||
defer logging.verbosity.Set("0")
|
||||
V(2).Info("test")
|
||||
if !contains(infoLog, "I", t) {
|
||||
t.Errorf("Info has wrong character: %q", contents(infoLog))
|
||||
}
|
||||
if !contains(infoLog, "test", t) {
|
||||
t.Error("Info failed")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a vmodule enables a log in this file.
|
||||
func TestVmoduleOn(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
logging.vmodule.Set("glog_test=2")
|
||||
defer logging.vmodule.Set("")
|
||||
if !V(1) {
|
||||
t.Error("V not enabled for 1")
|
||||
}
|
||||
if !V(2) {
|
||||
t.Error("V not enabled for 2")
|
||||
}
|
||||
if V(3) {
|
||||
t.Error("V enabled for 3")
|
||||
}
|
||||
V(2).Info("test")
|
||||
if !contains(infoLog, "I", t) {
|
||||
t.Errorf("Info has wrong character: %q", contents(infoLog))
|
||||
}
|
||||
if !contains(infoLog, "test", t) {
|
||||
t.Error("Info failed")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a vmodule of another file does not enable a log in this file.
|
||||
func TestVmoduleOff(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
logging.vmodule.Set("notthisfile=2")
|
||||
defer logging.vmodule.Set("")
|
||||
for i := 1; i <= 3; i++ {
|
||||
if V(Level(i)) {
|
||||
t.Errorf("V enabled for %d", i)
|
||||
}
|
||||
}
|
||||
V(2).Info("test")
|
||||
if contents(infoLog) != "" {
|
||||
t.Error("V logged incorrectly")
|
||||
}
|
||||
}
|
||||
|
||||
// vGlobs are patterns that match/don't match this file at V=2.
|
||||
var vGlobs = map[string]bool{
|
||||
// Easy to test the numeric match here.
|
||||
"glog_test=1": false, // If -vmodule sets V to 1, V(2) will fail.
|
||||
"glog_test=2": true,
|
||||
"glog_test=3": true, // If -vmodule sets V to 1, V(3) will succeed.
|
||||
// These all use 2 and check the patterns. All are true.
|
||||
"*=2": true,
|
||||
"?l*=2": true,
|
||||
"????_*=2": true,
|
||||
"??[mno]?_*t=2": true,
|
||||
// These all use 2 and check the patterns. All are false.
|
||||
"*x=2": false,
|
||||
"m*=2": false,
|
||||
"??_*=2": false,
|
||||
"?[abc]?_*t=2": false,
|
||||
}
|
||||
|
||||
// Test that vmodule globbing works as advertised.
|
||||
func testVmoduleGlob(pat string, match bool, t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
defer logging.vmodule.Set("")
|
||||
logging.vmodule.Set(pat)
|
||||
if V(2) != Verbose(match) {
|
||||
t.Errorf("incorrect match for %q: got %t expected %t", pat, V(2), match)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a vmodule globbing works as advertised.
|
||||
func TestVmoduleGlob(t *testing.T) {
|
||||
for glob, match := range vGlobs {
|
||||
testVmoduleGlob(glob, match, t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRollover(t *testing.T) {
|
||||
setFlags()
|
||||
var err error
|
||||
defer func(previous func(error)) { logExitFunc = previous }(logExitFunc)
|
||||
logExitFunc = func(e error) {
|
||||
err = e
|
||||
}
|
||||
defer func(previous uint64) { MaxSize = previous }(MaxSize)
|
||||
MaxSize = 512
|
||||
|
||||
Info("x") // Be sure we have a file.
|
||||
info, ok := logging.file[infoLog].(*syncBuffer)
|
||||
if !ok {
|
||||
t.Fatal("info wasn't created")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("info has initial error: %v", err)
|
||||
}
|
||||
fname0 := info.file.Name()
|
||||
Info(strings.Repeat("x", int(MaxSize))) // force a rollover
|
||||
if err != nil {
|
||||
t.Fatalf("info has error after big write: %v", err)
|
||||
}
|
||||
|
||||
// Make sure the next log file gets a file name with a different
|
||||
// time stamp.
|
||||
//
|
||||
// TODO: determine whether we need to support subsecond log
|
||||
// rotation. C++ does not appear to handle this case (nor does it
|
||||
// handle Daylight Savings Time properly).
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
Info("x") // create a new file
|
||||
if err != nil {
|
||||
t.Fatalf("error after rotation: %v", err)
|
||||
}
|
||||
fname1 := info.file.Name()
|
||||
if fname0 == fname1 {
|
||||
t.Errorf("info.f.Name did not change: %v", fname0)
|
||||
}
|
||||
if info.nbytes >= MaxSize {
|
||||
t.Errorf("file size was not reset: %d", info.nbytes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogBacktraceAt(t *testing.T) {
|
||||
setFlags()
|
||||
defer logging.swap(logging.newBuffers())
|
||||
// The peculiar style of this code simplifies line counting and maintenance of the
|
||||
// tracing block below.
|
||||
var infoLine string
|
||||
setTraceLocation := func(file string, line int, ok bool, delta int) {
|
||||
if !ok {
|
||||
t.Fatal("could not get file:line")
|
||||
}
|
||||
_, file = filepath.Split(file)
|
||||
infoLine = fmt.Sprintf("%s:%d", file, line+delta)
|
||||
err := logging.traceLocation.Set(infoLine)
|
||||
if err != nil {
|
||||
t.Fatal("error setting log_backtrace_at: ", err)
|
||||
}
|
||||
}
|
||||
{
|
||||
// Start of tracing block. These lines know about each other's relative position.
|
||||
_, file, line, ok := runtime.Caller(0)
|
||||
setTraceLocation(file, line, ok, +2) // Two lines between Caller and Info calls.
|
||||
Info("we want a stack trace here")
|
||||
}
|
||||
numAppearances := strings.Count(contents(infoLog), infoLine)
|
||||
if numAppearances < 2 {
|
||||
// Need 2 appearances, one in the log header and one in the trace:
|
||||
// log_test.go:281: I0511 16:36:06.952398 02238 log_test.go:280] we want a stack trace here
|
||||
// ...
|
||||
// github.com/glog/glog_test.go:280 (0x41ba91)
|
||||
// ...
|
||||
// We could be more precise but that would require knowing the details
|
||||
// of the traceback format, which may not be dependable.
|
||||
t.Fatal("got no trace back; log is ", contents(infoLog))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHeader(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf, _, _ := logging.header(infoLog, 0)
|
||||
logging.putBuffer(buf)
|
||||
}
|
||||
}
|
1
vendor/github.com/golang/groupcache/.gitignore
generated
vendored
1
vendor/github.com/golang/groupcache/.gitignore
generated
vendored
@@ -1 +0,0 @@
|
||||
*~
|
19
vendor/github.com/golang/groupcache/.travis.yml
generated
vendored
19
vendor/github.com/golang/groupcache/.travis.yml
generated
vendored
@@ -1,19 +0,0 @@
|
||||
language: go
|
||||
go_import_path: github.com/golang/groupcache
|
||||
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
script:
|
||||
- go test ./...
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- master
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/pkg
|
73
vendor/github.com/golang/groupcache/README.md
generated
vendored
73
vendor/github.com/golang/groupcache/README.md
generated
vendored
@@ -1,73 +0,0 @@
|
||||
# groupcache
|
||||
|
||||
## Summary
|
||||
|
||||
groupcache is a caching and cache-filling library, intended as a
|
||||
replacement for memcached in many cases.
|
||||
|
||||
For API docs and examples, see http://godoc.org/github.com/golang/groupcache
|
||||
|
||||
## Comparison to memcached
|
||||
|
||||
### **Like memcached**, groupcache:
|
||||
|
||||
* shards by key to select which peer is responsible for that key
|
||||
|
||||
### **Unlike memcached**, groupcache:
|
||||
|
||||
* does not require running a separate set of servers, thus massively
|
||||
reducing deployment/configuration pain. groupcache is a client
|
||||
library as well as a server. It connects to its own peers.
|
||||
|
||||
* comes with a cache filling mechanism. Whereas memcached just says
|
||||
"Sorry, cache miss", often resulting in a thundering herd of
|
||||
database (or whatever) loads from an unbounded number of clients
|
||||
(which has resulted in several fun outages), groupcache coordinates
|
||||
cache fills such that only one load in one process of an entire
|
||||
replicated set of processes populates the cache, then multiplexes
|
||||
the loaded value to all callers.
|
||||
|
||||
* does not support versioned values. If key "foo" is value "bar",
|
||||
key "foo" must always be "bar". There are neither cache expiration
|
||||
times, nor explicit cache evictions. Thus there is also no CAS,
|
||||
nor Increment/Decrement. This also means that groupcache....
|
||||
|
||||
* ... supports automatic mirroring of super-hot items to multiple
|
||||
processes. This prevents memcached hot spotting where a machine's
|
||||
CPU and/or NIC are overloaded by very popular keys/values.
|
||||
|
||||
* is currently only available for Go. It's very unlikely that I
|
||||
(bradfitz@) will port the code to any other language.
|
||||
|
||||
## Loading process
|
||||
|
||||
In a nutshell, a groupcache lookup of **Get("foo")** looks like:
|
||||
|
||||
(On machine #5 of a set of N machines running the same code)
|
||||
|
||||
1. Is the value of "foo" in local memory because it's super hot? If so, use it.
|
||||
|
||||
2. Is the value of "foo" in local memory because peer #5 (the current
|
||||
peer) is the owner of it? If so, use it.
|
||||
|
||||
3. Amongst all the peers in my set of N, am I the owner of the key
|
||||
"foo"? (e.g. does it consistent hash to 5?) If so, load it. If
|
||||
other callers come in, via the same process or via RPC requests
|
||||
from peers, they block waiting for the load to finish and get the
|
||||
same answer. If not, RPC to the peer that's the owner and get
|
||||
the answer. If the RPC fails, just load it locally (still with
|
||||
local dup suppression).
|
||||
|
||||
## Users
|
||||
|
||||
groupcache is in production use by dl.google.com (its original user),
|
||||
parts of Blogger, parts of Google Code, parts of Google Fiber, parts
|
||||
of Google production monitoring systems, etc.
|
||||
|
||||
## Presentations
|
||||
|
||||
See http://talks.golang.org/2013/oscon-dl.slide
|
||||
|
||||
## Help
|
||||
|
||||
Use the golang-nuts mailing list for any discussion or questions.
|
175
vendor/github.com/golang/groupcache/byteview.go
generated
vendored
175
vendor/github.com/golang/groupcache/byteview.go
generated
vendored
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A ByteView holds an immutable view of bytes.
|
||||
// Internally it wraps either a []byte or a string,
|
||||
// but that detail is invisible to callers.
|
||||
//
|
||||
// A ByteView is meant to be used as a value type, not
|
||||
// a pointer (like a time.Time).
|
||||
type ByteView struct {
|
||||
// If b is non-nil, b is used, else s is used.
|
||||
b []byte
|
||||
s string
|
||||
}
|
||||
|
||||
// Len returns the view's length.
|
||||
func (v ByteView) Len() int {
|
||||
if v.b != nil {
|
||||
return len(v.b)
|
||||
}
|
||||
return len(v.s)
|
||||
}
|
||||
|
||||
// ByteSlice returns a copy of the data as a byte slice.
|
||||
func (v ByteView) ByteSlice() []byte {
|
||||
if v.b != nil {
|
||||
return cloneBytes(v.b)
|
||||
}
|
||||
return []byte(v.s)
|
||||
}
|
||||
|
||||
// String returns the data as a string, making a copy if necessary.
|
||||
func (v ByteView) String() string {
|
||||
if v.b != nil {
|
||||
return string(v.b)
|
||||
}
|
||||
return v.s
|
||||
}
|
||||
|
||||
// At returns the byte at index i.
|
||||
func (v ByteView) At(i int) byte {
|
||||
if v.b != nil {
|
||||
return v.b[i]
|
||||
}
|
||||
return v.s[i]
|
||||
}
|
||||
|
||||
// Slice slices the view between the provided from and to indices.
|
||||
func (v ByteView) Slice(from, to int) ByteView {
|
||||
if v.b != nil {
|
||||
return ByteView{b: v.b[from:to]}
|
||||
}
|
||||
return ByteView{s: v.s[from:to]}
|
||||
}
|
||||
|
||||
// SliceFrom slices the view from the provided index until the end.
|
||||
func (v ByteView) SliceFrom(from int) ByteView {
|
||||
if v.b != nil {
|
||||
return ByteView{b: v.b[from:]}
|
||||
}
|
||||
return ByteView{s: v.s[from:]}
|
||||
}
|
||||
|
||||
// Copy copies b into dest and returns the number of bytes copied.
|
||||
func (v ByteView) Copy(dest []byte) int {
|
||||
if v.b != nil {
|
||||
return copy(dest, v.b)
|
||||
}
|
||||
return copy(dest, v.s)
|
||||
}
|
||||
|
||||
// Equal returns whether the bytes in b are the same as the bytes in
|
||||
// b2.
|
||||
func (v ByteView) Equal(b2 ByteView) bool {
|
||||
if b2.b == nil {
|
||||
return v.EqualString(b2.s)
|
||||
}
|
||||
return v.EqualBytes(b2.b)
|
||||
}
|
||||
|
||||
// EqualString returns whether the bytes in b are the same as the bytes
|
||||
// in s.
|
||||
func (v ByteView) EqualString(s string) bool {
|
||||
if v.b == nil {
|
||||
return v.s == s
|
||||
}
|
||||
l := v.Len()
|
||||
if len(s) != l {
|
||||
return false
|
||||
}
|
||||
for i, bi := range v.b {
|
||||
if bi != s[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// EqualBytes returns whether the bytes in b are the same as the bytes
|
||||
// in b2.
|
||||
func (v ByteView) EqualBytes(b2 []byte) bool {
|
||||
if v.b != nil {
|
||||
return bytes.Equal(v.b, b2)
|
||||
}
|
||||
l := v.Len()
|
||||
if len(b2) != l {
|
||||
return false
|
||||
}
|
||||
for i, bi := range b2 {
|
||||
if bi != v.s[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Reader returns an io.ReadSeeker for the bytes in v.
|
||||
func (v ByteView) Reader() io.ReadSeeker {
|
||||
if v.b != nil {
|
||||
return bytes.NewReader(v.b)
|
||||
}
|
||||
return strings.NewReader(v.s)
|
||||
}
|
||||
|
||||
// ReadAt implements io.ReaderAt on the bytes in v.
|
||||
func (v ByteView) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
if off < 0 {
|
||||
return 0, errors.New("view: invalid offset")
|
||||
}
|
||||
if off >= int64(v.Len()) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n = v.SliceFrom(int(off)).Copy(p)
|
||||
if n < len(p) {
|
||||
err = io.EOF
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo on the bytes in v.
|
||||
func (v ByteView) WriteTo(w io.Writer) (n int64, err error) {
|
||||
var m int
|
||||
if v.b != nil {
|
||||
m, err = w.Write(v.b)
|
||||
} else {
|
||||
m, err = io.WriteString(w, v.s)
|
||||
}
|
||||
if err == nil && m < v.Len() {
|
||||
err = io.ErrShortWrite
|
||||
}
|
||||
n = int64(m)
|
||||
return
|
||||
}
|
147
vendor/github.com/golang/groupcache/byteview_test.go
generated
vendored
147
vendor/github.com/golang/groupcache/byteview_test.go
generated
vendored
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestByteView(t *testing.T) {
|
||||
for _, s := range []string{"", "x", "yy"} {
|
||||
for _, v := range []ByteView{of([]byte(s)), of(s)} {
|
||||
name := fmt.Sprintf("string %q, view %+v", s, v)
|
||||
if v.Len() != len(s) {
|
||||
t.Errorf("%s: Len = %d; want %d", name, v.Len(), len(s))
|
||||
}
|
||||
if v.String() != s {
|
||||
t.Errorf("%s: String = %q; want %q", name, v.String(), s)
|
||||
}
|
||||
var longDest [3]byte
|
||||
if n := v.Copy(longDest[:]); n != len(s) {
|
||||
t.Errorf("%s: long Copy = %d; want %d", name, n, len(s))
|
||||
}
|
||||
var shortDest [1]byte
|
||||
if n := v.Copy(shortDest[:]); n != min(len(s), 1) {
|
||||
t.Errorf("%s: short Copy = %d; want %d", name, n, min(len(s), 1))
|
||||
}
|
||||
if got, err := ioutil.ReadAll(v.Reader()); err != nil || string(got) != s {
|
||||
t.Errorf("%s: Reader = %q, %v; want %q", name, got, err, s)
|
||||
}
|
||||
if got, err := ioutil.ReadAll(io.NewSectionReader(v, 0, int64(len(s)))); err != nil || string(got) != s {
|
||||
t.Errorf("%s: SectionReader of ReaderAt = %q, %v; want %q", name, got, err, s)
|
||||
}
|
||||
var dest bytes.Buffer
|
||||
if _, err := v.WriteTo(&dest); err != nil || !bytes.Equal(dest.Bytes(), []byte(s)) {
|
||||
t.Errorf("%s: WriteTo = %q, %v; want %q", name, dest.Bytes(), err, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// of returns a byte view of the []byte or string in x.
|
||||
func of(x interface{}) ByteView {
|
||||
if bytes, ok := x.([]byte); ok {
|
||||
return ByteView{b: bytes}
|
||||
}
|
||||
return ByteView{s: x.(string)}
|
||||
}
|
||||
|
||||
func TestByteViewEqual(t *testing.T) {
|
||||
tests := []struct {
|
||||
a interface{} // string or []byte
|
||||
b interface{} // string or []byte
|
||||
want bool
|
||||
}{
|
||||
{"x", "x", true},
|
||||
{"x", "y", false},
|
||||
{"x", "yy", false},
|
||||
{[]byte("x"), []byte("x"), true},
|
||||
{[]byte("x"), []byte("y"), false},
|
||||
{[]byte("x"), []byte("yy"), false},
|
||||
{[]byte("x"), "x", true},
|
||||
{[]byte("x"), "y", false},
|
||||
{[]byte("x"), "yy", false},
|
||||
{"x", []byte("x"), true},
|
||||
{"x", []byte("y"), false},
|
||||
{"x", []byte("yy"), false},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
va := of(tt.a)
|
||||
if bytes, ok := tt.b.([]byte); ok {
|
||||
if got := va.EqualBytes(bytes); got != tt.want {
|
||||
t.Errorf("%d. EqualBytes = %v; want %v", i, got, tt.want)
|
||||
}
|
||||
} else {
|
||||
if got := va.EqualString(tt.b.(string)); got != tt.want {
|
||||
t.Errorf("%d. EqualString = %v; want %v", i, got, tt.want)
|
||||
}
|
||||
}
|
||||
if got := va.Equal(of(tt.b)); got != tt.want {
|
||||
t.Errorf("%d. Equal = %v; want %v", i, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestByteViewSlice(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
from int
|
||||
to interface{} // nil to mean the end (SliceFrom); else int
|
||||
want string
|
||||
}{
|
||||
{
|
||||
in: "abc",
|
||||
from: 1,
|
||||
to: 2,
|
||||
want: "b",
|
||||
},
|
||||
{
|
||||
in: "abc",
|
||||
from: 1,
|
||||
want: "bc",
|
||||
},
|
||||
{
|
||||
in: "abc",
|
||||
to: 2,
|
||||
want: "ab",
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
for _, v := range []ByteView{of([]byte(tt.in)), of(tt.in)} {
|
||||
name := fmt.Sprintf("test %d, view %+v", i, v)
|
||||
if tt.to != nil {
|
||||
v = v.Slice(tt.from, tt.to.(int))
|
||||
} else {
|
||||
v = v.SliceFrom(tt.from)
|
||||
}
|
||||
if v.String() != tt.want {
|
||||
t.Errorf("%s: got %q; want %q", name, v.String(), tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
81
vendor/github.com/golang/groupcache/consistenthash/consistenthash.go
generated
vendored
81
vendor/github.com/golang/groupcache/consistenthash/consistenthash.go
generated
vendored
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package consistenthash provides an implementation of a ring hash.
|
||||
package consistenthash
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Hash func(data []byte) uint32
|
||||
|
||||
type Map struct {
|
||||
hash Hash
|
||||
replicas int
|
||||
keys []int // Sorted
|
||||
hashMap map[int]string
|
||||
}
|
||||
|
||||
func New(replicas int, fn Hash) *Map {
|
||||
m := &Map{
|
||||
replicas: replicas,
|
||||
hash: fn,
|
||||
hashMap: make(map[int]string),
|
||||
}
|
||||
if m.hash == nil {
|
||||
m.hash = crc32.ChecksumIEEE
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Returns true if there are no items available.
|
||||
func (m *Map) IsEmpty() bool {
|
||||
return len(m.keys) == 0
|
||||
}
|
||||
|
||||
// Adds some keys to the hash.
|
||||
func (m *Map) Add(keys ...string) {
|
||||
for _, key := range keys {
|
||||
for i := 0; i < m.replicas; i++ {
|
||||
hash := int(m.hash([]byte(strconv.Itoa(i) + key)))
|
||||
m.keys = append(m.keys, hash)
|
||||
m.hashMap[hash] = key
|
||||
}
|
||||
}
|
||||
sort.Ints(m.keys)
|
||||
}
|
||||
|
||||
// Gets the closest item in the hash to the provided key.
|
||||
func (m *Map) Get(key string) string {
|
||||
if m.IsEmpty() {
|
||||
return ""
|
||||
}
|
||||
|
||||
hash := int(m.hash([]byte(key)))
|
||||
|
||||
// Binary search for appropriate replica.
|
||||
idx := sort.Search(len(m.keys), func(i int) bool { return m.keys[i] >= hash })
|
||||
|
||||
// Means we have cycled back to the first replica.
|
||||
if idx == len(m.keys) {
|
||||
idx = 0
|
||||
}
|
||||
|
||||
return m.hashMap[m.keys[idx]]
|
||||
}
|
110
vendor/github.com/golang/groupcache/consistenthash/consistenthash_test.go
generated
vendored
110
vendor/github.com/golang/groupcache/consistenthash/consistenthash_test.go
generated
vendored
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package consistenthash
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHashing(t *testing.T) {
|
||||
|
||||
// Override the hash function to return easier to reason about values. Assumes
|
||||
// the keys can be converted to an integer.
|
||||
hash := New(3, func(key []byte) uint32 {
|
||||
i, err := strconv.Atoi(string(key))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return uint32(i)
|
||||
})
|
||||
|
||||
// Given the above hash function, this will give replicas with "hashes":
|
||||
// 2, 4, 6, 12, 14, 16, 22, 24, 26
|
||||
hash.Add("6", "4", "2")
|
||||
|
||||
testCases := map[string]string{
|
||||
"2": "2",
|
||||
"11": "2",
|
||||
"23": "4",
|
||||
"27": "2",
|
||||
}
|
||||
|
||||
for k, v := range testCases {
|
||||
if hash.Get(k) != v {
|
||||
t.Errorf("Asking for %s, should have yielded %s", k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Adds 8, 18, 28
|
||||
hash.Add("8")
|
||||
|
||||
// 27 should now map to 8.
|
||||
testCases["27"] = "8"
|
||||
|
||||
for k, v := range testCases {
|
||||
if hash.Get(k) != v {
|
||||
t.Errorf("Asking for %s, should have yielded %s", k, v)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestConsistency(t *testing.T) {
|
||||
hash1 := New(1, nil)
|
||||
hash2 := New(1, nil)
|
||||
|
||||
hash1.Add("Bill", "Bob", "Bonny")
|
||||
hash2.Add("Bob", "Bonny", "Bill")
|
||||
|
||||
if hash1.Get("Ben") != hash2.Get("Ben") {
|
||||
t.Errorf("Fetching 'Ben' from both hashes should be the same")
|
||||
}
|
||||
|
||||
hash2.Add("Becky", "Ben", "Bobby")
|
||||
|
||||
if hash1.Get("Ben") != hash2.Get("Ben") ||
|
||||
hash1.Get("Bob") != hash2.Get("Bob") ||
|
||||
hash1.Get("Bonny") != hash2.Get("Bonny") {
|
||||
t.Errorf("Direct matches should always return the same entry")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkGet8(b *testing.B) { benchmarkGet(b, 8) }
|
||||
func BenchmarkGet32(b *testing.B) { benchmarkGet(b, 32) }
|
||||
func BenchmarkGet128(b *testing.B) { benchmarkGet(b, 128) }
|
||||
func BenchmarkGet512(b *testing.B) { benchmarkGet(b, 512) }
|
||||
|
||||
func benchmarkGet(b *testing.B, shards int) {
|
||||
|
||||
hash := New(50, nil)
|
||||
|
||||
var buckets []string
|
||||
for i := 0; i < shards; i++ {
|
||||
buckets = append(buckets, fmt.Sprintf("shard-%d", i))
|
||||
}
|
||||
|
||||
hash.Add(buckets...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
hash.Get(buckets[i&(shards-1)])
|
||||
}
|
||||
}
|
491
vendor/github.com/golang/groupcache/groupcache.go
generated
vendored
491
vendor/github.com/golang/groupcache/groupcache.go
generated
vendored
@@ -1,491 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package groupcache provides a data loading mechanism with caching
|
||||
// and de-duplication that works across a set of peer processes.
|
||||
//
|
||||
// Each data Get first consults its local cache, otherwise delegates
|
||||
// to the requested key's canonical owner, which then checks its cache
|
||||
// or finally gets the data. In the common case, many concurrent
|
||||
// cache misses across a set of peers for the same key result in just
|
||||
// one cache fill.
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
pb "github.com/golang/groupcache/groupcachepb"
|
||||
"github.com/golang/groupcache/lru"
|
||||
"github.com/golang/groupcache/singleflight"
|
||||
)
|
||||
|
||||
// A Getter loads data for a key.
|
||||
type Getter interface {
|
||||
// Get returns the value identified by key, populating dest.
|
||||
//
|
||||
// The returned data must be unversioned. That is, key must
|
||||
// uniquely describe the loaded data, without an implicit
|
||||
// current time, and without relying on cache expiration
|
||||
// mechanisms.
|
||||
Get(ctx Context, key string, dest Sink) error
|
||||
}
|
||||
|
||||
// A GetterFunc implements Getter with a function.
|
||||
type GetterFunc func(ctx Context, key string, dest Sink) error
|
||||
|
||||
func (f GetterFunc) Get(ctx Context, key string, dest Sink) error {
|
||||
return f(ctx, key, dest)
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.RWMutex
|
||||
groups = make(map[string]*Group)
|
||||
|
||||
initPeerServerOnce sync.Once
|
||||
initPeerServer func()
|
||||
)
|
||||
|
||||
// GetGroup returns the named group previously created with NewGroup, or
|
||||
// nil if there's no such group.
|
||||
func GetGroup(name string) *Group {
|
||||
mu.RLock()
|
||||
g := groups[name]
|
||||
mu.RUnlock()
|
||||
return g
|
||||
}
|
||||
|
||||
// NewGroup creates a coordinated group-aware Getter from a Getter.
|
||||
//
|
||||
// The returned Getter tries (but does not guarantee) to run only one
|
||||
// Get call at once for a given key across an entire set of peer
|
||||
// processes. Concurrent callers both in the local process and in
|
||||
// other processes receive copies of the answer once the original Get
|
||||
// completes.
|
||||
//
|
||||
// The group name must be unique for each getter.
|
||||
func NewGroup(name string, cacheBytes int64, getter Getter) *Group {
|
||||
return newGroup(name, cacheBytes, getter, nil)
|
||||
}
|
||||
|
||||
// If peers is nil, the peerPicker is called via a sync.Once to initialize it.
|
||||
func newGroup(name string, cacheBytes int64, getter Getter, peers PeerPicker) *Group {
|
||||
if getter == nil {
|
||||
panic("nil Getter")
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
initPeerServerOnce.Do(callInitPeerServer)
|
||||
if _, dup := groups[name]; dup {
|
||||
panic("duplicate registration of group " + name)
|
||||
}
|
||||
g := &Group{
|
||||
name: name,
|
||||
getter: getter,
|
||||
peers: peers,
|
||||
cacheBytes: cacheBytes,
|
||||
loadGroup: &singleflight.Group{},
|
||||
}
|
||||
if fn := newGroupHook; fn != nil {
|
||||
fn(g)
|
||||
}
|
||||
groups[name] = g
|
||||
return g
|
||||
}
|
||||
|
||||
// newGroupHook, if non-nil, is called right after a new group is created.
|
||||
var newGroupHook func(*Group)
|
||||
|
||||
// RegisterNewGroupHook registers a hook that is run each time
|
||||
// a group is created.
|
||||
func RegisterNewGroupHook(fn func(*Group)) {
|
||||
if newGroupHook != nil {
|
||||
panic("RegisterNewGroupHook called more than once")
|
||||
}
|
||||
newGroupHook = fn
|
||||
}
|
||||
|
||||
// RegisterServerStart registers a hook that is run when the first
|
||||
// group is created.
|
||||
func RegisterServerStart(fn func()) {
|
||||
if initPeerServer != nil {
|
||||
panic("RegisterServerStart called more than once")
|
||||
}
|
||||
initPeerServer = fn
|
||||
}
|
||||
|
||||
func callInitPeerServer() {
|
||||
if initPeerServer != nil {
|
||||
initPeerServer()
|
||||
}
|
||||
}
|
||||
|
||||
// A Group is a cache namespace and associated data loaded spread over
|
||||
// a group of 1 or more machines.
|
||||
type Group struct {
|
||||
name string
|
||||
getter Getter
|
||||
peersOnce sync.Once
|
||||
peers PeerPicker
|
||||
cacheBytes int64 // limit for sum of mainCache and hotCache size
|
||||
|
||||
// mainCache is a cache of the keys for which this process
|
||||
// (amongst its peers) is authoritative. That is, this cache
|
||||
// contains keys which consistent hash on to this process's
|
||||
// peer number.
|
||||
mainCache cache
|
||||
|
||||
// hotCache contains keys/values for which this peer is not
|
||||
// authoritative (otherwise they would be in mainCache), but
|
||||
// are popular enough to warrant mirroring in this process to
|
||||
// avoid going over the network to fetch from a peer. Having
|
||||
// a hotCache avoids network hotspotting, where a peer's
|
||||
// network card could become the bottleneck on a popular key.
|
||||
// This cache is used sparingly to maximize the total number
|
||||
// of key/value pairs that can be stored globally.
|
||||
hotCache cache
|
||||
|
||||
// loadGroup ensures that each key is only fetched once
|
||||
// (either locally or remotely), regardless of the number of
|
||||
// concurrent callers.
|
||||
loadGroup flightGroup
|
||||
|
||||
_ int32 // force Stats to be 8-byte aligned on 32-bit platforms
|
||||
|
||||
// Stats are statistics on the group.
|
||||
Stats Stats
|
||||
}
|
||||
|
||||
// flightGroup is defined as an interface which flightgroup.Group
|
||||
// satisfies. We define this so that we may test with an alternate
|
||||
// implementation.
|
||||
type flightGroup interface {
|
||||
// Done is called when Do is done.
|
||||
Do(key string, fn func() (interface{}, error)) (interface{}, error)
|
||||
}
|
||||
|
||||
// Stats are per-group statistics.
|
||||
type Stats struct {
|
||||
Gets AtomicInt // any Get request, including from peers
|
||||
CacheHits AtomicInt // either cache was good
|
||||
PeerLoads AtomicInt // either remote load or remote cache hit (not an error)
|
||||
PeerErrors AtomicInt
|
||||
Loads AtomicInt // (gets - cacheHits)
|
||||
LoadsDeduped AtomicInt // after singleflight
|
||||
LocalLoads AtomicInt // total good local loads
|
||||
LocalLoadErrs AtomicInt // total bad local loads
|
||||
ServerRequests AtomicInt // gets that came over the network from peers
|
||||
}
|
||||
|
||||
// Name returns the name of the group.
|
||||
func (g *Group) Name() string {
|
||||
return g.name
|
||||
}
|
||||
|
||||
func (g *Group) initPeers() {
|
||||
if g.peers == nil {
|
||||
g.peers = getPeers(g.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Group) Get(ctx Context, key string, dest Sink) error {
|
||||
g.peersOnce.Do(g.initPeers)
|
||||
g.Stats.Gets.Add(1)
|
||||
if dest == nil {
|
||||
return errors.New("groupcache: nil dest Sink")
|
||||
}
|
||||
value, cacheHit := g.lookupCache(key)
|
||||
|
||||
if cacheHit {
|
||||
g.Stats.CacheHits.Add(1)
|
||||
return setSinkView(dest, value)
|
||||
}
|
||||
|
||||
// Optimization to avoid double unmarshalling or copying: keep
|
||||
// track of whether the dest was already populated. One caller
|
||||
// (if local) will set this; the losers will not. The common
|
||||
// case will likely be one caller.
|
||||
destPopulated := false
|
||||
value, destPopulated, err := g.load(ctx, key, dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if destPopulated {
|
||||
return nil
|
||||
}
|
||||
return setSinkView(dest, value)
|
||||
}
|
||||
|
||||
// load loads key either by invoking the getter locally or by sending it to another machine.
|
||||
func (g *Group) load(ctx Context, key string, dest Sink) (value ByteView, destPopulated bool, err error) {
|
||||
g.Stats.Loads.Add(1)
|
||||
viewi, err := g.loadGroup.Do(key, func() (interface{}, error) {
|
||||
// Check the cache again because singleflight can only dedup calls
|
||||
// that overlap concurrently. It's possible for 2 concurrent
|
||||
// requests to miss the cache, resulting in 2 load() calls. An
|
||||
// unfortunate goroutine scheduling would result in this callback
|
||||
// being run twice, serially. If we don't check the cache again,
|
||||
// cache.nbytes would be incremented below even though there will
|
||||
// be only one entry for this key.
|
||||
//
|
||||
// Consider the following serialized event ordering for two
|
||||
// goroutines in which this callback gets called twice for hte
|
||||
// same key:
|
||||
// 1: Get("key")
|
||||
// 2: Get("key")
|
||||
// 1: lookupCache("key")
|
||||
// 2: lookupCache("key")
|
||||
// 1: load("key")
|
||||
// 2: load("key")
|
||||
// 1: loadGroup.Do("key", fn)
|
||||
// 1: fn()
|
||||
// 2: loadGroup.Do("key", fn)
|
||||
// 2: fn()
|
||||
if value, cacheHit := g.lookupCache(key); cacheHit {
|
||||
g.Stats.CacheHits.Add(1)
|
||||
return value, nil
|
||||
}
|
||||
g.Stats.LoadsDeduped.Add(1)
|
||||
var value ByteView
|
||||
var err error
|
||||
if peer, ok := g.peers.PickPeer(key); ok {
|
||||
value, err = g.getFromPeer(ctx, peer, key)
|
||||
if err == nil {
|
||||
g.Stats.PeerLoads.Add(1)
|
||||
return value, nil
|
||||
}
|
||||
g.Stats.PeerErrors.Add(1)
|
||||
// TODO(bradfitz): log the peer's error? keep
|
||||
// log of the past few for /groupcachez? It's
|
||||
// probably boring (normal task movement), so not
|
||||
// worth logging I imagine.
|
||||
}
|
||||
value, err = g.getLocally(ctx, key, dest)
|
||||
if err != nil {
|
||||
g.Stats.LocalLoadErrs.Add(1)
|
||||
return nil, err
|
||||
}
|
||||
g.Stats.LocalLoads.Add(1)
|
||||
destPopulated = true // only one caller of load gets this return value
|
||||
g.populateCache(key, value, &g.mainCache)
|
||||
return value, nil
|
||||
})
|
||||
if err == nil {
|
||||
value = viewi.(ByteView)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (g *Group) getLocally(ctx Context, key string, dest Sink) (ByteView, error) {
|
||||
err := g.getter.Get(ctx, key, dest)
|
||||
if err != nil {
|
||||
return ByteView{}, err
|
||||
}
|
||||
return dest.view()
|
||||
}
|
||||
|
||||
func (g *Group) getFromPeer(ctx Context, peer ProtoGetter, key string) (ByteView, error) {
|
||||
req := &pb.GetRequest{
|
||||
Group: &g.name,
|
||||
Key: &key,
|
||||
}
|
||||
res := &pb.GetResponse{}
|
||||
err := peer.Get(ctx, req, res)
|
||||
if err != nil {
|
||||
return ByteView{}, err
|
||||
}
|
||||
value := ByteView{b: res.Value}
|
||||
// TODO(bradfitz): use res.MinuteQps or something smart to
|
||||
// conditionally populate hotCache. For now just do it some
|
||||
// percentage of the time.
|
||||
if rand.Intn(10) == 0 {
|
||||
g.populateCache(key, value, &g.hotCache)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (g *Group) lookupCache(key string) (value ByteView, ok bool) {
|
||||
if g.cacheBytes <= 0 {
|
||||
return
|
||||
}
|
||||
value, ok = g.mainCache.get(key)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
value, ok = g.hotCache.get(key)
|
||||
return
|
||||
}
|
||||
|
||||
func (g *Group) populateCache(key string, value ByteView, cache *cache) {
|
||||
if g.cacheBytes <= 0 {
|
||||
return
|
||||
}
|
||||
cache.add(key, value)
|
||||
|
||||
// Evict items from cache(s) if necessary.
|
||||
for {
|
||||
mainBytes := g.mainCache.bytes()
|
||||
hotBytes := g.hotCache.bytes()
|
||||
if mainBytes+hotBytes <= g.cacheBytes {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(bradfitz): this is good-enough-for-now logic.
|
||||
// It should be something based on measurements and/or
|
||||
// respecting the costs of different resources.
|
||||
victim := &g.mainCache
|
||||
if hotBytes > mainBytes/8 {
|
||||
victim = &g.hotCache
|
||||
}
|
||||
victim.removeOldest()
|
||||
}
|
||||
}
|
||||
|
||||
// CacheType represents a type of cache.
|
||||
type CacheType int
|
||||
|
||||
const (
|
||||
// The MainCache is the cache for items that this peer is the
|
||||
// owner for.
|
||||
MainCache CacheType = iota + 1
|
||||
|
||||
// The HotCache is the cache for items that seem popular
|
||||
// enough to replicate to this node, even though it's not the
|
||||
// owner.
|
||||
HotCache
|
||||
)
|
||||
|
||||
// CacheStats returns stats about the provided cache within the group.
|
||||
func (g *Group) CacheStats(which CacheType) CacheStats {
|
||||
switch which {
|
||||
case MainCache:
|
||||
return g.mainCache.stats()
|
||||
case HotCache:
|
||||
return g.hotCache.stats()
|
||||
default:
|
||||
return CacheStats{}
|
||||
}
|
||||
}
|
||||
|
||||
// cache is a wrapper around an *lru.Cache that adds synchronization,
|
||||
// makes values always be ByteView, and counts the size of all keys and
|
||||
// values.
|
||||
type cache struct {
|
||||
mu sync.RWMutex
|
||||
nbytes int64 // of all keys and values
|
||||
lru *lru.Cache
|
||||
nhit, nget int64
|
||||
nevict int64 // number of evictions
|
||||
}
|
||||
|
||||
func (c *cache) stats() CacheStats {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return CacheStats{
|
||||
Bytes: c.nbytes,
|
||||
Items: c.itemsLocked(),
|
||||
Gets: c.nget,
|
||||
Hits: c.nhit,
|
||||
Evictions: c.nevict,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cache) add(key string, value ByteView) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.lru == nil {
|
||||
c.lru = &lru.Cache{
|
||||
OnEvicted: func(key lru.Key, value interface{}) {
|
||||
val := value.(ByteView)
|
||||
c.nbytes -= int64(len(key.(string))) + int64(val.Len())
|
||||
c.nevict++
|
||||
},
|
||||
}
|
||||
}
|
||||
c.lru.Add(key, value)
|
||||
c.nbytes += int64(len(key)) + int64(value.Len())
|
||||
}
|
||||
|
||||
func (c *cache) get(key string) (value ByteView, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.nget++
|
||||
if c.lru == nil {
|
||||
return
|
||||
}
|
||||
vi, ok := c.lru.Get(key)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
c.nhit++
|
||||
return vi.(ByteView), true
|
||||
}
|
||||
|
||||
func (c *cache) removeOldest() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.lru != nil {
|
||||
c.lru.RemoveOldest()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cache) bytes() int64 {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return c.nbytes
|
||||
}
|
||||
|
||||
func (c *cache) items() int64 {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return c.itemsLocked()
|
||||
}
|
||||
|
||||
func (c *cache) itemsLocked() int64 {
|
||||
if c.lru == nil {
|
||||
return 0
|
||||
}
|
||||
return int64(c.lru.Len())
|
||||
}
|
||||
|
||||
// An AtomicInt is an int64 to be accessed atomically.
|
||||
type AtomicInt int64
|
||||
|
||||
// Add atomically adds n to i.
|
||||
func (i *AtomicInt) Add(n int64) {
|
||||
atomic.AddInt64((*int64)(i), n)
|
||||
}
|
||||
|
||||
// Get atomically gets the value of i.
|
||||
func (i *AtomicInt) Get() int64 {
|
||||
return atomic.LoadInt64((*int64)(i))
|
||||
}
|
||||
|
||||
func (i *AtomicInt) String() string {
|
||||
return strconv.FormatInt(i.Get(), 10)
|
||||
}
|
||||
|
||||
// CacheStats are returned by stats accessors on Group.
|
||||
type CacheStats struct {
|
||||
Bytes int64
|
||||
Items int64
|
||||
Gets int64
|
||||
Hits int64
|
||||
Evictions int64
|
||||
}
|
456
vendor/github.com/golang/groupcache/groupcache_test.go
generated
vendored
456
vendor/github.com/golang/groupcache/groupcache_test.go
generated
vendored
@@ -1,456 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Tests for groupcache.
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
pb "github.com/golang/groupcache/groupcachepb"
|
||||
testpb "github.com/golang/groupcache/testpb"
|
||||
)
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
stringGroup, protoGroup Getter
|
||||
|
||||
stringc = make(chan string)
|
||||
|
||||
dummyCtx Context
|
||||
|
||||
// cacheFills is the number of times stringGroup or
|
||||
// protoGroup's Getter have been called. Read using the
|
||||
// cacheFills function.
|
||||
cacheFills AtomicInt
|
||||
)
|
||||
|
||||
const (
|
||||
stringGroupName = "string-group"
|
||||
protoGroupName = "proto-group"
|
||||
testMessageType = "google3/net/groupcache/go/test_proto.TestMessage"
|
||||
fromChan = "from-chan"
|
||||
cacheSize = 1 << 20
|
||||
)
|
||||
|
||||
func testSetup() {
|
||||
stringGroup = NewGroup(stringGroupName, cacheSize, GetterFunc(func(_ Context, key string, dest Sink) error {
|
||||
if key == fromChan {
|
||||
key = <-stringc
|
||||
}
|
||||
cacheFills.Add(1)
|
||||
return dest.SetString("ECHO:" + key)
|
||||
}))
|
||||
|
||||
protoGroup = NewGroup(protoGroupName, cacheSize, GetterFunc(func(_ Context, key string, dest Sink) error {
|
||||
if key == fromChan {
|
||||
key = <-stringc
|
||||
}
|
||||
cacheFills.Add(1)
|
||||
return dest.SetProto(&testpb.TestMessage{
|
||||
Name: proto.String("ECHO:" + key),
|
||||
City: proto.String("SOME-CITY"),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// tests that a Getter's Get method is only called once with two
|
||||
// outstanding callers. This is the string variant.
|
||||
func TestGetDupSuppressString(t *testing.T) {
|
||||
once.Do(testSetup)
|
||||
// Start two getters. The first should block (waiting reading
|
||||
// from stringc) and the second should latch on to the first
|
||||
// one.
|
||||
resc := make(chan string, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
var s string
|
||||
if err := stringGroup.Get(dummyCtx, fromChan, StringSink(&s)); err != nil {
|
||||
resc <- "ERROR:" + err.Error()
|
||||
return
|
||||
}
|
||||
resc <- s
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait a bit so both goroutines get merged together via
|
||||
// singleflight.
|
||||
// TODO(bradfitz): decide whether there are any non-offensive
|
||||
// debug/test hooks that could be added to singleflight to
|
||||
// make a sleep here unnecessary.
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
// Unblock the first getter, which should unblock the second
|
||||
// as well.
|
||||
stringc <- "foo"
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case v := <-resc:
|
||||
if v != "ECHO:foo" {
|
||||
t.Errorf("got %q; want %q", v, "ECHO:foo")
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Errorf("timeout waiting on getter #%d of 2", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tests that a Getter's Get method is only called once with two
|
||||
// outstanding callers. This is the proto variant.
|
||||
func TestGetDupSuppressProto(t *testing.T) {
|
||||
once.Do(testSetup)
|
||||
// Start two getters. The first should block (waiting reading
|
||||
// from stringc) and the second should latch on to the first
|
||||
// one.
|
||||
resc := make(chan *testpb.TestMessage, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
tm := new(testpb.TestMessage)
|
||||
if err := protoGroup.Get(dummyCtx, fromChan, ProtoSink(tm)); err != nil {
|
||||
tm.Name = proto.String("ERROR:" + err.Error())
|
||||
}
|
||||
resc <- tm
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait a bit so both goroutines get merged together via
|
||||
// singleflight.
|
||||
// TODO(bradfitz): decide whether there are any non-offensive
|
||||
// debug/test hooks that could be added to singleflight to
|
||||
// make a sleep here unnecessary.
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
// Unblock the first getter, which should unblock the second
|
||||
// as well.
|
||||
stringc <- "Fluffy"
|
||||
want := &testpb.TestMessage{
|
||||
Name: proto.String("ECHO:Fluffy"),
|
||||
City: proto.String("SOME-CITY"),
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case v := <-resc:
|
||||
if !reflect.DeepEqual(v, want) {
|
||||
t.Errorf(" Got: %v\nWant: %v", proto.CompactTextString(v), proto.CompactTextString(want))
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Errorf("timeout waiting on getter #%d of 2", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func countFills(f func()) int64 {
|
||||
fills0 := cacheFills.Get()
|
||||
f()
|
||||
return cacheFills.Get() - fills0
|
||||
}
|
||||
|
||||
func TestCaching(t *testing.T) {
|
||||
once.Do(testSetup)
|
||||
fills := countFills(func() {
|
||||
for i := 0; i < 10; i++ {
|
||||
var s string
|
||||
if err := stringGroup.Get(dummyCtx, "TestCaching-key", StringSink(&s)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
if fills != 1 {
|
||||
t.Errorf("expected 1 cache fill; got %d", fills)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheEviction(t *testing.T) {
|
||||
once.Do(testSetup)
|
||||
testKey := "TestCacheEviction-key"
|
||||
getTestKey := func() {
|
||||
var res string
|
||||
for i := 0; i < 10; i++ {
|
||||
if err := stringGroup.Get(dummyCtx, testKey, StringSink(&res)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
fills := countFills(getTestKey)
|
||||
if fills != 1 {
|
||||
t.Fatalf("expected 1 cache fill; got %d", fills)
|
||||
}
|
||||
|
||||
g := stringGroup.(*Group)
|
||||
evict0 := g.mainCache.nevict
|
||||
|
||||
// Trash the cache with other keys.
|
||||
var bytesFlooded int64
|
||||
// cacheSize/len(testKey) is approximate
|
||||
for bytesFlooded < cacheSize+1024 {
|
||||
var res string
|
||||
key := fmt.Sprintf("dummy-key-%d", bytesFlooded)
|
||||
stringGroup.Get(dummyCtx, key, StringSink(&res))
|
||||
bytesFlooded += int64(len(key) + len(res))
|
||||
}
|
||||
evicts := g.mainCache.nevict - evict0
|
||||
if evicts <= 0 {
|
||||
t.Errorf("evicts = %v; want more than 0", evicts)
|
||||
}
|
||||
|
||||
// Test that the key is gone.
|
||||
fills = countFills(getTestKey)
|
||||
if fills != 1 {
|
||||
t.Fatalf("expected 1 cache fill after cache trashing; got %d", fills)
|
||||
}
|
||||
}
|
||||
|
||||
type fakePeer struct {
|
||||
hits int
|
||||
fail bool
|
||||
}
|
||||
|
||||
func (p *fakePeer) Get(_ Context, in *pb.GetRequest, out *pb.GetResponse) error {
|
||||
p.hits++
|
||||
if p.fail {
|
||||
return errors.New("simulated error from peer")
|
||||
}
|
||||
out.Value = []byte("got:" + in.GetKey())
|
||||
return nil
|
||||
}
|
||||
|
||||
type fakePeers []ProtoGetter
|
||||
|
||||
func (p fakePeers) PickPeer(key string) (peer ProtoGetter, ok bool) {
|
||||
if len(p) == 0 {
|
||||
return
|
||||
}
|
||||
n := crc32.Checksum([]byte(key), crc32.IEEETable) % uint32(len(p))
|
||||
return p[n], p[n] != nil
|
||||
}
|
||||
|
||||
// tests that peers (virtual, in-process) are hit, and how much.
|
||||
func TestPeers(t *testing.T) {
|
||||
once.Do(testSetup)
|
||||
rand.Seed(123)
|
||||
peer0 := &fakePeer{}
|
||||
peer1 := &fakePeer{}
|
||||
peer2 := &fakePeer{}
|
||||
peerList := fakePeers([]ProtoGetter{peer0, peer1, peer2, nil})
|
||||
const cacheSize = 0 // disabled
|
||||
localHits := 0
|
||||
getter := func(_ Context, key string, dest Sink) error {
|
||||
localHits++
|
||||
return dest.SetString("got:" + key)
|
||||
}
|
||||
testGroup := newGroup("TestPeers-group", cacheSize, GetterFunc(getter), peerList)
|
||||
run := func(name string, n int, wantSummary string) {
|
||||
// Reset counters
|
||||
localHits = 0
|
||||
for _, p := range []*fakePeer{peer0, peer1, peer2} {
|
||||
p.hits = 0
|
||||
}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
key := fmt.Sprintf("key-%d", i)
|
||||
want := "got:" + key
|
||||
var got string
|
||||
err := testGroup.Get(dummyCtx, key, StringSink(&got))
|
||||
if err != nil {
|
||||
t.Errorf("%s: error on key %q: %v", name, key, err)
|
||||
continue
|
||||
}
|
||||
if got != want {
|
||||
t.Errorf("%s: for key %q, got %q; want %q", name, key, got, want)
|
||||
}
|
||||
}
|
||||
summary := func() string {
|
||||
return fmt.Sprintf("localHits = %d, peers = %d %d %d", localHits, peer0.hits, peer1.hits, peer2.hits)
|
||||
}
|
||||
if got := summary(); got != wantSummary {
|
||||
t.Errorf("%s: got %q; want %q", name, got, wantSummary)
|
||||
}
|
||||
}
|
||||
resetCacheSize := func(maxBytes int64) {
|
||||
g := testGroup
|
||||
g.cacheBytes = maxBytes
|
||||
g.mainCache = cache{}
|
||||
g.hotCache = cache{}
|
||||
}
|
||||
|
||||
// Base case; peers all up, with no problems.
|
||||
resetCacheSize(1 << 20)
|
||||
run("base", 200, "localHits = 49, peers = 51 49 51")
|
||||
|
||||
// Verify cache was hit. All localHits are gone, and some of
|
||||
// the peer hits (the ones randomly selected to be maybe hot)
|
||||
run("cached_base", 200, "localHits = 0, peers = 49 47 48")
|
||||
resetCacheSize(0)
|
||||
|
||||
// With one of the peers being down.
|
||||
// TODO(bradfitz): on a peer number being unavailable, the
|
||||
// consistent hashing should maybe keep trying others to
|
||||
// spread the load out. Currently it fails back to local
|
||||
// execution if the first consistent-hash slot is unavailable.
|
||||
peerList[0] = nil
|
||||
run("one_peer_down", 200, "localHits = 100, peers = 0 49 51")
|
||||
|
||||
// Failing peer
|
||||
peerList[0] = peer0
|
||||
peer0.fail = true
|
||||
run("peer0_failing", 200, "localHits = 100, peers = 51 49 51")
|
||||
}
|
||||
|
||||
func TestTruncatingByteSliceTarget(t *testing.T) {
|
||||
var buf [100]byte
|
||||
s := buf[:]
|
||||
if err := stringGroup.Get(dummyCtx, "short", TruncatingByteSliceSink(&s)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := "ECHO:short"; string(s) != want {
|
||||
t.Errorf("short key got %q; want %q", s, want)
|
||||
}
|
||||
|
||||
s = buf[:6]
|
||||
if err := stringGroup.Get(dummyCtx, "truncated", TruncatingByteSliceSink(&s)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := "ECHO:t"; string(s) != want {
|
||||
t.Errorf("truncated key got %q; want %q", s, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocatingByteSliceTarget(t *testing.T) {
|
||||
var dst []byte
|
||||
sink := AllocatingByteSliceSink(&dst)
|
||||
|
||||
inBytes := []byte("some bytes")
|
||||
sink.SetBytes(inBytes)
|
||||
if want := "some bytes"; string(dst) != want {
|
||||
t.Errorf("SetBytes resulted in %q; want %q", dst, want)
|
||||
}
|
||||
v, err := sink.view()
|
||||
if err != nil {
|
||||
t.Fatalf("view after SetBytes failed: %v", err)
|
||||
}
|
||||
if &inBytes[0] == &dst[0] {
|
||||
t.Error("inBytes and dst share memory")
|
||||
}
|
||||
if &inBytes[0] == &v.b[0] {
|
||||
t.Error("inBytes and view share memory")
|
||||
}
|
||||
if &dst[0] == &v.b[0] {
|
||||
t.Error("dst and view share memory")
|
||||
}
|
||||
}
|
||||
|
||||
// orderedFlightGroup allows the caller to force the schedule of when
|
||||
// orig.Do will be called. This is useful to serialize calls such
|
||||
// that singleflight cannot dedup them.
|
||||
type orderedFlightGroup struct {
|
||||
mu sync.Mutex
|
||||
stage1 chan bool
|
||||
stage2 chan bool
|
||||
orig flightGroup
|
||||
}
|
||||
|
||||
func (g *orderedFlightGroup) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
|
||||
<-g.stage1
|
||||
<-g.stage2
|
||||
g.mu.Lock()
|
||||
defer g.mu.Unlock()
|
||||
return g.orig.Do(key, fn)
|
||||
}
|
||||
|
||||
// TestNoDedup tests invariants on the cache size when singleflight is
|
||||
// unable to dedup calls.
|
||||
func TestNoDedup(t *testing.T) {
|
||||
const testkey = "testkey"
|
||||
const testval = "testval"
|
||||
g := newGroup("testgroup", 1024, GetterFunc(func(_ Context, key string, dest Sink) error {
|
||||
return dest.SetString(testval)
|
||||
}), nil)
|
||||
|
||||
orderedGroup := &orderedFlightGroup{
|
||||
stage1: make(chan bool),
|
||||
stage2: make(chan bool),
|
||||
orig: g.loadGroup,
|
||||
}
|
||||
// Replace loadGroup with our wrapper so we can control when
|
||||
// loadGroup.Do is entered for each concurrent request.
|
||||
g.loadGroup = orderedGroup
|
||||
|
||||
// Issue two idential requests concurrently. Since the cache is
|
||||
// empty, it will miss. Both will enter load(), but we will only
|
||||
// allow one at a time to enter singleflight.Do, so the callback
|
||||
// function will be called twice.
|
||||
resc := make(chan string, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
var s string
|
||||
if err := g.Get(dummyCtx, testkey, StringSink(&s)); err != nil {
|
||||
resc <- "ERROR:" + err.Error()
|
||||
return
|
||||
}
|
||||
resc <- s
|
||||
}()
|
||||
}
|
||||
|
||||
// Ensure both goroutines have entered the Do routine. This implies
|
||||
// both concurrent requests have checked the cache, found it empty,
|
||||
// and called load().
|
||||
orderedGroup.stage1 <- true
|
||||
orderedGroup.stage1 <- true
|
||||
orderedGroup.stage2 <- true
|
||||
orderedGroup.stage2 <- true
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
if s := <-resc; s != testval {
|
||||
t.Errorf("result is %s want %s", s, testval)
|
||||
}
|
||||
}
|
||||
|
||||
const wantItems = 1
|
||||
if g.mainCache.items() != wantItems {
|
||||
t.Errorf("mainCache has %d items, want %d", g.mainCache.items(), wantItems)
|
||||
}
|
||||
|
||||
// If the singleflight callback doesn't double-check the cache again
|
||||
// upon entry, we would increment nbytes twice but the entry would
|
||||
// only be in the cache once.
|
||||
const wantBytes = int64(len(testkey) + len(testval))
|
||||
if g.mainCache.nbytes != wantBytes {
|
||||
t.Errorf("cache has %d bytes, want %d", g.mainCache.nbytes, wantBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupStatsAlignment(t *testing.T) {
|
||||
var g Group
|
||||
off := unsafe.Offsetof(g.Stats)
|
||||
if off%8 != 0 {
|
||||
t.Fatal("Stats structure is not 8-byte aligned.")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(bradfitz): port the Google-internal full integration test into here,
|
||||
// using HTTP requests instead of our RPC system.
|
65
vendor/github.com/golang/groupcache/groupcachepb/groupcache.pb.go
generated
vendored
65
vendor/github.com/golang/groupcache/groupcachepb/groupcache.pb.go
generated
vendored
@@ -1,65 +0,0 @@
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: groupcache.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package groupcachepb
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import json "encoding/json"
|
||||
import math "math"
|
||||
|
||||
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = &json.SyntaxError{}
|
||||
var _ = math.Inf
|
||||
|
||||
type GetRequest struct {
|
||||
Group *string `protobuf:"bytes,1,req,name=group" json:"group,omitempty"`
|
||||
Key *string `protobuf:"bytes,2,req,name=key" json:"key,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetRequest) Reset() { *m = GetRequest{} }
|
||||
func (m *GetRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetRequest) ProtoMessage() {}
|
||||
|
||||
func (m *GetRequest) GetGroup() string {
|
||||
if m != nil && m.Group != nil {
|
||||
return *m.Group
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GetRequest) GetKey() string {
|
||||
if m != nil && m.Key != nil {
|
||||
return *m.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetResponse struct {
|
||||
Value []byte `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
|
||||
MinuteQps *float64 `protobuf:"fixed64,2,opt,name=minute_qps" json:"minute_qps,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetResponse) Reset() { *m = GetResponse{} }
|
||||
func (m *GetResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetResponse) ProtoMessage() {}
|
||||
|
||||
func (m *GetResponse) GetValue() []byte {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetResponse) GetMinuteQps() float64 {
|
||||
if m != nil && m.MinuteQps != nil {
|
||||
return *m.MinuteQps
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
34
vendor/github.com/golang/groupcache/groupcachepb/groupcache.proto
generated
vendored
34
vendor/github.com/golang/groupcache/groupcachepb/groupcache.proto
generated
vendored
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package groupcachepb;
|
||||
|
||||
message GetRequest {
|
||||
required string group = 1;
|
||||
required string key = 2; // not actually required/guaranteed to be UTF-8
|
||||
}
|
||||
|
||||
message GetResponse {
|
||||
optional bytes value = 1;
|
||||
optional double minute_qps = 2;
|
||||
}
|
||||
|
||||
service GroupCache {
|
||||
rpc Get(GetRequest) returns (GetResponse) {
|
||||
};
|
||||
}
|
227
vendor/github.com/golang/groupcache/http.go
generated
vendored
227
vendor/github.com/golang/groupcache/http.go
generated
vendored
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/groupcache/consistenthash"
|
||||
pb "github.com/golang/groupcache/groupcachepb"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
const defaultBasePath = "/_groupcache/"
|
||||
|
||||
const defaultReplicas = 50
|
||||
|
||||
// HTTPPool implements PeerPicker for a pool of HTTP peers.
|
||||
type HTTPPool struct {
|
||||
// Context optionally specifies a context for the server to use when it
|
||||
// receives a request.
|
||||
// If nil, the server uses a nil Context.
|
||||
Context func(*http.Request) Context
|
||||
|
||||
// Transport optionally specifies an http.RoundTripper for the client
|
||||
// to use when it makes a request.
|
||||
// If nil, the client uses http.DefaultTransport.
|
||||
Transport func(Context) http.RoundTripper
|
||||
|
||||
// this peer's base URL, e.g. "https://example.net:8000"
|
||||
self string
|
||||
|
||||
// opts specifies the options.
|
||||
opts HTTPPoolOptions
|
||||
|
||||
mu sync.Mutex // guards peers and httpGetters
|
||||
peers *consistenthash.Map
|
||||
httpGetters map[string]*httpGetter // keyed by e.g. "http://10.0.0.2:8008"
|
||||
}
|
||||
|
||||
// HTTPPoolOptions are the configurations of a HTTPPool.
|
||||
type HTTPPoolOptions struct {
|
||||
// BasePath specifies the HTTP path that will serve groupcache requests.
|
||||
// If blank, it defaults to "/_groupcache/".
|
||||
BasePath string
|
||||
|
||||
// Replicas specifies the number of key replicas on the consistent hash.
|
||||
// If blank, it defaults to 50.
|
||||
Replicas int
|
||||
|
||||
// HashFn specifies the hash function of the consistent hash.
|
||||
// If blank, it defaults to crc32.ChecksumIEEE.
|
||||
HashFn consistenthash.Hash
|
||||
}
|
||||
|
||||
// NewHTTPPool initializes an HTTP pool of peers, and registers itself as a PeerPicker.
|
||||
// For convenience, it also registers itself as an http.Handler with http.DefaultServeMux.
|
||||
// The self argument should be a valid base URL that points to the current server,
|
||||
// for example "http://example.net:8000".
|
||||
func NewHTTPPool(self string) *HTTPPool {
|
||||
p := NewHTTPPoolOpts(self, nil)
|
||||
http.Handle(p.opts.BasePath, p)
|
||||
return p
|
||||
}
|
||||
|
||||
var httpPoolMade bool
|
||||
|
||||
// NewHTTPPoolOpts initializes an HTTP pool of peers with the given options.
|
||||
// Unlike NewHTTPPool, this function does not register the created pool as an HTTP handler.
|
||||
// The returned *HTTPPool implements http.Handler and must be registered using http.Handle.
|
||||
func NewHTTPPoolOpts(self string, o *HTTPPoolOptions) *HTTPPool {
|
||||
if httpPoolMade {
|
||||
panic("groupcache: NewHTTPPool must be called only once")
|
||||
}
|
||||
httpPoolMade = true
|
||||
|
||||
p := &HTTPPool{
|
||||
self: self,
|
||||
httpGetters: make(map[string]*httpGetter),
|
||||
}
|
||||
if o != nil {
|
||||
p.opts = *o
|
||||
}
|
||||
if p.opts.BasePath == "" {
|
||||
p.opts.BasePath = defaultBasePath
|
||||
}
|
||||
if p.opts.Replicas == 0 {
|
||||
p.opts.Replicas = defaultReplicas
|
||||
}
|
||||
p.peers = consistenthash.New(p.opts.Replicas, p.opts.HashFn)
|
||||
|
||||
RegisterPeerPicker(func() PeerPicker { return p })
|
||||
return p
|
||||
}
|
||||
|
||||
// Set updates the pool's list of peers.
|
||||
// Each peer value should be a valid base URL,
|
||||
// for example "http://example.net:8000".
|
||||
func (p *HTTPPool) Set(peers ...string) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.peers = consistenthash.New(p.opts.Replicas, p.opts.HashFn)
|
||||
p.peers.Add(peers...)
|
||||
p.httpGetters = make(map[string]*httpGetter, len(peers))
|
||||
for _, peer := range peers {
|
||||
p.httpGetters[peer] = &httpGetter{transport: p.Transport, baseURL: peer + p.opts.BasePath}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *HTTPPool) PickPeer(key string) (ProtoGetter, bool) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
if p.peers.IsEmpty() {
|
||||
return nil, false
|
||||
}
|
||||
if peer := p.peers.Get(key); peer != p.self {
|
||||
return p.httpGetters[peer], true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Parse request.
|
||||
if !strings.HasPrefix(r.URL.Path, p.opts.BasePath) {
|
||||
panic("HTTPPool serving unexpected path: " + r.URL.Path)
|
||||
}
|
||||
parts := strings.SplitN(r.URL.Path[len(p.opts.BasePath):], "/", 2)
|
||||
if len(parts) != 2 {
|
||||
http.Error(w, "bad request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
groupName := parts[0]
|
||||
key := parts[1]
|
||||
|
||||
// Fetch the value for this group/key.
|
||||
group := GetGroup(groupName)
|
||||
if group == nil {
|
||||
http.Error(w, "no such group: "+groupName, http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
var ctx Context
|
||||
if p.Context != nil {
|
||||
ctx = p.Context(r)
|
||||
}
|
||||
|
||||
group.Stats.ServerRequests.Add(1)
|
||||
var value []byte
|
||||
err := group.Get(ctx, key, AllocatingByteSliceSink(&value))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Write the value to the response body as a proto message.
|
||||
body, err := proto.Marshal(&pb.GetResponse{Value: value})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/x-protobuf")
|
||||
w.Write(body)
|
||||
}
|
||||
|
||||
type httpGetter struct {
|
||||
transport func(Context) http.RoundTripper
|
||||
baseURL string
|
||||
}
|
||||
|
||||
var bufferPool = sync.Pool{
|
||||
New: func() interface{} { return new(bytes.Buffer) },
|
||||
}
|
||||
|
||||
func (h *httpGetter) Get(context Context, in *pb.GetRequest, out *pb.GetResponse) error {
|
||||
u := fmt.Sprintf(
|
||||
"%v%v/%v",
|
||||
h.baseURL,
|
||||
url.QueryEscape(in.GetGroup()),
|
||||
url.QueryEscape(in.GetKey()),
|
||||
)
|
||||
req, err := http.NewRequest("GET", u, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tr := http.DefaultTransport
|
||||
if h.transport != nil {
|
||||
tr = h.transport(context)
|
||||
}
|
||||
res, err := tr.RoundTrip(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("server returned: %v", res.Status)
|
||||
}
|
||||
b := bufferPool.Get().(*bytes.Buffer)
|
||||
b.Reset()
|
||||
defer bufferPool.Put(b)
|
||||
_, err = io.Copy(b, res.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading response body: %v", err)
|
||||
}
|
||||
err = proto.Unmarshal(b.Bytes(), out)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding response body: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
166
vendor/github.com/golang/groupcache/http_test.go
generated
vendored
166
vendor/github.com/golang/groupcache/http_test.go
generated
vendored
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
peerAddrs = flag.String("test_peer_addrs", "", "Comma-separated list of peer addresses; used by TestHTTPPool")
|
||||
peerIndex = flag.Int("test_peer_index", -1, "Index of which peer this child is; used by TestHTTPPool")
|
||||
peerChild = flag.Bool("test_peer_child", false, "True if running as a child process; used by TestHTTPPool")
|
||||
)
|
||||
|
||||
func TestHTTPPool(t *testing.T) {
|
||||
if *peerChild {
|
||||
beChildForTestHTTPPool()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
const (
|
||||
nChild = 4
|
||||
nGets = 100
|
||||
)
|
||||
|
||||
var childAddr []string
|
||||
for i := 0; i < nChild; i++ {
|
||||
childAddr = append(childAddr, pickFreeAddr(t))
|
||||
}
|
||||
|
||||
var cmds []*exec.Cmd
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < nChild; i++ {
|
||||
cmd := exec.Command(os.Args[0],
|
||||
"--test.run=TestHTTPPool",
|
||||
"--test_peer_child",
|
||||
"--test_peer_addrs="+strings.Join(childAddr, ","),
|
||||
"--test_peer_index="+strconv.Itoa(i),
|
||||
)
|
||||
cmds = append(cmds, cmd)
|
||||
wg.Add(1)
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal("failed to start child process: ", err)
|
||||
}
|
||||
go awaitAddrReady(t, childAddr[i], &wg)
|
||||
}
|
||||
defer func() {
|
||||
for i := 0; i < nChild; i++ {
|
||||
if cmds[i].Process != nil {
|
||||
cmds[i].Process.Kill()
|
||||
}
|
||||
}
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
// Use a dummy self address so that we don't handle gets in-process.
|
||||
p := NewHTTPPool("should-be-ignored")
|
||||
p.Set(addrToURL(childAddr)...)
|
||||
|
||||
// Dummy getter function. Gets should go to children only.
|
||||
// The only time this process will handle a get is when the
|
||||
// children can't be contacted for some reason.
|
||||
getter := GetterFunc(func(ctx Context, key string, dest Sink) error {
|
||||
return errors.New("parent getter called; something's wrong")
|
||||
})
|
||||
g := NewGroup("httpPoolTest", 1<<20, getter)
|
||||
|
||||
for _, key := range testKeys(nGets) {
|
||||
var value string
|
||||
if err := g.Get(nil, key, StringSink(&value)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if suffix := ":" + key; !strings.HasSuffix(value, suffix) {
|
||||
t.Errorf("Get(%q) = %q, want value ending in %q", key, value, suffix)
|
||||
}
|
||||
t.Logf("Get key=%q, value=%q (peer:key)", key, value)
|
||||
}
|
||||
}
|
||||
|
||||
func testKeys(n int) (keys []string) {
|
||||
keys = make([]string, n)
|
||||
for i := range keys {
|
||||
keys[i] = strconv.Itoa(i)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func beChildForTestHTTPPool() {
|
||||
addrs := strings.Split(*peerAddrs, ",")
|
||||
|
||||
p := NewHTTPPool("http://" + addrs[*peerIndex])
|
||||
p.Set(addrToURL(addrs)...)
|
||||
|
||||
getter := GetterFunc(func(ctx Context, key string, dest Sink) error {
|
||||
dest.SetString(strconv.Itoa(*peerIndex) + ":" + key)
|
||||
return nil
|
||||
})
|
||||
NewGroup("httpPoolTest", 1<<20, getter)
|
||||
|
||||
log.Fatal(http.ListenAndServe(addrs[*peerIndex], p))
|
||||
}
|
||||
|
||||
// This is racy. Another process could swoop in and steal the port between the
|
||||
// call to this function and the next listen call. Should be okay though.
|
||||
// The proper way would be to pass the l.File() as ExtraFiles to the child
|
||||
// process, and then close your copy once the child starts.
|
||||
func pickFreeAddr(t *testing.T) string {
|
||||
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer l.Close()
|
||||
return l.Addr().String()
|
||||
}
|
||||
|
||||
func addrToURL(addr []string) []string {
|
||||
url := make([]string, len(addr))
|
||||
for i := range addr {
|
||||
url[i] = "http://" + addr[i]
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
func awaitAddrReady(t *testing.T, addr string, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
const max = 1 * time.Second
|
||||
tries := 0
|
||||
for {
|
||||
tries++
|
||||
c, err := net.Dial("tcp", addr)
|
||||
if err == nil {
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
delay := time.Duration(tries) * 25 * time.Millisecond
|
||||
if delay > max {
|
||||
delay = max
|
||||
}
|
||||
time.Sleep(delay)
|
||||
}
|
||||
}
|
97
vendor/github.com/golang/groupcache/lru/lru_test.go
generated
vendored
97
vendor/github.com/golang/groupcache/lru/lru_test.go
generated
vendored
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package lru
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type simpleStruct struct {
|
||||
int
|
||||
string
|
||||
}
|
||||
|
||||
type complexStruct struct {
|
||||
int
|
||||
simpleStruct
|
||||
}
|
||||
|
||||
var getTests = []struct {
|
||||
name string
|
||||
keyToAdd interface{}
|
||||
keyToGet interface{}
|
||||
expectedOk bool
|
||||
}{
|
||||
{"string_hit", "myKey", "myKey", true},
|
||||
{"string_miss", "myKey", "nonsense", false},
|
||||
{"simple_struct_hit", simpleStruct{1, "two"}, simpleStruct{1, "two"}, true},
|
||||
{"simple_struct_miss", simpleStruct{1, "two"}, simpleStruct{0, "noway"}, false},
|
||||
{"complex_struct_hit", complexStruct{1, simpleStruct{2, "three"}},
|
||||
complexStruct{1, simpleStruct{2, "three"}}, true},
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
for _, tt := range getTests {
|
||||
lru := New(0)
|
||||
lru.Add(tt.keyToAdd, 1234)
|
||||
val, ok := lru.Get(tt.keyToGet)
|
||||
if ok != tt.expectedOk {
|
||||
t.Fatalf("%s: cache hit = %v; want %v", tt.name, ok, !ok)
|
||||
} else if ok && val != 1234 {
|
||||
t.Fatalf("%s expected get to return 1234 but got %v", tt.name, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
lru := New(0)
|
||||
lru.Add("myKey", 1234)
|
||||
if val, ok := lru.Get("myKey"); !ok {
|
||||
t.Fatal("TestRemove returned no match")
|
||||
} else if val != 1234 {
|
||||
t.Fatalf("TestRemove failed. Expected %d, got %v", 1234, val)
|
||||
}
|
||||
|
||||
lru.Remove("myKey")
|
||||
if _, ok := lru.Get("myKey"); ok {
|
||||
t.Fatal("TestRemove returned a removed entry")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvict(t *testing.T) {
|
||||
evictedKeys := make([]Key, 0)
|
||||
onEvictedFun := func(key Key, value interface{}) {
|
||||
evictedKeys = append(evictedKeys, key)
|
||||
}
|
||||
|
||||
lru := New(20)
|
||||
lru.OnEvicted = onEvictedFun
|
||||
for i := 0; i < 22; i++ {
|
||||
lru.Add(fmt.Sprintf("myKey%d", i), 1234)
|
||||
}
|
||||
|
||||
if len(evictedKeys) != 2 {
|
||||
t.Fatalf("got %d evicted keys; want 2", len(evictedKeys))
|
||||
}
|
||||
if evictedKeys[0] != Key("myKey0") {
|
||||
t.Fatalf("got %v in first evicted key; want %s", evictedKeys[0], "myKey0")
|
||||
}
|
||||
if evictedKeys[1] != Key("myKey1") {
|
||||
t.Fatalf("got %v in second evicted key; want %s", evictedKeys[1], "myKey1")
|
||||
}
|
||||
}
|
85
vendor/github.com/golang/groupcache/peers.go
generated
vendored
85
vendor/github.com/golang/groupcache/peers.go
generated
vendored
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// peers.go defines how processes find and communicate with their peers.
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
pb "github.com/golang/groupcache/groupcachepb"
|
||||
)
|
||||
|
||||
// Context is an opaque value passed through calls to the
|
||||
// ProtoGetter. It may be nil if your ProtoGetter implementation does
|
||||
// not require a context.
|
||||
type Context interface{}
|
||||
|
||||
// ProtoGetter is the interface that must be implemented by a peer.
|
||||
type ProtoGetter interface {
|
||||
Get(context Context, in *pb.GetRequest, out *pb.GetResponse) error
|
||||
}
|
||||
|
||||
// PeerPicker is the interface that must be implemented to locate
|
||||
// the peer that owns a specific key.
|
||||
type PeerPicker interface {
|
||||
// PickPeer returns the peer that owns the specific key
|
||||
// and true to indicate that a remote peer was nominated.
|
||||
// It returns nil, false if the key owner is the current peer.
|
||||
PickPeer(key string) (peer ProtoGetter, ok bool)
|
||||
}
|
||||
|
||||
// NoPeers is an implementation of PeerPicker that never finds a peer.
|
||||
type NoPeers struct{}
|
||||
|
||||
func (NoPeers) PickPeer(key string) (peer ProtoGetter, ok bool) { return }
|
||||
|
||||
var (
|
||||
portPicker func(groupName string) PeerPicker
|
||||
)
|
||||
|
||||
// RegisterPeerPicker registers the peer initialization function.
|
||||
// It is called once, when the first group is created.
|
||||
// Either RegisterPeerPicker or RegisterPerGroupPeerPicker should be
|
||||
// called exactly once, but not both.
|
||||
func RegisterPeerPicker(fn func() PeerPicker) {
|
||||
if portPicker != nil {
|
||||
panic("RegisterPeerPicker called more than once")
|
||||
}
|
||||
portPicker = func(_ string) PeerPicker { return fn() }
|
||||
}
|
||||
|
||||
// RegisterPerGroupPeerPicker registers the peer initialization function,
|
||||
// which takes the groupName, to be used in choosing a PeerPicker.
|
||||
// It is called once, when the first group is created.
|
||||
// Either RegisterPeerPicker or RegisterPerGroupPeerPicker should be
|
||||
// called exactly once, but not both.
|
||||
func RegisterPerGroupPeerPicker(fn func(groupName string) PeerPicker) {
|
||||
if portPicker != nil {
|
||||
panic("RegisterPeerPicker called more than once")
|
||||
}
|
||||
portPicker = fn
|
||||
}
|
||||
|
||||
func getPeers(groupName string) PeerPicker {
|
||||
if portPicker == nil {
|
||||
return NoPeers{}
|
||||
}
|
||||
pk := portPicker(groupName)
|
||||
if pk == nil {
|
||||
pk = NoPeers{}
|
||||
}
|
||||
return pk
|
||||
}
|
64
vendor/github.com/golang/groupcache/singleflight/singleflight.go
generated
vendored
64
vendor/github.com/golang/groupcache/singleflight/singleflight.go
generated
vendored
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package singleflight provides a duplicate function call suppression
|
||||
// mechanism.
|
||||
package singleflight
|
||||
|
||||
import "sync"
|
||||
|
||||
// call is an in-flight or completed Do call
|
||||
type call struct {
|
||||
wg sync.WaitGroup
|
||||
val interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
// Group represents a class of work and forms a namespace in which
|
||||
// units of work can be executed with duplicate suppression.
|
||||
type Group struct {
|
||||
mu sync.Mutex // protects m
|
||||
m map[string]*call // lazily initialized
|
||||
}
|
||||
|
||||
// Do executes and returns the results of the given function, making
|
||||
// sure that only one execution is in-flight for a given key at a
|
||||
// time. If a duplicate comes in, the duplicate caller waits for the
|
||||
// original to complete and receives the same results.
|
||||
func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
|
||||
g.mu.Lock()
|
||||
if g.m == nil {
|
||||
g.m = make(map[string]*call)
|
||||
}
|
||||
if c, ok := g.m[key]; ok {
|
||||
g.mu.Unlock()
|
||||
c.wg.Wait()
|
||||
return c.val, c.err
|
||||
}
|
||||
c := new(call)
|
||||
c.wg.Add(1)
|
||||
g.m[key] = c
|
||||
g.mu.Unlock()
|
||||
|
||||
c.val, c.err = fn()
|
||||
c.wg.Done()
|
||||
|
||||
g.mu.Lock()
|
||||
delete(g.m, key)
|
||||
g.mu.Unlock()
|
||||
|
||||
return c.val, c.err
|
||||
}
|
85
vendor/github.com/golang/groupcache/singleflight/singleflight_test.go
generated
vendored
85
vendor/github.com/golang/groupcache/singleflight/singleflight_test.go
generated
vendored
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package singleflight
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDo(t *testing.T) {
|
||||
var g Group
|
||||
v, err := g.Do("key", func() (interface{}, error) {
|
||||
return "bar", nil
|
||||
})
|
||||
if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want {
|
||||
t.Errorf("Do = %v; want %v", got, want)
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Do error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoErr(t *testing.T) {
|
||||
var g Group
|
||||
someErr := errors.New("Some error")
|
||||
v, err := g.Do("key", func() (interface{}, error) {
|
||||
return nil, someErr
|
||||
})
|
||||
if err != someErr {
|
||||
t.Errorf("Do error = %v; want someErr", err)
|
||||
}
|
||||
if v != nil {
|
||||
t.Errorf("unexpected non-nil value %#v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoDupSuppress(t *testing.T) {
|
||||
var g Group
|
||||
c := make(chan string)
|
||||
var calls int32
|
||||
fn := func() (interface{}, error) {
|
||||
atomic.AddInt32(&calls, 1)
|
||||
return <-c, nil
|
||||
}
|
||||
|
||||
const n = 10
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < n; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
v, err := g.Do("key", fn)
|
||||
if err != nil {
|
||||
t.Errorf("Do error: %v", err)
|
||||
}
|
||||
if v.(string) != "bar" {
|
||||
t.Errorf("got %q; want %q", v, "bar")
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond) // let goroutines above block
|
||||
c <- "bar"
|
||||
wg.Wait()
|
||||
if got := atomic.LoadInt32(&calls); got != 1 {
|
||||
t.Errorf("number of calls = %d; want 1", got)
|
||||
}
|
||||
}
|
322
vendor/github.com/golang/groupcache/sinks.go
generated
vendored
322
vendor/github.com/golang/groupcache/sinks.go
generated
vendored
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package groupcache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
// A Sink receives data from a Get call.
|
||||
//
|
||||
// Implementation of Getter must call exactly one of the Set methods
|
||||
// on success.
|
||||
type Sink interface {
|
||||
// SetString sets the value to s.
|
||||
SetString(s string) error
|
||||
|
||||
// SetBytes sets the value to the contents of v.
|
||||
// The caller retains ownership of v.
|
||||
SetBytes(v []byte) error
|
||||
|
||||
// SetProto sets the value to the encoded version of m.
|
||||
// The caller retains ownership of m.
|
||||
SetProto(m proto.Message) error
|
||||
|
||||
// view returns a frozen view of the bytes for caching.
|
||||
view() (ByteView, error)
|
||||
}
|
||||
|
||||
func cloneBytes(b []byte) []byte {
|
||||
c := make([]byte, len(b))
|
||||
copy(c, b)
|
||||
return c
|
||||
}
|
||||
|
||||
func setSinkView(s Sink, v ByteView) error {
|
||||
// A viewSetter is a Sink that can also receive its value from
|
||||
// a ByteView. This is a fast path to minimize copies when the
|
||||
// item was already cached locally in memory (where it's
|
||||
// cached as a ByteView)
|
||||
type viewSetter interface {
|
||||
setView(v ByteView) error
|
||||
}
|
||||
if vs, ok := s.(viewSetter); ok {
|
||||
return vs.setView(v)
|
||||
}
|
||||
if v.b != nil {
|
||||
return s.SetBytes(v.b)
|
||||
}
|
||||
return s.SetString(v.s)
|
||||
}
|
||||
|
||||
// StringSink returns a Sink that populates the provided string pointer.
|
||||
func StringSink(sp *string) Sink {
|
||||
return &stringSink{sp: sp}
|
||||
}
|
||||
|
||||
type stringSink struct {
|
||||
sp *string
|
||||
v ByteView
|
||||
// TODO(bradfitz): track whether any Sets were called.
|
||||
}
|
||||
|
||||
func (s *stringSink) view() (ByteView, error) {
|
||||
// TODO(bradfitz): return an error if no Set was called
|
||||
return s.v, nil
|
||||
}
|
||||
|
||||
func (s *stringSink) SetString(v string) error {
|
||||
s.v.b = nil
|
||||
s.v.s = v
|
||||
*s.sp = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringSink) SetBytes(v []byte) error {
|
||||
return s.SetString(string(v))
|
||||
}
|
||||
|
||||
func (s *stringSink) SetProto(m proto.Message) error {
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.v.b = b
|
||||
*s.sp = string(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByteViewSink returns a Sink that populates a ByteView.
|
||||
func ByteViewSink(dst *ByteView) Sink {
|
||||
if dst == nil {
|
||||
panic("nil dst")
|
||||
}
|
||||
return &byteViewSink{dst: dst}
|
||||
}
|
||||
|
||||
type byteViewSink struct {
|
||||
dst *ByteView
|
||||
|
||||
// if this code ever ends up tracking that at least one set*
|
||||
// method was called, don't make it an error to call set
|
||||
// methods multiple times. Lorry's payload.go does that, and
|
||||
// it makes sense. The comment at the top of this file about
|
||||
// "exactly one of the Set methods" is overly strict. We
|
||||
// really care about at least once (in a handler), but if
|
||||
// multiple handlers fail (or multiple functions in a program
|
||||
// using a Sink), it's okay to re-use the same one.
|
||||
}
|
||||
|
||||
func (s *byteViewSink) setView(v ByteView) error {
|
||||
*s.dst = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *byteViewSink) view() (ByteView, error) {
|
||||
return *s.dst, nil
|
||||
}
|
||||
|
||||
func (s *byteViewSink) SetProto(m proto.Message) error {
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s.dst = ByteView{b: b}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *byteViewSink) SetBytes(b []byte) error {
|
||||
*s.dst = ByteView{b: cloneBytes(b)}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *byteViewSink) SetString(v string) error {
|
||||
*s.dst = ByteView{s: v}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProtoSink returns a sink that unmarshals binary proto values into m.
|
||||
func ProtoSink(m proto.Message) Sink {
|
||||
return &protoSink{
|
||||
dst: m,
|
||||
}
|
||||
}
|
||||
|
||||
type protoSink struct {
|
||||
dst proto.Message // authoritative value
|
||||
typ string
|
||||
|
||||
v ByteView // encoded
|
||||
}
|
||||
|
||||
func (s *protoSink) view() (ByteView, error) {
|
||||
return s.v, nil
|
||||
}
|
||||
|
||||
func (s *protoSink) SetBytes(b []byte) error {
|
||||
err := proto.Unmarshal(b, s.dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.v.b = cloneBytes(b)
|
||||
s.v.s = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *protoSink) SetString(v string) error {
|
||||
b := []byte(v)
|
||||
err := proto.Unmarshal(b, s.dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.v.b = b
|
||||
s.v.s = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *protoSink) SetProto(m proto.Message) error {
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(bradfitz): optimize for same-task case more and write
|
||||
// right through? would need to document ownership rules at
|
||||
// the same time. but then we could just assign *dst = *m
|
||||
// here. This works for now:
|
||||
err = proto.Unmarshal(b, s.dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.v.b = b
|
||||
s.v.s = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllocatingByteSliceSink returns a Sink that allocates
|
||||
// a byte slice to hold the received value and assigns
|
||||
// it to *dst. The memory is not retained by groupcache.
|
||||
func AllocatingByteSliceSink(dst *[]byte) Sink {
|
||||
return &allocBytesSink{dst: dst}
|
||||
}
|
||||
|
||||
type allocBytesSink struct {
|
||||
dst *[]byte
|
||||
v ByteView
|
||||
}
|
||||
|
||||
func (s *allocBytesSink) view() (ByteView, error) {
|
||||
return s.v, nil
|
||||
}
|
||||
|
||||
func (s *allocBytesSink) setView(v ByteView) error {
|
||||
if v.b != nil {
|
||||
*s.dst = cloneBytes(v.b)
|
||||
} else {
|
||||
*s.dst = []byte(v.s)
|
||||
}
|
||||
s.v = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *allocBytesSink) SetProto(m proto.Message) error {
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.setBytesOwned(b)
|
||||
}
|
||||
|
||||
func (s *allocBytesSink) SetBytes(b []byte) error {
|
||||
return s.setBytesOwned(cloneBytes(b))
|
||||
}
|
||||
|
||||
func (s *allocBytesSink) setBytesOwned(b []byte) error {
|
||||
if s.dst == nil {
|
||||
return errors.New("nil AllocatingByteSliceSink *[]byte dst")
|
||||
}
|
||||
*s.dst = cloneBytes(b) // another copy, protecting the read-only s.v.b view
|
||||
s.v.b = b
|
||||
s.v.s = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *allocBytesSink) SetString(v string) error {
|
||||
if s.dst == nil {
|
||||
return errors.New("nil AllocatingByteSliceSink *[]byte dst")
|
||||
}
|
||||
*s.dst = []byte(v)
|
||||
s.v.b = nil
|
||||
s.v.s = v
|
||||
return nil
|
||||
}
|
||||
|
||||
// TruncatingByteSliceSink returns a Sink that writes up to len(*dst)
|
||||
// bytes to *dst. If more bytes are available, they're silently
|
||||
// truncated. If fewer bytes are available than len(*dst), *dst
|
||||
// is shrunk to fit the number of bytes available.
|
||||
func TruncatingByteSliceSink(dst *[]byte) Sink {
|
||||
return &truncBytesSink{dst: dst}
|
||||
}
|
||||
|
||||
type truncBytesSink struct {
|
||||
dst *[]byte
|
||||
v ByteView
|
||||
}
|
||||
|
||||
func (s *truncBytesSink) view() (ByteView, error) {
|
||||
return s.v, nil
|
||||
}
|
||||
|
||||
func (s *truncBytesSink) SetProto(m proto.Message) error {
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.setBytesOwned(b)
|
||||
}
|
||||
|
||||
func (s *truncBytesSink) SetBytes(b []byte) error {
|
||||
return s.setBytesOwned(cloneBytes(b))
|
||||
}
|
||||
|
||||
func (s *truncBytesSink) setBytesOwned(b []byte) error {
|
||||
if s.dst == nil {
|
||||
return errors.New("nil TruncatingByteSliceSink *[]byte dst")
|
||||
}
|
||||
n := copy(*s.dst, b)
|
||||
if n < len(*s.dst) {
|
||||
*s.dst = (*s.dst)[:n]
|
||||
}
|
||||
s.v.b = b
|
||||
s.v.s = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *truncBytesSink) SetString(v string) error {
|
||||
if s.dst == nil {
|
||||
return errors.New("nil TruncatingByteSliceSink *[]byte dst")
|
||||
}
|
||||
n := copy(*s.dst, v)
|
||||
if n < len(*s.dst) {
|
||||
*s.dst = (*s.dst)[:n]
|
||||
}
|
||||
s.v.b = nil
|
||||
s.v.s = v
|
||||
return nil
|
||||
}
|
235
vendor/github.com/golang/groupcache/testpb/test.pb.go
generated
vendored
235
vendor/github.com/golang/groupcache/testpb/test.pb.go
generated
vendored
@@ -1,235 +0,0 @@
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: test.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package testpb
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import json "encoding/json"
|
||||
import math "math"
|
||||
|
||||
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = &json.SyntaxError{}
|
||||
var _ = math.Inf
|
||||
|
||||
type TestMessage struct {
|
||||
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
City *string `protobuf:"bytes,2,opt,name=city" json:"city,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TestMessage) Reset() { *m = TestMessage{} }
|
||||
func (m *TestMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*TestMessage) ProtoMessage() {}
|
||||
|
||||
func (m *TestMessage) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
return *m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TestMessage) GetCity() string {
|
||||
if m != nil && m.City != nil {
|
||||
return *m.City
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TestRequest struct {
|
||||
Lower *string `protobuf:"bytes,1,req,name=lower" json:"lower,omitempty"`
|
||||
RepeatCount *int32 `protobuf:"varint,2,opt,name=repeat_count,def=1" json:"repeat_count,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TestRequest) Reset() { *m = TestRequest{} }
|
||||
func (m *TestRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*TestRequest) ProtoMessage() {}
|
||||
|
||||
const Default_TestRequest_RepeatCount int32 = 1
|
||||
|
||||
func (m *TestRequest) GetLower() string {
|
||||
if m != nil && m.Lower != nil {
|
||||
return *m.Lower
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TestRequest) GetRepeatCount() int32 {
|
||||
if m != nil && m.RepeatCount != nil {
|
||||
return *m.RepeatCount
|
||||
}
|
||||
return Default_TestRequest_RepeatCount
|
||||
}
|
||||
|
||||
type TestResponse struct {
|
||||
Value *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TestResponse) Reset() { *m = TestResponse{} }
|
||||
func (m *TestResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*TestResponse) ProtoMessage() {}
|
||||
|
||||
func (m *TestResponse) GetValue() string {
|
||||
if m != nil && m.Value != nil {
|
||||
return *m.Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type CacheStats struct {
|
||||
Items *int64 `protobuf:"varint,1,opt,name=items" json:"items,omitempty"`
|
||||
Bytes *int64 `protobuf:"varint,2,opt,name=bytes" json:"bytes,omitempty"`
|
||||
Gets *int64 `protobuf:"varint,3,opt,name=gets" json:"gets,omitempty"`
|
||||
Hits *int64 `protobuf:"varint,4,opt,name=hits" json:"hits,omitempty"`
|
||||
Evicts *int64 `protobuf:"varint,5,opt,name=evicts" json:"evicts,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CacheStats) Reset() { *m = CacheStats{} }
|
||||
func (m *CacheStats) String() string { return proto.CompactTextString(m) }
|
||||
func (*CacheStats) ProtoMessage() {}
|
||||
|
||||
func (m *CacheStats) GetItems() int64 {
|
||||
if m != nil && m.Items != nil {
|
||||
return *m.Items
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CacheStats) GetBytes() int64 {
|
||||
if m != nil && m.Bytes != nil {
|
||||
return *m.Bytes
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CacheStats) GetGets() int64 {
|
||||
if m != nil && m.Gets != nil {
|
||||
return *m.Gets
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CacheStats) GetHits() int64 {
|
||||
if m != nil && m.Hits != nil {
|
||||
return *m.Hits
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CacheStats) GetEvicts() int64 {
|
||||
if m != nil && m.Evicts != nil {
|
||||
return *m.Evicts
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type StatsResponse struct {
|
||||
Gets *int64 `protobuf:"varint,1,opt,name=gets" json:"gets,omitempty"`
|
||||
CacheHits *int64 `protobuf:"varint,12,opt,name=cache_hits" json:"cache_hits,omitempty"`
|
||||
Fills *int64 `protobuf:"varint,2,opt,name=fills" json:"fills,omitempty"`
|
||||
TotalAlloc *uint64 `protobuf:"varint,3,opt,name=total_alloc" json:"total_alloc,omitempty"`
|
||||
MainCache *CacheStats `protobuf:"bytes,4,opt,name=main_cache" json:"main_cache,omitempty"`
|
||||
HotCache *CacheStats `protobuf:"bytes,5,opt,name=hot_cache" json:"hot_cache,omitempty"`
|
||||
ServerIn *int64 `protobuf:"varint,6,opt,name=server_in" json:"server_in,omitempty"`
|
||||
Loads *int64 `protobuf:"varint,8,opt,name=loads" json:"loads,omitempty"`
|
||||
PeerLoads *int64 `protobuf:"varint,9,opt,name=peer_loads" json:"peer_loads,omitempty"`
|
||||
PeerErrors *int64 `protobuf:"varint,10,opt,name=peer_errors" json:"peer_errors,omitempty"`
|
||||
LocalLoads *int64 `protobuf:"varint,11,opt,name=local_loads" json:"local_loads,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *StatsResponse) Reset() { *m = StatsResponse{} }
|
||||
func (m *StatsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatsResponse) ProtoMessage() {}
|
||||
|
||||
func (m *StatsResponse) GetGets() int64 {
|
||||
if m != nil && m.Gets != nil {
|
||||
return *m.Gets
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetCacheHits() int64 {
|
||||
if m != nil && m.CacheHits != nil {
|
||||
return *m.CacheHits
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetFills() int64 {
|
||||
if m != nil && m.Fills != nil {
|
||||
return *m.Fills
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetTotalAlloc() uint64 {
|
||||
if m != nil && m.TotalAlloc != nil {
|
||||
return *m.TotalAlloc
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetMainCache() *CacheStats {
|
||||
if m != nil {
|
||||
return m.MainCache
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetHotCache() *CacheStats {
|
||||
if m != nil {
|
||||
return m.HotCache
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetServerIn() int64 {
|
||||
if m != nil && m.ServerIn != nil {
|
||||
return *m.ServerIn
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetLoads() int64 {
|
||||
if m != nil && m.Loads != nil {
|
||||
return *m.Loads
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetPeerLoads() int64 {
|
||||
if m != nil && m.PeerLoads != nil {
|
||||
return *m.PeerLoads
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetPeerErrors() int64 {
|
||||
if m != nil && m.PeerErrors != nil {
|
||||
return *m.PeerErrors
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetLocalLoads() int64 {
|
||||
if m != nil && m.LocalLoads != nil {
|
||||
return *m.LocalLoads
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Empty struct {
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Empty) Reset() { *m = Empty{} }
|
||||
func (m *Empty) String() string { return proto.CompactTextString(m) }
|
||||
func (*Empty) ProtoMessage() {}
|
||||
|
||||
func init() {
|
||||
}
|
63
vendor/github.com/golang/groupcache/testpb/test.proto
generated
vendored
63
vendor/github.com/golang/groupcache/testpb/test.proto
generated
vendored
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package testpb;
|
||||
|
||||
message TestMessage {
|
||||
optional string name = 1;
|
||||
optional string city = 2;
|
||||
}
|
||||
|
||||
message TestRequest {
|
||||
required string lower = 1; // to be returned upper case
|
||||
optional int32 repeat_count = 2 [default = 1]; // .. this many times
|
||||
}
|
||||
|
||||
message TestResponse {
|
||||
optional string value = 1;
|
||||
}
|
||||
|
||||
message CacheStats {
|
||||
optional int64 items = 1;
|
||||
optional int64 bytes = 2;
|
||||
optional int64 gets = 3;
|
||||
optional int64 hits = 4;
|
||||
optional int64 evicts = 5;
|
||||
}
|
||||
|
||||
message StatsResponse {
|
||||
optional int64 gets = 1;
|
||||
optional int64 cache_hits = 12;
|
||||
optional int64 fills = 2;
|
||||
optional uint64 total_alloc = 3;
|
||||
optional CacheStats main_cache = 4;
|
||||
optional CacheStats hot_cache = 5;
|
||||
optional int64 server_in = 6;
|
||||
optional int64 loads = 8;
|
||||
optional int64 peer_loads = 9;
|
||||
optional int64 peer_errors = 10;
|
||||
optional int64 local_loads = 11;
|
||||
}
|
||||
|
||||
message Empty {}
|
||||
|
||||
service GroupCacheTest {
|
||||
rpc InitPeers(Empty) returns (Empty) {};
|
||||
rpc Get(TestRequest) returns (TestResponse) {};
|
||||
rpc GetStats(Empty) returns (StatsResponse) {};
|
||||
}
|
17
vendor/github.com/golang/mock/.gitignore
generated
vendored
17
vendor/github.com/golang/mock/.gitignore
generated
vendored
@@ -1,17 +0,0 @@
|
||||
# Object files and binaries from go.
|
||||
*.[568]
|
||||
|
||||
# Library files.
|
||||
*.a
|
||||
|
||||
# Any file prefixed by an underscore.
|
||||
*/_*
|
||||
|
||||
# Vim temporary files.
|
||||
.*.swp
|
||||
|
||||
# The mockgen binary.
|
||||
mockgen/mockgen
|
||||
|
||||
# A binary produced by gotest.
|
||||
#gomock/[568]\.out
|
14
vendor/github.com/golang/mock/.travis.yml
generated
vendored
14
vendor/github.com/golang/mock/.travis.yml
generated
vendored
@@ -1,14 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
|
||||
script:
|
||||
- go build ./...
|
||||
- go install github.com/golang/mock/mockgen
|
||||
- ./ci/check_go_fmt.sh
|
||||
- ./ci/check_go_generate.sh
|
||||
- go test -v ./...
|
94
vendor/github.com/golang/mock/README.md
generated
vendored
94
vendor/github.com/golang/mock/README.md
generated
vendored
@@ -1,94 +0,0 @@
|
||||
gomock [](https://travis-ci.org/golang/mock)
|
||||
======
|
||||
|
||||
GoMock is a mocking framework for the [Go programming language][golang]. It
|
||||
integrates well with Go's built-in `testing` package, but can be used in other
|
||||
contexts too.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Once you have [installed Go][golang-install], run these commands
|
||||
to install the `gomock` package and the `mockgen` tool:
|
||||
|
||||
go get github.com/golang/mock/gomock
|
||||
go get github.com/golang/mock/mockgen
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
After installing, you can use `go doc` to get documentation:
|
||||
|
||||
go doc github.com/golang/mock/gomock
|
||||
|
||||
Alternatively, there is an online reference for the package hosted on GoPkgDoc
|
||||
[here][gomock-ref].
|
||||
|
||||
|
||||
Running mockgen
|
||||
---------------
|
||||
|
||||
`mockgen` has two modes of operation: source and reflect.
|
||||
Source mode generates mock interfaces from a source file.
|
||||
It is enabled by using the -source flag. Other flags that
|
||||
may be useful in this mode are -imports and -aux_files.
|
||||
|
||||
Example:
|
||||
|
||||
mockgen -source=foo.go [other options]
|
||||
|
||||
Reflect mode generates mock interfaces by building a program
|
||||
that uses reflection to understand interfaces. It is enabled
|
||||
by passing two non-flag arguments: an import path, and a
|
||||
comma-separated list of symbols.
|
||||
|
||||
Example:
|
||||
|
||||
mockgen database/sql/driver Conn,Driver
|
||||
|
||||
The `mockgen` command is used to generate source code for a mock
|
||||
class given a Go source file containing interfaces to be mocked.
|
||||
It supports the following flags:
|
||||
|
||||
* `-source`: A file containing interfaces to be mocked.
|
||||
|
||||
* `-destination`: A file to which to write the resulting source code. If you
|
||||
don't set this, the code is printed to standard output.
|
||||
|
||||
* `-package`: The package to use for the resulting mock class
|
||||
source code. If you don't set this, the package name is `mock_` concatenated
|
||||
with the package of the input file.
|
||||
|
||||
* `-imports`: A list of explicit imports that should be used in the resulting
|
||||
source code, specified as a comma-separated list of elements of the form
|
||||
`foo=bar/baz`, where `bar/baz` is the package being imported and `foo` is
|
||||
the identifier to use for the package in the generated source code.
|
||||
|
||||
* `-aux_files`: A list of additional files that should be consulted to
|
||||
resolve e.g. embedded interfaces defined in a different file. This is
|
||||
specified as a comma-separated list of elements of the form
|
||||
`foo=bar/baz.go`, where `bar/baz.go` is the source file and `foo` is the
|
||||
package name of that file used by the -source file.
|
||||
|
||||
* `-build_flags`: (reflect mode only) Flags passed verbatim to `go build`.
|
||||
|
||||
* `-mock_names`: A list of custom names for generated mocks. This is specified
|
||||
as a comma-separated list of elements of the form
|
||||
`Repository=MockSensorRepository,Endpoint=MockSensorEndpoint`, where
|
||||
`Repository` is the interface name and `MockSensorRepository` is the desired
|
||||
mock name (mock factory method and mock recorder will be named after the mock).
|
||||
If one of the interfaces has no custom name specified, then default naming
|
||||
convention will be used.
|
||||
|
||||
For an example of the use of `mockgen`, see the `sample/` directory. In simple
|
||||
cases, you will need only the `-source` flag.
|
||||
|
||||
|
||||
TODO: Brief overview of how to create mock objects and set up expectations, and
|
||||
an example.
|
||||
|
||||
[golang]: http://golang.org/
|
||||
[golang-install]: http://golang.org/doc/install.html#releases
|
||||
[gomock-ref]: http://godoc.org/github.com/golang/mock/gomock
|
12
vendor/github.com/golang/mock/ci/check_go_fmt.sh
generated
vendored
12
vendor/github.com/golang/mock/ci/check_go_fmt.sh
generated
vendored
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script is used by the CI to check if the code is gofmt formatted.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GOFMT_DIFF=$(IFS=$'\n'; gofmt -d $( find . -type f -name '*.go' ) )
|
||||
if [[ -n "${GOFMT_DIFF}" ]]; then
|
||||
echo "${GOFMT_DIFF}"
|
||||
echo
|
||||
echo "The go source files aren't gofmt formatted."
|
||||
exit 1
|
||||
fi
|
25
vendor/github.com/golang/mock/ci/check_go_generate.sh
generated
vendored
25
vendor/github.com/golang/mock/ci/check_go_generate.sh
generated
vendored
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script is used by the CI to check if 'go generate ./...' is up to date.
|
||||
#
|
||||
# Note: If the generated files aren't up to date then this script updates
|
||||
# them despite printing an error message so running it the second time
|
||||
# might not print any errors. This isn't very useful locally during development
|
||||
# but it works well with the CI that downloads a fresh version of the repo
|
||||
# each time before executing this script.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TEMP_DIR=$( mktemp -d )
|
||||
function cleanup() {
|
||||
rm -rf "${TEMP_DIR}"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
cp -r . "${TEMP_DIR}/"
|
||||
go generate ./...
|
||||
if ! diff -r . "${TEMP_DIR}"; then
|
||||
echo
|
||||
echo "The generated files aren't up to date."
|
||||
echo "Update them with the 'go generate ./...' command."
|
||||
exit 1
|
||||
fi
|
51
vendor/github.com/golang/mock/gomock/call_test.go
generated
vendored
51
vendor/github.com/golang/mock/gomock/call_test.go
generated
vendored
@@ -1,51 +0,0 @@
|
||||
package gomock
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type mockTestReporter struct {
|
||||
errorCalls int
|
||||
fatalCalls int
|
||||
}
|
||||
|
||||
func (o *mockTestReporter) Errorf(format string, args ...interface{}) {
|
||||
o.errorCalls++
|
||||
}
|
||||
|
||||
func (o *mockTestReporter) Fatalf(format string, args ...interface{}) {
|
||||
o.fatalCalls++
|
||||
}
|
||||
|
||||
func (o *mockTestReporter) Helper() {}
|
||||
|
||||
func TestCall_After(t *testing.T) {
|
||||
t.Run("SelfPrereqCallsFatalf", func(t *testing.T) {
|
||||
tr1 := &mockTestReporter{}
|
||||
|
||||
c := &Call{t: tr1}
|
||||
c.After(c)
|
||||
|
||||
if tr1.fatalCalls != 1 {
|
||||
t.Errorf("number of fatal calls == %v, want 1", tr1.fatalCalls)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("LoopInCallOrderCallsFatalf", func(t *testing.T) {
|
||||
tr1 := &mockTestReporter{}
|
||||
tr2 := &mockTestReporter{}
|
||||
|
||||
c1 := &Call{t: tr1}
|
||||
c2 := &Call{t: tr2}
|
||||
c1.After(c2)
|
||||
c2.After(c1)
|
||||
|
||||
if tr1.errorCalls != 0 || tr1.fatalCalls != 0 {
|
||||
t.Error("unexpected errors")
|
||||
}
|
||||
|
||||
if tr2.fatalCalls != 1 {
|
||||
t.Errorf("number of fatal calls == %v, want 1", tr2.fatalCalls)
|
||||
}
|
||||
})
|
||||
}
|
76
vendor/github.com/golang/mock/gomock/callset_test.go
generated
vendored
76
vendor/github.com/golang/mock/gomock/callset_test.go
generated
vendored
@@ -1,76 +0,0 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gomock
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type receiverType struct{}
|
||||
|
||||
func (receiverType) Func() {}
|
||||
|
||||
func TestCallSetAdd(t *testing.T) {
|
||||
method := "TestMethod"
|
||||
var receiver interface{} = "TestReceiver"
|
||||
cs := newCallSet()
|
||||
|
||||
numCalls := 10
|
||||
for i := 0; i < numCalls; i++ {
|
||||
cs.Add(newCall(t, receiver, method, reflect.TypeOf(receiverType{}.Func)))
|
||||
}
|
||||
|
||||
call, err := cs.FindMatch(receiver, method, []interface{}{})
|
||||
if err != nil {
|
||||
t.Fatalf("FindMatch: %v", err)
|
||||
}
|
||||
if call == nil {
|
||||
t.Fatalf("FindMatch: Got nil, want non-nil *Call")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallSetRemove(t *testing.T) {
|
||||
method := "TestMethod"
|
||||
var receiver interface{} = "TestReceiver"
|
||||
|
||||
cs := newCallSet()
|
||||
ourCalls := []*Call{}
|
||||
|
||||
numCalls := 10
|
||||
for i := 0; i < numCalls; i++ {
|
||||
// NOTE: abuse the `numCalls` value to convey initial ordering of mocked calls
|
||||
generatedCall := &Call{receiver: receiver, method: method, numCalls: i}
|
||||
cs.Add(generatedCall)
|
||||
ourCalls = append(ourCalls, generatedCall)
|
||||
}
|
||||
|
||||
// validateOrder validates that the calls in the array are ordered as they were added
|
||||
validateOrder := func(calls []*Call) {
|
||||
// lastNum tracks the last `numCalls` (call order) value seen
|
||||
lastNum := -1
|
||||
for _, c := range calls {
|
||||
if lastNum >= c.numCalls {
|
||||
t.Errorf("found call %d after call %d", c.numCalls, lastNum)
|
||||
}
|
||||
lastNum = c.numCalls
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range ourCalls {
|
||||
validateOrder(cs.expected[callSetKey{receiver, method}])
|
||||
cs.Remove(c)
|
||||
}
|
||||
}
|
712
vendor/github.com/golang/mock/gomock/controller_test.go
generated
vendored
712
vendor/github.com/golang/mock/gomock/controller_test.go
generated
vendored
@@ -1,712 +0,0 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gomock_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
type ErrorReporter struct {
|
||||
t *testing.T
|
||||
log []string
|
||||
failed bool
|
||||
fatalToken struct{}
|
||||
}
|
||||
|
||||
func NewErrorReporter(t *testing.T) *ErrorReporter {
|
||||
return &ErrorReporter{t: t}
|
||||
}
|
||||
|
||||
func (e *ErrorReporter) reportLog() {
|
||||
for _, entry := range e.log {
|
||||
e.t.Log(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ErrorReporter) assertPass(msg string) {
|
||||
if e.failed {
|
||||
e.t.Errorf("Expected pass, but got failure(s): %s", msg)
|
||||
e.reportLog()
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ErrorReporter) assertFail(msg string) {
|
||||
if !e.failed {
|
||||
e.t.Errorf("Expected failure, but got pass: %s", msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Use to check that code triggers a fatal test failure.
|
||||
func (e *ErrorReporter) assertFatal(fn func(), expectedErrMsgs ...string) {
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
var actual string
|
||||
if e.failed {
|
||||
actual = "non-fatal failure"
|
||||
} else {
|
||||
actual = "pass"
|
||||
}
|
||||
e.t.Error("Expected fatal failure, but got a", actual)
|
||||
} else if token, ok := err.(*struct{}); ok && token == &e.fatalToken {
|
||||
// This is okay - the panic is from Fatalf().
|
||||
if expectedErrMsgs != nil {
|
||||
// assert that the actual error message
|
||||
// contains expectedErrMsgs
|
||||
|
||||
// check the last actualErrMsg, because the previous messages come from previous errors
|
||||
actualErrMsg := e.log[len(e.log)-1]
|
||||
for _, expectedErrMsg := range expectedErrMsgs {
|
||||
if !strings.Contains(actualErrMsg, expectedErrMsg) {
|
||||
e.t.Errorf("Error message:\ngot: %q\nwant to contain: %q\n", actualErrMsg, expectedErrMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
} else {
|
||||
// Some other panic.
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
fn()
|
||||
}
|
||||
|
||||
// recoverUnexpectedFatal can be used as a deferred call in test cases to
|
||||
// recover from and display a call to ErrorReporter.Fatalf().
|
||||
func (e *ErrorReporter) recoverUnexpectedFatal() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
// No panic.
|
||||
} else if token, ok := err.(*struct{}); ok && token == &e.fatalToken {
|
||||
// Unexpected fatal error happened.
|
||||
e.t.Error("Got unexpected fatal error(s). All errors up to this point:")
|
||||
e.reportLog()
|
||||
return
|
||||
} else {
|
||||
// Some other panic.
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ErrorReporter) Logf(format string, args ...interface{}) {
|
||||
e.log = append(e.log, fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func (e *ErrorReporter) Errorf(format string, args ...interface{}) {
|
||||
e.Logf(format, args...)
|
||||
e.failed = true
|
||||
}
|
||||
|
||||
func (e *ErrorReporter) Fatalf(format string, args ...interface{}) {
|
||||
e.Logf(format, args...)
|
||||
e.failed = true
|
||||
panic(&e.fatalToken)
|
||||
}
|
||||
|
||||
// A type purely for use as a receiver in testing the Controller.
|
||||
type Subject struct{}
|
||||
|
||||
func (s *Subject) FooMethod(arg string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (s *Subject) BarMethod(arg string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (s *Subject) VariadicMethod(arg int, vararg ...string) {}
|
||||
|
||||
// A type purely for ActOnTestStructMethod
|
||||
type TestStruct struct {
|
||||
Number int
|
||||
Message string
|
||||
}
|
||||
|
||||
func (s *Subject) ActOnTestStructMethod(arg TestStruct, arg1 int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (s *Subject) SetArgMethod(sliceArg []byte, ptrArg *int) {}
|
||||
|
||||
func assertEqual(t *testing.T, expected interface{}, actual interface{}) {
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Errorf("Expected %+v, but got %+v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func createFixtures(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller) {
|
||||
// reporter acts as a testing.T-like object that we pass to the
|
||||
// Controller. We use it to test that the mock considered tests
|
||||
// successful or failed.
|
||||
reporter = NewErrorReporter(t)
|
||||
ctrl = gomock.NewController(reporter)
|
||||
return
|
||||
}
|
||||
|
||||
func TestNoCalls(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
ctrl.Finish()
|
||||
reporter.assertPass("No calls expected or made.")
|
||||
}
|
||||
|
||||
func TestNoRecordedCallsForAReceiver(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "NotRecordedMethod", "argument")
|
||||
}, "Unexpected call to", "there are no expected calls of the method \"NotRecordedMethod\" for that receiver")
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestNoRecordedMatchingMethodNameForAReceiver(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument")
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "NotRecordedMethod", "argument")
|
||||
}, "Unexpected call to", "there are no expected calls of the method \"NotRecordedMethod\" for that receiver")
|
||||
reporter.assertFatal(func() {
|
||||
// The expected call wasn't made.
|
||||
ctrl.Finish()
|
||||
})
|
||||
}
|
||||
|
||||
// This tests that a call with an arguments of some primitive type matches a recorded call.
|
||||
func TestExpectedMethodCall(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument")
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Finish()
|
||||
|
||||
reporter.assertPass("Expected method call made.")
|
||||
}
|
||||
|
||||
func TestUnexpectedMethodCall(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
})
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestRepeatedCall(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").Times(3)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
reporter.assertPass("After expected repeated method calls.")
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
})
|
||||
ctrl.Finish()
|
||||
reporter.assertFail("After calling one too many times.")
|
||||
}
|
||||
|
||||
func TestUnexpectedArgCount(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
defer reporter.recoverUnexpectedFatal()
|
||||
subject := new(Subject)
|
||||
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument")
|
||||
reporter.assertFatal(func() {
|
||||
// This call is made with the wrong number of arguments...
|
||||
ctrl.Call(subject, "FooMethod", "argument", "extra_argument")
|
||||
}, "Unexpected call to", "wrong number of arguments", "Got: 2, want: 1")
|
||||
reporter.assertFatal(func() {
|
||||
// ... so is this.
|
||||
ctrl.Call(subject, "FooMethod")
|
||||
}, "Unexpected call to", "wrong number of arguments", "Got: 0, want: 1")
|
||||
reporter.assertFatal(func() {
|
||||
// The expected call wasn't made.
|
||||
ctrl.Finish()
|
||||
})
|
||||
}
|
||||
|
||||
// This tests that a call with complex arguments (a struct and some primitive type) matches a recorded call.
|
||||
func TestExpectedMethodCall_CustomStruct(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
expectedArg0 := TestStruct{Number: 123, Message: "hello"}
|
||||
ctrl.RecordCall(subject, "ActOnTestStructMethod", expectedArg0, 15)
|
||||
ctrl.Call(subject, "ActOnTestStructMethod", expectedArg0, 15)
|
||||
|
||||
reporter.assertPass("Expected method call made.")
|
||||
}
|
||||
|
||||
func TestUnexpectedArgValue_FirstArg(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
defer reporter.recoverUnexpectedFatal()
|
||||
subject := new(Subject)
|
||||
|
||||
expectedArg0 := TestStruct{Number: 123, Message: "hello"}
|
||||
ctrl.RecordCall(subject, "ActOnTestStructMethod", expectedArg0, 15)
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
// the method argument (of TestStruct type) has 1 unexpected value (for the Message field)
|
||||
ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 123, Message: "no message"}, 15)
|
||||
}, "Unexpected call to", "doesn't match the argument at index 0",
|
||||
"Got: {123 no message}\nWant: is equal to {123 hello}")
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
// the method argument (of TestStruct type) has 2 unexpected values (for both fields)
|
||||
ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 11, Message: "no message"}, 15)
|
||||
}, "Unexpected call to", "doesn't match the argument at index 0",
|
||||
"Got: {11 no message}\nWant: is equal to {123 hello}")
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
// The expected call wasn't made.
|
||||
ctrl.Finish()
|
||||
})
|
||||
}
|
||||
|
||||
func TestUnexpectedArgValue_SecondtArg(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
defer reporter.recoverUnexpectedFatal()
|
||||
subject := new(Subject)
|
||||
|
||||
expectedArg0 := TestStruct{Number: 123, Message: "hello"}
|
||||
ctrl.RecordCall(subject, "ActOnTestStructMethod", expectedArg0, 15)
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 123, Message: "hello"}, 3)
|
||||
}, "Unexpected call to", "doesn't match the argument at index 1",
|
||||
"Got: 3\nWant: is equal to 15")
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
// The expected call wasn't made.
|
||||
ctrl.Finish()
|
||||
})
|
||||
}
|
||||
|
||||
func TestAnyTimes(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").AnyTimes()
|
||||
for i := 0; i < 100; i++ {
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
}
|
||||
reporter.assertPass("After 100 method calls.")
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestMinTimes1(t *testing.T) {
|
||||
// It fails if there are no calls
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1)
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Finish()
|
||||
})
|
||||
|
||||
// It succeeds if there is one call
|
||||
reporter, ctrl = createFixtures(t)
|
||||
subject = new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Finish()
|
||||
|
||||
// It succeeds if there are many calls
|
||||
reporter, ctrl = createFixtures(t)
|
||||
subject = new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1)
|
||||
for i := 0; i < 100; i++ {
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
}
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestMaxTimes1(t *testing.T) {
|
||||
// It succeeds if there are no calls
|
||||
_, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1)
|
||||
ctrl.Finish()
|
||||
|
||||
// It succeeds if there is one call
|
||||
_, ctrl = createFixtures(t)
|
||||
subject = new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Finish()
|
||||
|
||||
//It fails if there are more
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject = new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
})
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestMinMaxTimes(t *testing.T) {
|
||||
// It fails if there are less calls than specified
|
||||
reporter, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Finish()
|
||||
})
|
||||
|
||||
// It fails if there are more calls than specified
|
||||
reporter, ctrl = createFixtures(t)
|
||||
subject = new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
})
|
||||
|
||||
// It succeeds if there is just the right number of calls
|
||||
reporter, ctrl = createFixtures(t)
|
||||
subject = new(Subject)
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(2).MinTimes(2)
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestDo(t *testing.T) {
|
||||
_, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
doCalled := false
|
||||
var argument string
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").Do(
|
||||
func(arg string) {
|
||||
doCalled = true
|
||||
argument = arg
|
||||
})
|
||||
if doCalled {
|
||||
t.Error("Do() callback called too early.")
|
||||
}
|
||||
|
||||
ctrl.Call(subject, "FooMethod", "argument")
|
||||
|
||||
if !doCalled {
|
||||
t.Error("Do() callback not called.")
|
||||
}
|
||||
if "argument" != argument {
|
||||
t.Error("Do callback received wrong argument.")
|
||||
}
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestDoAndReturn(t *testing.T) {
|
||||
_, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
doCalled := false
|
||||
var argument string
|
||||
ctrl.RecordCall(subject, "FooMethod", "argument").DoAndReturn(
|
||||
func(arg string) int {
|
||||
doCalled = true
|
||||
argument = arg
|
||||
return 5
|
||||
})
|
||||
if doCalled {
|
||||
t.Error("Do() callback called too early.")
|
||||
}
|
||||
|
||||
rets := ctrl.Call(subject, "FooMethod", "argument")
|
||||
|
||||
if !doCalled {
|
||||
t.Error("Do() callback not called.")
|
||||
}
|
||||
if "argument" != argument {
|
||||
t.Error("Do callback received wrong argument.")
|
||||
}
|
||||
if len(rets) != 1 {
|
||||
t.Fatalf("Return values from Call: got %d, want 1", len(rets))
|
||||
}
|
||||
if ret, ok := rets[0].(int); !ok {
|
||||
t.Fatalf("Return value is not an int")
|
||||
} else if ret != 5 {
|
||||
t.Errorf("DoAndReturn return value: got %d, want 5", ret)
|
||||
}
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestSetArgSlice(t *testing.T) {
|
||||
_, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
var in = []byte{4, 5, 6}
|
||||
var set = []byte{1, 2, 3}
|
||||
ctrl.RecordCall(subject, "SetArgMethod", in, nil).SetArg(0, set)
|
||||
ctrl.Call(subject, "SetArgMethod", in, nil)
|
||||
|
||||
if !reflect.DeepEqual(in, set) {
|
||||
t.Error("Expected SetArg() to modify input slice argument")
|
||||
}
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestSetArgPtr(t *testing.T) {
|
||||
_, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
var in int = 43
|
||||
const set = 42
|
||||
ctrl.RecordCall(subject, "SetArgMethod", nil, &in).SetArg(1, set)
|
||||
ctrl.Call(subject, "SetArgMethod", nil, &in)
|
||||
|
||||
if in != set {
|
||||
t.Error("Expected SetArg() to modify value pointed to by argument")
|
||||
}
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestReturn(t *testing.T) {
|
||||
_, ctrl := createFixtures(t)
|
||||
subject := new(Subject)
|
||||
|
||||
// Unspecified return should produce "zero" result.
|
||||
ctrl.RecordCall(subject, "FooMethod", "zero")
|
||||
ctrl.RecordCall(subject, "FooMethod", "five").Return(5)
|
||||
|
||||
assertEqual(
|
||||
t,
|
||||
[]interface{}{0},
|
||||
ctrl.Call(subject, "FooMethod", "zero"))
|
||||
|
||||
assertEqual(
|
||||
t,
|
||||
[]interface{}{5},
|
||||
ctrl.Call(subject, "FooMethod", "five"))
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestUnorderedCalls(t *testing.T) {
|
||||
reporter, ctrl := createFixtures(t)
|
||||
defer reporter.recoverUnexpectedFatal()
|
||||
subjectTwo := new(Subject)
|
||||
subjectOne := new(Subject)
|
||||
|
||||
ctrl.RecordCall(subjectOne, "FooMethod", "1")
|
||||
ctrl.RecordCall(subjectOne, "BarMethod", "2")
|
||||
ctrl.RecordCall(subjectTwo, "FooMethod", "3")
|
||||
ctrl.RecordCall(subjectTwo, "BarMethod", "4")
|
||||
|
||||
// Make the calls in a different order, which should be fine.
|
||||
ctrl.Call(subjectOne, "BarMethod", "2")
|
||||
ctrl.Call(subjectTwo, "FooMethod", "3")
|
||||
ctrl.Call(subjectTwo, "BarMethod", "4")
|
||||
ctrl.Call(subjectOne, "FooMethod", "1")
|
||||
|
||||
reporter.assertPass("After making all calls in different order")
|
||||
|
||||
ctrl.Finish()
|
||||
|
||||
reporter.assertPass("After finish")
|
||||
}
|
||||
|
||||
func commonTestOrderedCalls(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller, subjectOne, subjectTwo *Subject) {
|
||||
reporter, ctrl = createFixtures(t)
|
||||
|
||||
subjectOne = new(Subject)
|
||||
subjectTwo = new(Subject)
|
||||
|
||||
gomock.InOrder(
|
||||
ctrl.RecordCall(subjectOne, "FooMethod", "1").AnyTimes(),
|
||||
ctrl.RecordCall(subjectTwo, "FooMethod", "2"),
|
||||
ctrl.RecordCall(subjectTwo, "BarMethod", "3"),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func TestOrderedCallsCorrect(t *testing.T) {
|
||||
reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t)
|
||||
|
||||
ctrl.Call(subjectOne, "FooMethod", "1")
|
||||
ctrl.Call(subjectTwo, "FooMethod", "2")
|
||||
ctrl.Call(subjectTwo, "BarMethod", "3")
|
||||
|
||||
ctrl.Finish()
|
||||
|
||||
reporter.assertPass("After finish")
|
||||
}
|
||||
|
||||
func TestOrderedCallsInCorrect(t *testing.T) {
|
||||
reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t)
|
||||
|
||||
ctrl.Call(subjectOne, "FooMethod", "1")
|
||||
reporter.assertFatal(func() {
|
||||
// FooMethod(2) should be called before BarMethod(3)
|
||||
ctrl.Call(subjectTwo, "BarMethod", "3")
|
||||
}, "Unexpected call to", "Subject.BarMethod([3])", "doesn't have a prerequisite call satisfied")
|
||||
}
|
||||
|
||||
// Test that calls that are prerequisites to other calls but have maxCalls >
|
||||
// minCalls are removed from the expected call set.
|
||||
func TestOrderedCallsWithPreReqMaxUnbounded(t *testing.T) {
|
||||
reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t)
|
||||
|
||||
// Initially we should be able to call FooMethod("1") as many times as we
|
||||
// want.
|
||||
ctrl.Call(subjectOne, "FooMethod", "1")
|
||||
ctrl.Call(subjectOne, "FooMethod", "1")
|
||||
|
||||
// But calling something that has it as a prerequite should remove it from
|
||||
// the expected call set. This allows tests to ensure that FooMethod("1") is
|
||||
// *not* called after FooMethod("2").
|
||||
ctrl.Call(subjectTwo, "FooMethod", "2")
|
||||
|
||||
// Therefore this call should fail:
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.Call(subjectOne, "FooMethod", "1")
|
||||
})
|
||||
}
|
||||
|
||||
func TestCallAfterLoopPanic(t *testing.T) {
|
||||
_, ctrl := createFixtures(t)
|
||||
|
||||
subject := new(Subject)
|
||||
|
||||
firstCall := ctrl.RecordCall(subject, "FooMethod", "1")
|
||||
secondCall := ctrl.RecordCall(subject, "FooMethod", "2")
|
||||
thirdCall := ctrl.RecordCall(subject, "FooMethod", "3")
|
||||
|
||||
gomock.InOrder(firstCall, secondCall, thirdCall)
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Error("Call.After creation of dependency loop did not panic.")
|
||||
}
|
||||
}()
|
||||
|
||||
// This should panic due to dependency loop.
|
||||
firstCall.After(thirdCall)
|
||||
}
|
||||
|
||||
func TestPanicOverridesExpectationChecks(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
reporter := NewErrorReporter(t)
|
||||
|
||||
reporter.assertFatal(func() {
|
||||
ctrl.RecordCall(new(Subject), "FooMethod", "1")
|
||||
defer ctrl.Finish()
|
||||
reporter.Fatalf("Intentional panic")
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetArgWithBadType(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
s := new(Subject)
|
||||
// This should catch a type error:
|
||||
rep.assertFatal(func() {
|
||||
ctrl.RecordCall(s, "FooMethod", "1").SetArg(0, "blah")
|
||||
})
|
||||
ctrl.Call(s, "FooMethod", "1")
|
||||
}
|
||||
|
||||
func TestTimes0(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
s := new(Subject)
|
||||
ctrl.RecordCall(s, "FooMethod", "arg").Times(0)
|
||||
rep.assertFatal(func() {
|
||||
ctrl.Call(s, "FooMethod", "arg")
|
||||
})
|
||||
}
|
||||
|
||||
func TestVariadicMatching(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
defer rep.recoverUnexpectedFatal()
|
||||
|
||||
s := new(Subject)
|
||||
ctrl.RecordCall(s, "VariadicMethod", 0, "1", "2")
|
||||
ctrl.Call(s, "VariadicMethod", 0, "1", "2")
|
||||
ctrl.Finish()
|
||||
rep.assertPass("variadic matching works")
|
||||
}
|
||||
|
||||
func TestVariadicNoMatch(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
defer rep.recoverUnexpectedFatal()
|
||||
|
||||
s := new(Subject)
|
||||
ctrl.RecordCall(s, "VariadicMethod", 0)
|
||||
rep.assertFatal(func() {
|
||||
ctrl.Call(s, "VariadicMethod", 1)
|
||||
}, "Expected call at", "doesn't match the argument at index 0",
|
||||
"Got: 1\nWant: is equal to 0")
|
||||
ctrl.Call(s, "VariadicMethod", 0)
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestVariadicMatchingWithSlice(t *testing.T) {
|
||||
testCases := [][]string{
|
||||
{"1"},
|
||||
{"1", "2"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%d arguments", len(tc)), func(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
defer rep.recoverUnexpectedFatal()
|
||||
|
||||
s := new(Subject)
|
||||
ctrl.RecordCall(s, "VariadicMethod", 1, tc)
|
||||
args := make([]interface{}, len(tc)+1)
|
||||
args[0] = 1
|
||||
for i, arg := range tc {
|
||||
args[i+1] = arg
|
||||
}
|
||||
ctrl.Call(s, "VariadicMethod", args...)
|
||||
ctrl.Finish()
|
||||
rep.assertPass("slices can be used as matchers for variadic arguments")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDuplicateFinishCallFails(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
|
||||
ctrl.Finish()
|
||||
rep.assertPass("the first Finish call should succeed")
|
||||
|
||||
rep.assertFatal(ctrl.Finish, "Controller.Finish was called more than once. It has to be called exactly once.")
|
||||
}
|
70
vendor/github.com/golang/mock/gomock/matchers_test.go
generated
vendored
70
vendor/github.com/golang/mock/gomock/matchers_test.go
generated
vendored
@@ -1,70 +0,0 @@
|
||||
// Copyright 2010 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gomock_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
mock_matcher "github.com/golang/mock/gomock/mock_matcher"
|
||||
)
|
||||
|
||||
func TestMatchers(t *testing.T) {
|
||||
type e interface{}
|
||||
type testCase struct {
|
||||
matcher gomock.Matcher
|
||||
yes, no []e
|
||||
}
|
||||
tests := []testCase{
|
||||
testCase{gomock.Any(), []e{3, nil, "foo"}, nil},
|
||||
testCase{gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}},
|
||||
testCase{gomock.Nil(),
|
||||
[]e{nil, (error)(nil), (chan bool)(nil), (*int)(nil)},
|
||||
[]e{"", 0, make(chan bool), errors.New("err"), new(int)}},
|
||||
testCase{gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
for _, x := range test.yes {
|
||||
if !test.matcher.Matches(x) {
|
||||
t.Errorf(`test %d: "%v %s" should be true.`, i, x, test.matcher)
|
||||
}
|
||||
}
|
||||
for _, x := range test.no {
|
||||
if test.matcher.Matches(x) {
|
||||
t.Errorf(`test %d: "%v %s" should be false.`, i, x, test.matcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A more thorough test of notMatcher
|
||||
func TestNotMatcher(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockMatcher := mock_matcher.NewMockMatcher(ctrl)
|
||||
notMatcher := gomock.Not(mockMatcher)
|
||||
|
||||
mockMatcher.EXPECT().Matches(4).Return(true)
|
||||
if match := notMatcher.Matches(4); match {
|
||||
t.Errorf("notMatcher should not match 4")
|
||||
}
|
||||
|
||||
mockMatcher.EXPECT().Matches(5).Return(false)
|
||||
if match := notMatcher.Matches(5); !match {
|
||||
t.Errorf("notMatcher should match 5")
|
||||
}
|
||||
}
|
57
vendor/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go
generated
vendored
57
vendor/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go
generated
vendored
@@ -1,57 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/golang/mock/gomock (interfaces: Matcher)
|
||||
|
||||
// Package mock_gomock is a generated GoMock package.
|
||||
package mock_gomock
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockMatcher is a mock of Matcher interface
|
||||
type MockMatcher struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockMatcherMockRecorder
|
||||
}
|
||||
|
||||
// MockMatcherMockRecorder is the mock recorder for MockMatcher
|
||||
type MockMatcherMockRecorder struct {
|
||||
mock *MockMatcher
|
||||
}
|
||||
|
||||
// NewMockMatcher creates a new mock instance
|
||||
func NewMockMatcher(ctrl *gomock.Controller) *MockMatcher {
|
||||
mock := &MockMatcher{ctrl: ctrl}
|
||||
mock.recorder = &MockMatcherMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockMatcher) EXPECT() *MockMatcherMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Matches mocks base method
|
||||
func (m *MockMatcher) Matches(arg0 interface{}) bool {
|
||||
ret := m.ctrl.Call(m, "Matches", arg0)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Matches indicates an expected call of Matches
|
||||
func (mr *MockMatcherMockRecorder) Matches(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Matches", reflect.TypeOf((*MockMatcher)(nil).Matches), arg0)
|
||||
}
|
||||
|
||||
// String mocks base method
|
||||
func (m *MockMatcher) String() string {
|
||||
ret := m.ctrl.Call(m, "String")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// String indicates an expected call of String
|
||||
func (mr *MockMatcherMockRecorder) String() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "String", reflect.TypeOf((*MockMatcher)(nil).String))
|
||||
}
|
559
vendor/github.com/golang/mock/mockgen/mockgen.go
generated
vendored
559
vendor/github.com/golang/mock/mockgen/mockgen.go
generated
vendored
@@ -1,559 +0,0 @@
|
||||
// Copyright 2010 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// MockGen generates mock implementations of Go interfaces.
|
||||
package main
|
||||
|
||||
// TODO: This does not support recursive embedded interfaces.
|
||||
// TODO: This does not support embedding package-local interfaces in a separate file.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"go/format"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/golang/mock/mockgen/model"
|
||||
)
|
||||
|
||||
const (
|
||||
gomockImportPath = "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
var (
|
||||
source = flag.String("source", "", "(source mode) Input Go source file; enables source mode.")
|
||||
destination = flag.String("destination", "", "Output file; defaults to stdout.")
|
||||
mockNames = flag.String("mock_names", "", "Comma-separated interfaceName=mockName pairs of explicit mock names to use. Mock names default to 'Mock'+ interfaceName suffix.")
|
||||
packageOut = flag.String("package", "", "Package of the generated code; defaults to the package of the input with a 'mock_' prefix.")
|
||||
selfPackage = flag.String("self_package", "", "The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.")
|
||||
writePkgComment = flag.Bool("write_package_comment", true, "Writes package documentation comment (godoc) if true.")
|
||||
|
||||
debugParser = flag.Bool("debug_parser", false, "Print out parser results only.")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
var pkg *model.Package
|
||||
var err error
|
||||
if *source != "" {
|
||||
pkg, err = ParseFile(*source)
|
||||
} else {
|
||||
if flag.NArg() != 2 {
|
||||
usage()
|
||||
log.Fatal("Expected exactly two arguments")
|
||||
}
|
||||
pkg, err = Reflect(flag.Arg(0), strings.Split(flag.Arg(1), ","))
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Loading input failed: %v", err)
|
||||
}
|
||||
|
||||
if *debugParser {
|
||||
pkg.Print(os.Stdout)
|
||||
return
|
||||
}
|
||||
|
||||
dst := os.Stdout
|
||||
if len(*destination) > 0 {
|
||||
f, err := os.Create(*destination)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed opening destination file: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
dst = f
|
||||
}
|
||||
|
||||
packageName := *packageOut
|
||||
if packageName == "" {
|
||||
// pkg.Name in reflect mode is the base name of the import path,
|
||||
// which might have characters that are illegal to have in package names.
|
||||
packageName = "mock_" + sanitize(pkg.Name)
|
||||
}
|
||||
|
||||
// outputPackagePath represents the fully qualified name of the package of
|
||||
// the generated code. Its purposes are to prevent the module from importing
|
||||
// itself and to prevent qualifying type names that come from its own
|
||||
// package (i.e. if there is a type called X then we want to print "X" not
|
||||
// "package.X" since "package" is this package). This can happen if the mock
|
||||
// is output into an already existing package.
|
||||
outputPackagePath := *selfPackage
|
||||
if len(outputPackagePath) == 0 && len(*destination) > 0 {
|
||||
dst, _ := filepath.Abs(filepath.Dir(*destination))
|
||||
for _, prefix := range build.Default.SrcDirs() {
|
||||
if strings.HasPrefix(dst, prefix) {
|
||||
if rel, err := filepath.Rel(prefix, dst); err == nil {
|
||||
outputPackagePath = rel
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g := new(generator)
|
||||
if *source != "" {
|
||||
g.filename = *source
|
||||
} else {
|
||||
g.srcPackage = flag.Arg(0)
|
||||
g.srcInterfaces = flag.Arg(1)
|
||||
}
|
||||
|
||||
if *mockNames != "" {
|
||||
g.mockNames = parseMockNames(*mockNames)
|
||||
}
|
||||
if err := g.Generate(pkg, packageName, outputPackagePath); err != nil {
|
||||
log.Fatalf("Failed generating mock: %v", err)
|
||||
}
|
||||
if _, err := dst.Write(g.Output()); err != nil {
|
||||
log.Fatalf("Failed writing to destination: %v", err)
|
||||
}
|
||||
}
|
||||
func parseMockNames(names string) map[string]string {
|
||||
mocksMap := make(map[string]string)
|
||||
for _, kv := range strings.Split(names, ",") {
|
||||
parts := strings.SplitN(kv, "=", 2)
|
||||
if len(parts) != 2 || parts[1] == "" {
|
||||
log.Fatalf("bad mock names spec: %v", kv)
|
||||
}
|
||||
mocksMap[parts[0]] = parts[1]
|
||||
}
|
||||
return mocksMap
|
||||
}
|
||||
|
||||
func usage() {
|
||||
io.WriteString(os.Stderr, usageText)
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
const usageText = `mockgen has two modes of operation: source and reflect.
|
||||
|
||||
Source mode generates mock interfaces from a source file.
|
||||
It is enabled by using the -source flag. Other flags that
|
||||
may be useful in this mode are -imports and -aux_files.
|
||||
Example:
|
||||
mockgen -source=foo.go [other options]
|
||||
|
||||
Reflect mode generates mock interfaces by building a program
|
||||
that uses reflection to understand interfaces. It is enabled
|
||||
by passing two non-flag arguments: an import path, and a
|
||||
comma-separated list of symbols.
|
||||
Example:
|
||||
mockgen database/sql/driver Conn,Driver
|
||||
|
||||
`
|
||||
|
||||
type generator struct {
|
||||
buf bytes.Buffer
|
||||
indent string
|
||||
mockNames map[string]string //may be empty
|
||||
filename string // may be empty
|
||||
srcPackage, srcInterfaces string // may be empty
|
||||
|
||||
packageMap map[string]string // map from import path to package name
|
||||
}
|
||||
|
||||
func (g *generator) p(format string, args ...interface{}) {
|
||||
fmt.Fprintf(&g.buf, g.indent+format+"\n", args...)
|
||||
}
|
||||
|
||||
func (g *generator) in() {
|
||||
g.indent += "\t"
|
||||
}
|
||||
|
||||
func (g *generator) out() {
|
||||
if len(g.indent) > 0 {
|
||||
g.indent = g.indent[0 : len(g.indent)-1]
|
||||
}
|
||||
}
|
||||
|
||||
func removeDot(s string) string {
|
||||
if len(s) > 0 && s[len(s)-1] == '.' {
|
||||
return s[0 : len(s)-1]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// sanitize cleans up a string to make a suitable package name.
|
||||
func sanitize(s string) string {
|
||||
t := ""
|
||||
for _, r := range s {
|
||||
if t == "" {
|
||||
if unicode.IsLetter(r) || r == '_' {
|
||||
t += string(r)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {
|
||||
t += string(r)
|
||||
continue
|
||||
}
|
||||
}
|
||||
t += "_"
|
||||
}
|
||||
if t == "_" {
|
||||
t = "x"
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (g *generator) Generate(pkg *model.Package, pkgName string, outputPackagePath string) error {
|
||||
g.p("// Code generated by MockGen. DO NOT EDIT.")
|
||||
if g.filename != "" {
|
||||
g.p("// Source: %v", g.filename)
|
||||
} else {
|
||||
g.p("// Source: %v (interfaces: %v)", g.srcPackage, g.srcInterfaces)
|
||||
}
|
||||
g.p("")
|
||||
|
||||
// Get all required imports, and generate unique names for them all.
|
||||
im := pkg.Imports()
|
||||
im[gomockImportPath] = true
|
||||
|
||||
// Only import reflect if it's used. We only use reflect in mocked methods
|
||||
// so only import if any of the mocked interfaces have methods.
|
||||
for _, intf := range pkg.Interfaces {
|
||||
if len(intf.Methods) > 0 {
|
||||
im["reflect"] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Sort keys to make import alias generation predictable
|
||||
sorted_paths := make([]string, len(im), len(im))
|
||||
x := 0
|
||||
for pth := range im {
|
||||
sorted_paths[x] = pth
|
||||
x++
|
||||
}
|
||||
sort.Strings(sorted_paths)
|
||||
|
||||
g.packageMap = make(map[string]string, len(im))
|
||||
localNames := make(map[string]bool, len(im))
|
||||
for _, pth := range sorted_paths {
|
||||
base := sanitize(path.Base(pth))
|
||||
|
||||
// Local names for an imported package can usually be the basename of the import path.
|
||||
// A couple of situations don't permit that, such as duplicate local names
|
||||
// (e.g. importing "html/template" and "text/template"), or where the basename is
|
||||
// a keyword (e.g. "foo/case").
|
||||
// try base0, base1, ...
|
||||
pkgName := base
|
||||
i := 0
|
||||
for localNames[pkgName] || token.Lookup(pkgName).IsKeyword() {
|
||||
pkgName = base + strconv.Itoa(i)
|
||||
i++
|
||||
}
|
||||
|
||||
g.packageMap[pth] = pkgName
|
||||
localNames[pkgName] = true
|
||||
}
|
||||
|
||||
if *writePkgComment {
|
||||
g.p("// Package %v is a generated GoMock package.", pkgName)
|
||||
}
|
||||
g.p("package %v", pkgName)
|
||||
g.p("")
|
||||
g.p("import (")
|
||||
g.in()
|
||||
for path, pkg := range g.packageMap {
|
||||
if path == outputPackagePath {
|
||||
continue
|
||||
}
|
||||
g.p("%v %q", pkg, path)
|
||||
}
|
||||
for _, path := range pkg.DotImports {
|
||||
g.p(". %q", path)
|
||||
}
|
||||
g.out()
|
||||
g.p(")")
|
||||
|
||||
for _, intf := range pkg.Interfaces {
|
||||
if err := g.GenerateMockInterface(intf, outputPackagePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// The name of the mock type to use for the given interface identifier.
|
||||
func (g *generator) mockName(typeName string) string {
|
||||
if mockName, ok := g.mockNames[typeName]; ok {
|
||||
return mockName
|
||||
}
|
||||
|
||||
return "Mock" + typeName
|
||||
}
|
||||
|
||||
func (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePath string) error {
|
||||
mockType := g.mockName(intf.Name)
|
||||
|
||||
g.p("")
|
||||
g.p("// %v is a mock of %v interface", mockType, intf.Name)
|
||||
g.p("type %v struct {", mockType)
|
||||
g.in()
|
||||
g.p("ctrl *gomock.Controller")
|
||||
g.p("recorder *%vMockRecorder", mockType)
|
||||
g.out()
|
||||
g.p("}")
|
||||
g.p("")
|
||||
|
||||
g.p("// %vMockRecorder is the mock recorder for %v", mockType, mockType)
|
||||
g.p("type %vMockRecorder struct {", mockType)
|
||||
g.in()
|
||||
g.p("mock *%v", mockType)
|
||||
g.out()
|
||||
g.p("}")
|
||||
g.p("")
|
||||
|
||||
// TODO: Re-enable this if we can import the interface reliably.
|
||||
//g.p("// Verify that the mock satisfies the interface at compile time.")
|
||||
//g.p("var _ %v = (*%v)(nil)", typeName, mockType)
|
||||
//g.p("")
|
||||
|
||||
g.p("// New%v creates a new mock instance", mockType)
|
||||
g.p("func New%v(ctrl *gomock.Controller) *%v {", mockType, mockType)
|
||||
g.in()
|
||||
g.p("mock := &%v{ctrl: ctrl}", mockType)
|
||||
g.p("mock.recorder = &%vMockRecorder{mock}", mockType)
|
||||
g.p("return mock")
|
||||
g.out()
|
||||
g.p("}")
|
||||
g.p("")
|
||||
|
||||
// XXX: possible name collision here if someone has EXPECT in their interface.
|
||||
g.p("// EXPECT returns an object that allows the caller to indicate expected use")
|
||||
g.p("func (m *%v) EXPECT() *%vMockRecorder {", mockType, mockType)
|
||||
g.in()
|
||||
g.p("return m.recorder")
|
||||
g.out()
|
||||
g.p("}")
|
||||
|
||||
g.GenerateMockMethods(mockType, intf, outputPackagePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *generator) GenerateMockMethods(mockType string, intf *model.Interface, pkgOverride string) {
|
||||
for _, m := range intf.Methods {
|
||||
g.p("")
|
||||
g.GenerateMockMethod(mockType, m, pkgOverride)
|
||||
g.p("")
|
||||
g.GenerateMockRecorderMethod(mockType, m)
|
||||
}
|
||||
}
|
||||
|
||||
func makeArgString(argNames, argTypes []string) string {
|
||||
args := make([]string, len(argNames))
|
||||
for i, name := range argNames {
|
||||
// specify the type only once for consecutive args of the same type
|
||||
if i+1 < len(argTypes) && argTypes[i] == argTypes[i+1] {
|
||||
args[i] = name
|
||||
} else {
|
||||
args[i] = name + " " + argTypes[i]
|
||||
}
|
||||
}
|
||||
return strings.Join(args, ", ")
|
||||
}
|
||||
|
||||
// GenerateMockMethod generates a mock method implementation.
|
||||
// If non-empty, pkgOverride is the package in which unqualified types reside.
|
||||
func (g *generator) GenerateMockMethod(mockType string, m *model.Method, pkgOverride string) error {
|
||||
argNames := g.getArgNames(m)
|
||||
argTypes := g.getArgTypes(m, pkgOverride)
|
||||
argString := makeArgString(argNames, argTypes)
|
||||
|
||||
rets := make([]string, len(m.Out))
|
||||
for i, p := range m.Out {
|
||||
rets[i] = p.Type.String(g.packageMap, pkgOverride)
|
||||
}
|
||||
retString := strings.Join(rets, ", ")
|
||||
if len(rets) > 1 {
|
||||
retString = "(" + retString + ")"
|
||||
}
|
||||
if retString != "" {
|
||||
retString = " " + retString
|
||||
}
|
||||
|
||||
ia := newIdentifierAllocator(argNames)
|
||||
idRecv := ia.allocateIdentifier("m")
|
||||
|
||||
g.p("// %v mocks base method", m.Name)
|
||||
g.p("func (%v *%v) %v(%v)%v {", idRecv, mockType, m.Name, argString, retString)
|
||||
g.in()
|
||||
|
||||
var callArgs string
|
||||
if m.Variadic == nil {
|
||||
if len(argNames) > 0 {
|
||||
callArgs = ", " + strings.Join(argNames, ", ")
|
||||
}
|
||||
} else {
|
||||
// Non-trivial. The generated code must build a []interface{},
|
||||
// but the variadic argument may be any type.
|
||||
idVarArgs := ia.allocateIdentifier("varargs")
|
||||
idVArg := ia.allocateIdentifier("a")
|
||||
g.p("%s := []interface{}{%s}", idVarArgs, strings.Join(argNames[:len(argNames)-1], ", "))
|
||||
g.p("for _, %s := range %s {", idVArg, argNames[len(argNames)-1])
|
||||
g.in()
|
||||
g.p("%s = append(%s, %s)", idVarArgs, idVarArgs, idVArg)
|
||||
g.out()
|
||||
g.p("}")
|
||||
callArgs = ", " + idVarArgs + "..."
|
||||
}
|
||||
if len(m.Out) == 0 {
|
||||
g.p(`%v.ctrl.Call(%v, %q%v)`, idRecv, idRecv, m.Name, callArgs)
|
||||
} else {
|
||||
idRet := ia.allocateIdentifier("ret")
|
||||
g.p(`%v := %v.ctrl.Call(%v, %q%v)`, idRet, idRecv, idRecv, m.Name, callArgs)
|
||||
|
||||
// Go does not allow "naked" type assertions on nil values, so we use the two-value form here.
|
||||
// The value of that is either (x.(T), true) or (Z, false), where Z is the zero value for T.
|
||||
// Happily, this coincides with the semantics we want here.
|
||||
retNames := make([]string, len(rets))
|
||||
for i, t := range rets {
|
||||
retNames[i] = ia.allocateIdentifier(fmt.Sprintf("ret%d", i))
|
||||
g.p("%s, _ := %s[%d].(%s)", retNames[i], idRet, i, t)
|
||||
}
|
||||
g.p("return " + strings.Join(retNames, ", "))
|
||||
}
|
||||
|
||||
g.out()
|
||||
g.p("}")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *generator) GenerateMockRecorderMethod(mockType string, m *model.Method) error {
|
||||
argNames := g.getArgNames(m)
|
||||
|
||||
var argString string
|
||||
if m.Variadic == nil {
|
||||
argString = strings.Join(argNames, ", ")
|
||||
} else {
|
||||
argString = strings.Join(argNames[:len(argNames)-1], ", ")
|
||||
}
|
||||
if argString != "" {
|
||||
argString += " interface{}"
|
||||
}
|
||||
|
||||
if m.Variadic != nil {
|
||||
if argString != "" {
|
||||
argString += ", "
|
||||
}
|
||||
argString += fmt.Sprintf("%s ...interface{}", argNames[len(argNames)-1])
|
||||
}
|
||||
|
||||
ia := newIdentifierAllocator(argNames)
|
||||
idRecv := ia.allocateIdentifier("mr")
|
||||
|
||||
g.p("// %v indicates an expected call of %v", m.Name, m.Name)
|
||||
g.p("func (%s *%vMockRecorder) %v(%v) *gomock.Call {", idRecv, mockType, m.Name, argString)
|
||||
g.in()
|
||||
|
||||
var callArgs string
|
||||
if m.Variadic == nil {
|
||||
if len(argNames) > 0 {
|
||||
callArgs = ", " + strings.Join(argNames, ", ")
|
||||
}
|
||||
} else {
|
||||
if len(argNames) == 1 {
|
||||
// Easy: just use ... to push the arguments through.
|
||||
callArgs = ", " + argNames[0] + "..."
|
||||
} else {
|
||||
// Hard: create a temporary slice.
|
||||
idVarArgs := ia.allocateIdentifier("varargs")
|
||||
g.p("%s := append([]interface{}{%s}, %s...)",
|
||||
idVarArgs,
|
||||
strings.Join(argNames[:len(argNames)-1], ", "),
|
||||
argNames[len(argNames)-1])
|
||||
callArgs = ", " + idVarArgs + "..."
|
||||
}
|
||||
}
|
||||
g.p(`return %s.mock.ctrl.RecordCallWithMethodType(%s.mock, "%s", reflect.TypeOf((*%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, m.Name, callArgs)
|
||||
|
||||
g.out()
|
||||
g.p("}")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *generator) getArgNames(m *model.Method) []string {
|
||||
argNames := make([]string, len(m.In))
|
||||
for i, p := range m.In {
|
||||
name := p.Name
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("arg%d", i)
|
||||
}
|
||||
argNames[i] = name
|
||||
}
|
||||
if m.Variadic != nil {
|
||||
name := m.Variadic.Name
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("arg%d", len(m.In))
|
||||
}
|
||||
argNames = append(argNames, name)
|
||||
}
|
||||
return argNames
|
||||
}
|
||||
|
||||
func (g *generator) getArgTypes(m *model.Method, pkgOverride string) []string {
|
||||
argTypes := make([]string, len(m.In))
|
||||
for i, p := range m.In {
|
||||
argTypes[i] = p.Type.String(g.packageMap, pkgOverride)
|
||||
}
|
||||
if m.Variadic != nil {
|
||||
argTypes = append(argTypes, "..."+m.Variadic.Type.String(g.packageMap, pkgOverride))
|
||||
}
|
||||
return argTypes
|
||||
}
|
||||
|
||||
type identifierAllocator map[string]struct{}
|
||||
|
||||
func newIdentifierAllocator(taken []string) identifierAllocator {
|
||||
a := make(identifierAllocator, len(taken))
|
||||
for _, s := range taken {
|
||||
a[s] = struct{}{}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (o identifierAllocator) allocateIdentifier(want string) string {
|
||||
id := want
|
||||
for i := 2; ; i++ {
|
||||
if _, ok := o[id]; !ok {
|
||||
o[id] = struct{}{}
|
||||
return id
|
||||
}
|
||||
id = want + "_" + strconv.Itoa(i)
|
||||
}
|
||||
}
|
||||
|
||||
// Output returns the generator's output, formatted in the standard Go style.
|
||||
func (g *generator) Output() []byte {
|
||||
src, err := format.Source(g.buf.Bytes())
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to format generated source code: %s\n%s", err, g.buf.String())
|
||||
}
|
||||
return src
|
||||
}
|
181
vendor/github.com/golang/mock/mockgen/mockgen_test.go
generated
vendored
181
vendor/github.com/golang/mock/mockgen/mockgen_test.go
generated
vendored
@@ -1,181 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMakeArgString(t *testing.T) {
|
||||
testCases := []struct {
|
||||
argNames []string
|
||||
argTypes []string
|
||||
argString string
|
||||
}{
|
||||
{
|
||||
argNames: nil,
|
||||
argTypes: nil,
|
||||
argString: "",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0"},
|
||||
argTypes: []string{"int"},
|
||||
argString: "arg0 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1"},
|
||||
argTypes: []string{"int", "bool"},
|
||||
argString: "arg0 int, arg1 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1"},
|
||||
argTypes: []string{"int", "int"},
|
||||
argString: "arg0, arg1 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2"},
|
||||
argTypes: []string{"bool", "int", "int"},
|
||||
argString: "arg0 bool, arg1, arg2 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2"},
|
||||
argTypes: []string{"int", "bool", "int"},
|
||||
argString: "arg0 int, arg1 bool, arg2 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2"},
|
||||
argTypes: []string{"int", "int", "bool"},
|
||||
argString: "arg0, arg1 int, arg2 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2"},
|
||||
argTypes: []string{"int", "int", "int"},
|
||||
argString: "arg0, arg1, arg2 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
|
||||
argTypes: []string{"bool", "int", "int", "int"},
|
||||
argString: "arg0 bool, arg1, arg2, arg3 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
|
||||
argTypes: []string{"int", "bool", "int", "int"},
|
||||
argString: "arg0 int, arg1 bool, arg2, arg3 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
|
||||
argTypes: []string{"int", "int", "bool", "int"},
|
||||
argString: "arg0, arg1 int, arg2 bool, arg3 int",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
|
||||
argTypes: []string{"int", "int", "int", "bool"},
|
||||
argString: "arg0, arg1, arg2 int, arg3 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
|
||||
argTypes: []string{"bool", "int", "int", "int", "bool"},
|
||||
argString: "arg0 bool, arg1, arg2, arg3 int, arg4 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
|
||||
argTypes: []string{"int", "bool", "int", "int", "bool"},
|
||||
argString: "arg0 int, arg1 bool, arg2, arg3 int, arg4 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
|
||||
argTypes: []string{"int", "int", "bool", "int", "bool"},
|
||||
argString: "arg0, arg1 int, arg2 bool, arg3 int, arg4 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
|
||||
argTypes: []string{"int", "int", "int", "bool", "bool"},
|
||||
argString: "arg0, arg1, arg2 int, arg3, arg4 bool",
|
||||
},
|
||||
{
|
||||
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
|
||||
argTypes: []string{"int", "int", "bool", "bool", "int"},
|
||||
argString: "arg0, arg1 int, arg2, arg3 bool, arg4 int",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||
s := makeArgString(tc.argNames, tc.argTypes)
|
||||
if s != tc.argString {
|
||||
t.Errorf("result == %q, want %q", s, tc.argString)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewIdentifierAllocator(t *testing.T) {
|
||||
a := newIdentifierAllocator([]string{"taken1", "taken2"})
|
||||
if len(a) != 2 {
|
||||
t.Fatalf("expected 2 items, got %v", len(a))
|
||||
}
|
||||
|
||||
_, ok := a["taken1"]
|
||||
if !ok {
|
||||
t.Errorf("allocator doesn't contain 'taken1': %#v", a)
|
||||
}
|
||||
|
||||
_, ok = a["taken2"]
|
||||
if !ok {
|
||||
t.Errorf("allocator doesn't contain 'taken2': %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
func allocatorContainsIdentifiers(a identifierAllocator, ids []string) bool {
|
||||
if len(a) != len(ids) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, id := range ids {
|
||||
_, ok := a[id]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func TestIdentifierAllocator_allocateIdentifier(t *testing.T) {
|
||||
a := newIdentifierAllocator([]string{"taken"})
|
||||
|
||||
t2 := a.allocateIdentifier("taken_2")
|
||||
if t2 != "taken_2" {
|
||||
t.Fatalf("expected 'taken_2', got %q", t2)
|
||||
}
|
||||
expected := []string{"taken", "taken_2"}
|
||||
if !allocatorContainsIdentifiers(a, expected) {
|
||||
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
|
||||
}
|
||||
|
||||
t3 := a.allocateIdentifier("taken")
|
||||
if t3 != "taken_3" {
|
||||
t.Fatalf("expected 'taken_3', got %q", t3)
|
||||
}
|
||||
expected = []string{"taken", "taken_2", "taken_3"}
|
||||
if !allocatorContainsIdentifiers(a, expected) {
|
||||
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
|
||||
}
|
||||
|
||||
t4 := a.allocateIdentifier("taken")
|
||||
if t4 != "taken_4" {
|
||||
t.Fatalf("expected 'taken_4', got %q", t4)
|
||||
}
|
||||
expected = []string{"taken", "taken_2", "taken_3", "taken_4"}
|
||||
if !allocatorContainsIdentifiers(a, expected) {
|
||||
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
|
||||
}
|
||||
|
||||
id := a.allocateIdentifier("id")
|
||||
if id != "id" {
|
||||
t.Fatalf("expected 'id', got %q", id)
|
||||
}
|
||||
expected = []string{"taken", "taken_2", "taken_3", "taken_4", "id"}
|
||||
if !allocatorContainsIdentifiers(a, expected) {
|
||||
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
|
||||
}
|
||||
}
|
449
vendor/github.com/golang/mock/mockgen/model/model.go
generated
vendored
449
vendor/github.com/golang/mock/mockgen/model/model.go
generated
vendored
@@ -1,449 +0,0 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package model contains the data model necessary for generating mock implementations.
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// pkgPath is the importable path for package model
|
||||
const pkgPath = "github.com/golang/mock/mockgen/model"
|
||||
|
||||
// Package is a Go package. It may be a subset.
|
||||
type Package struct {
|
||||
Name string
|
||||
Interfaces []*Interface
|
||||
DotImports []string
|
||||
}
|
||||
|
||||
func (pkg *Package) Print(w io.Writer) {
|
||||
fmt.Fprintf(w, "package %s\n", pkg.Name)
|
||||
for _, intf := range pkg.Interfaces {
|
||||
intf.Print(w)
|
||||
}
|
||||
}
|
||||
|
||||
// Imports returns the imports needed by the Package as a set of import paths.
|
||||
func (pkg *Package) Imports() map[string]bool {
|
||||
im := make(map[string]bool)
|
||||
for _, intf := range pkg.Interfaces {
|
||||
intf.addImports(im)
|
||||
}
|
||||
return im
|
||||
}
|
||||
|
||||
// Interface is a Go interface.
|
||||
type Interface struct {
|
||||
Name string
|
||||
Methods []*Method
|
||||
}
|
||||
|
||||
func (intf *Interface) Print(w io.Writer) {
|
||||
fmt.Fprintf(w, "interface %s\n", intf.Name)
|
||||
for _, m := range intf.Methods {
|
||||
m.Print(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (intf *Interface) addImports(im map[string]bool) {
|
||||
for _, m := range intf.Methods {
|
||||
m.addImports(im)
|
||||
}
|
||||
}
|
||||
|
||||
// Method is a single method of an interface.
|
||||
type Method struct {
|
||||
Name string
|
||||
In, Out []*Parameter
|
||||
Variadic *Parameter // may be nil
|
||||
}
|
||||
|
||||
func (m *Method) Print(w io.Writer) {
|
||||
fmt.Fprintf(w, " - method %s\n", m.Name)
|
||||
if len(m.In) > 0 {
|
||||
fmt.Fprintf(w, " in:\n")
|
||||
for _, p := range m.In {
|
||||
p.Print(w)
|
||||
}
|
||||
}
|
||||
if m.Variadic != nil {
|
||||
fmt.Fprintf(w, " ...:\n")
|
||||
m.Variadic.Print(w)
|
||||
}
|
||||
if len(m.Out) > 0 {
|
||||
fmt.Fprintf(w, " out:\n")
|
||||
for _, p := range m.Out {
|
||||
p.Print(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Method) addImports(im map[string]bool) {
|
||||
for _, p := range m.In {
|
||||
p.Type.addImports(im)
|
||||
}
|
||||
if m.Variadic != nil {
|
||||
m.Variadic.Type.addImports(im)
|
||||
}
|
||||
for _, p := range m.Out {
|
||||
p.Type.addImports(im)
|
||||
}
|
||||
}
|
||||
|
||||
// Parameter is an argument or return parameter of a method.
|
||||
type Parameter struct {
|
||||
Name string // may be empty
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (p *Parameter) Print(w io.Writer) {
|
||||
n := p.Name
|
||||
if n == "" {
|
||||
n = `""`
|
||||
}
|
||||
fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, ""))
|
||||
}
|
||||
|
||||
// Type is a Go type.
|
||||
type Type interface {
|
||||
String(pm map[string]string, pkgOverride string) string
|
||||
addImports(im map[string]bool)
|
||||
}
|
||||
|
||||
func init() {
|
||||
gob.Register(&ArrayType{})
|
||||
gob.Register(&ChanType{})
|
||||
gob.Register(&FuncType{})
|
||||
gob.Register(&MapType{})
|
||||
gob.Register(&NamedType{})
|
||||
gob.Register(&PointerType{})
|
||||
|
||||
// Call gob.RegisterName to make sure it has the consistent name registered
|
||||
// for both gob decoder and encoder.
|
||||
//
|
||||
// For a non-pointer type, gob.Register will try to get package full path by
|
||||
// calling rt.PkgPath() for a name to register. If your project has vendor
|
||||
// directory, it is possible that PkgPath will get a path like this:
|
||||
// ../../../vendor/github.com/golang/mock/mockgen/model
|
||||
gob.RegisterName(pkgPath+".PredeclaredType", PredeclaredType(""))
|
||||
}
|
||||
|
||||
// ArrayType is an array or slice type.
|
||||
type ArrayType struct {
|
||||
Len int // -1 for slices, >= 0 for arrays
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (at *ArrayType) String(pm map[string]string, pkgOverride string) string {
|
||||
s := "[]"
|
||||
if at.Len > -1 {
|
||||
s = fmt.Sprintf("[%d]", at.Len)
|
||||
}
|
||||
return s + at.Type.String(pm, pkgOverride)
|
||||
}
|
||||
|
||||
func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) }
|
||||
|
||||
// ChanType is a channel type.
|
||||
type ChanType struct {
|
||||
Dir ChanDir // 0, 1 or 2
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (ct *ChanType) String(pm map[string]string, pkgOverride string) string {
|
||||
s := ct.Type.String(pm, pkgOverride)
|
||||
if ct.Dir == RecvDir {
|
||||
return "<-chan " + s
|
||||
}
|
||||
if ct.Dir == SendDir {
|
||||
return "chan<- " + s
|
||||
}
|
||||
return "chan " + s
|
||||
}
|
||||
|
||||
func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) }
|
||||
|
||||
// ChanDir is a channel direction.
|
||||
type ChanDir int
|
||||
|
||||
const (
|
||||
RecvDir ChanDir = 1
|
||||
SendDir ChanDir = 2
|
||||
)
|
||||
|
||||
// FuncType is a function type.
|
||||
type FuncType struct {
|
||||
In, Out []*Parameter
|
||||
Variadic *Parameter // may be nil
|
||||
}
|
||||
|
||||
func (ft *FuncType) String(pm map[string]string, pkgOverride string) string {
|
||||
args := make([]string, len(ft.In))
|
||||
for i, p := range ft.In {
|
||||
args[i] = p.Type.String(pm, pkgOverride)
|
||||
}
|
||||
if ft.Variadic != nil {
|
||||
args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride))
|
||||
}
|
||||
rets := make([]string, len(ft.Out))
|
||||
for i, p := range ft.Out {
|
||||
rets[i] = p.Type.String(pm, pkgOverride)
|
||||
}
|
||||
retString := strings.Join(rets, ", ")
|
||||
if nOut := len(ft.Out); nOut == 1 {
|
||||
retString = " " + retString
|
||||
} else if nOut > 1 {
|
||||
retString = " (" + retString + ")"
|
||||
}
|
||||
return "func(" + strings.Join(args, ", ") + ")" + retString
|
||||
}
|
||||
|
||||
func (ft *FuncType) addImports(im map[string]bool) {
|
||||
for _, p := range ft.In {
|
||||
p.Type.addImports(im)
|
||||
}
|
||||
if ft.Variadic != nil {
|
||||
ft.Variadic.Type.addImports(im)
|
||||
}
|
||||
for _, p := range ft.Out {
|
||||
p.Type.addImports(im)
|
||||
}
|
||||
}
|
||||
|
||||
// MapType is a map type.
|
||||
type MapType struct {
|
||||
Key, Value Type
|
||||
}
|
||||
|
||||
func (mt *MapType) String(pm map[string]string, pkgOverride string) string {
|
||||
return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride)
|
||||
}
|
||||
|
||||
func (mt *MapType) addImports(im map[string]bool) {
|
||||
mt.Key.addImports(im)
|
||||
mt.Value.addImports(im)
|
||||
}
|
||||
|
||||
// NamedType is an exported type in a package.
|
||||
type NamedType struct {
|
||||
Package string // may be empty
|
||||
Type string // TODO: should this be typed Type?
|
||||
}
|
||||
|
||||
func (nt *NamedType) String(pm map[string]string, pkgOverride string) string {
|
||||
// TODO: is this right?
|
||||
if pkgOverride == nt.Package {
|
||||
return nt.Type
|
||||
}
|
||||
return pm[nt.Package] + "." + nt.Type
|
||||
}
|
||||
func (nt *NamedType) addImports(im map[string]bool) {
|
||||
if nt.Package != "" {
|
||||
im[nt.Package] = true
|
||||
}
|
||||
}
|
||||
|
||||
// PointerType is a pointer to another type.
|
||||
type PointerType struct {
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (pt *PointerType) String(pm map[string]string, pkgOverride string) string {
|
||||
return "*" + pt.Type.String(pm, pkgOverride)
|
||||
}
|
||||
func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) }
|
||||
|
||||
// PredeclaredType is a predeclared type such as "int".
|
||||
type PredeclaredType string
|
||||
|
||||
func (pt PredeclaredType) String(pm map[string]string, pkgOverride string) string { return string(pt) }
|
||||
func (pt PredeclaredType) addImports(im map[string]bool) {}
|
||||
|
||||
// The following code is intended to be called by the program generated by ../reflect.go.
|
||||
|
||||
func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) {
|
||||
if it.Kind() != reflect.Interface {
|
||||
return nil, fmt.Errorf("%v is not an interface", it)
|
||||
}
|
||||
intf := &Interface{}
|
||||
|
||||
for i := 0; i < it.NumMethod(); i++ {
|
||||
mt := it.Method(i)
|
||||
// TODO: need to skip unexported methods? or just raise an error?
|
||||
m := &Method{
|
||||
Name: mt.Name,
|
||||
}
|
||||
|
||||
var err error
|
||||
m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
intf.Methods = append(intf.Methods, m)
|
||||
}
|
||||
|
||||
return intf, nil
|
||||
}
|
||||
|
||||
// t's Kind must be a reflect.Func.
|
||||
func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) {
|
||||
nin := t.NumIn()
|
||||
if t.IsVariadic() {
|
||||
nin--
|
||||
}
|
||||
var p *Parameter
|
||||
for i := 0; i < nin; i++ {
|
||||
p, err = parameterFromType(t.In(i))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
in = append(in, p)
|
||||
}
|
||||
if t.IsVariadic() {
|
||||
p, err = parameterFromType(t.In(nin).Elem())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
variadic = p
|
||||
}
|
||||
for i := 0; i < t.NumOut(); i++ {
|
||||
p, err = parameterFromType(t.Out(i))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out = append(out, p)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parameterFromType(t reflect.Type) (*Parameter, error) {
|
||||
tt, err := typeFromType(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Parameter{Type: tt}, nil
|
||||
}
|
||||
|
||||
var errorType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
|
||||
var byteType = reflect.TypeOf(byte(0))
|
||||
|
||||
func typeFromType(t reflect.Type) (Type, error) {
|
||||
// Hack workaround for https://golang.org/issue/3853.
|
||||
// This explicit check should not be necessary.
|
||||
if t == byteType {
|
||||
return PredeclaredType("byte"), nil
|
||||
}
|
||||
|
||||
if imp := t.PkgPath(); imp != "" {
|
||||
// PkgPath might return a path that includes "vendor"
|
||||
// These paths do not compile, so we need to remove everything
|
||||
// up to and including "/vendor/"
|
||||
// see https://github.com/golang/go/issues/12019
|
||||
if i := strings.LastIndex(imp, "/vendor/"); i != -1 {
|
||||
imp = imp[i+len("/vendor/"):]
|
||||
}
|
||||
return &NamedType{
|
||||
Package: imp,
|
||||
Type: t.Name(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// only unnamed or predeclared types after here
|
||||
|
||||
// Lots of types have element types. Let's do the parsing and error checking for all of them.
|
||||
var elemType Type
|
||||
switch t.Kind() {
|
||||
case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
var err error
|
||||
elemType, err = typeFromType(t.Elem())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Array:
|
||||
return &ArrayType{
|
||||
Len: t.Len(),
|
||||
Type: elemType,
|
||||
}, nil
|
||||
case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
|
||||
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String:
|
||||
return PredeclaredType(t.Kind().String()), nil
|
||||
case reflect.Chan:
|
||||
var dir ChanDir
|
||||
switch t.ChanDir() {
|
||||
case reflect.RecvDir:
|
||||
dir = RecvDir
|
||||
case reflect.SendDir:
|
||||
dir = SendDir
|
||||
}
|
||||
return &ChanType{
|
||||
Dir: dir,
|
||||
Type: elemType,
|
||||
}, nil
|
||||
case reflect.Func:
|
||||
in, variadic, out, err := funcArgsFromType(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FuncType{
|
||||
In: in,
|
||||
Out: out,
|
||||
Variadic: variadic,
|
||||
}, nil
|
||||
case reflect.Interface:
|
||||
// Two special interfaces.
|
||||
if t.NumMethod() == 0 {
|
||||
return PredeclaredType("interface{}"), nil
|
||||
}
|
||||
if t == errorType {
|
||||
return PredeclaredType("error"), nil
|
||||
}
|
||||
case reflect.Map:
|
||||
kt, err := typeFromType(t.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &MapType{
|
||||
Key: kt,
|
||||
Value: elemType,
|
||||
}, nil
|
||||
case reflect.Ptr:
|
||||
return &PointerType{
|
||||
Type: elemType,
|
||||
}, nil
|
||||
case reflect.Slice:
|
||||
return &ArrayType{
|
||||
Len: -1,
|
||||
Type: elemType,
|
||||
}, nil
|
||||
case reflect.Struct:
|
||||
if t.NumField() == 0 {
|
||||
return PredeclaredType("struct{}"), nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Struct, UnsafePointer
|
||||
return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind())
|
||||
}
|
504
vendor/github.com/golang/mock/mockgen/parse.go
generated
vendored
504
vendor/github.com/golang/mock/mockgen/parse.go
generated
vendored
@@ -1,504 +0,0 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
// This file contains the model construction by parsing source files.
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"log"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/mock/mockgen/model"
|
||||
)
|
||||
|
||||
var (
|
||||
imports = flag.String("imports", "", "(source mode) Comma-separated name=path pairs of explicit imports to use.")
|
||||
auxFiles = flag.String("aux_files", "", "(source mode) Comma-separated pkg=path pairs of auxiliary Go source files.")
|
||||
)
|
||||
|
||||
// TODO: simplify error reporting
|
||||
|
||||
func ParseFile(source string) (*model.Package, error) {
|
||||
srcDir, err := filepath.Abs(filepath.Dir(source))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed getting source directory: %v", err)
|
||||
}
|
||||
|
||||
var packageImport string
|
||||
if p, err := build.ImportDir(srcDir, 0); err == nil {
|
||||
packageImport = p.ImportPath
|
||||
} // TODO: should we fail if this returns an error?
|
||||
|
||||
fs := token.NewFileSet()
|
||||
file, err := parser.ParseFile(fs, source, nil, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed parsing source file %v: %v", source, err)
|
||||
}
|
||||
|
||||
p := &fileParser{
|
||||
fileSet: fs,
|
||||
imports: make(map[string]string),
|
||||
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
|
||||
auxInterfaces: make(map[string]map[string]*ast.InterfaceType),
|
||||
srcDir: srcDir,
|
||||
}
|
||||
|
||||
// Handle -imports.
|
||||
dotImports := make(map[string]bool)
|
||||
if *imports != "" {
|
||||
for _, kv := range strings.Split(*imports, ",") {
|
||||
eq := strings.Index(kv, "=")
|
||||
k, v := kv[:eq], kv[eq+1:]
|
||||
if k == "." {
|
||||
// TODO: Catch dupes?
|
||||
dotImports[v] = true
|
||||
} else {
|
||||
// TODO: Catch dupes?
|
||||
p.imports[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle -aux_files.
|
||||
if err := p.parseAuxFiles(*auxFiles); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.addAuxInterfacesFromFile(packageImport, file) // this file
|
||||
|
||||
pkg, err := p.parseFile(packageImport, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkg.DotImports = make([]string, 0, len(dotImports))
|
||||
for path := range dotImports {
|
||||
pkg.DotImports = append(pkg.DotImports, path)
|
||||
}
|
||||
return pkg, nil
|
||||
}
|
||||
|
||||
type fileParser struct {
|
||||
fileSet *token.FileSet
|
||||
imports map[string]string // package name => import path
|
||||
importedInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface
|
||||
|
||||
auxFiles []*ast.File
|
||||
auxInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface
|
||||
|
||||
srcDir string
|
||||
}
|
||||
|
||||
func (p *fileParser) errorf(pos token.Pos, format string, args ...interface{}) error {
|
||||
ps := p.fileSet.Position(pos)
|
||||
format = "%s:%d:%d: " + format
|
||||
args = append([]interface{}{ps.Filename, ps.Line, ps.Column}, args...)
|
||||
return fmt.Errorf(format, args...)
|
||||
}
|
||||
|
||||
func (p *fileParser) parseAuxFiles(auxFiles string) error {
|
||||
auxFiles = strings.TrimSpace(auxFiles)
|
||||
if auxFiles == "" {
|
||||
return nil
|
||||
}
|
||||
for _, kv := range strings.Split(auxFiles, ",") {
|
||||
parts := strings.SplitN(kv, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("bad aux file spec: %v", kv)
|
||||
}
|
||||
pkg, fpath := parts[0], parts[1]
|
||||
|
||||
file, err := parser.ParseFile(p.fileSet, fpath, nil, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.auxFiles = append(p.auxFiles, file)
|
||||
p.addAuxInterfacesFromFile(pkg, file)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *fileParser) addAuxInterfacesFromFile(pkg string, file *ast.File) {
|
||||
if _, ok := p.auxInterfaces[pkg]; !ok {
|
||||
p.auxInterfaces[pkg] = make(map[string]*ast.InterfaceType)
|
||||
}
|
||||
for ni := range iterInterfaces(file) {
|
||||
p.auxInterfaces[pkg][ni.name.Name] = ni.it
|
||||
}
|
||||
}
|
||||
|
||||
// parseFile loads all file imports and auxiliary files import into the
|
||||
// fileParser, parses all file interfaces and returns package model.
|
||||
func (p *fileParser) parseFile(importPath string, file *ast.File) (*model.Package, error) {
|
||||
allImports := importsOfFile(file)
|
||||
// Don't stomp imports provided by -imports. Those should take precedence.
|
||||
for pkg, path := range allImports {
|
||||
if _, ok := p.imports[pkg]; !ok {
|
||||
p.imports[pkg] = path
|
||||
}
|
||||
}
|
||||
// Add imports from auxiliary files, which might be needed for embedded interfaces.
|
||||
// Don't stomp any other imports.
|
||||
for _, f := range p.auxFiles {
|
||||
for pkg, path := range importsOfFile(f) {
|
||||
if _, ok := p.imports[pkg]; !ok {
|
||||
p.imports[pkg] = path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var is []*model.Interface
|
||||
for ni := range iterInterfaces(file) {
|
||||
i, err := p.parseInterface(ni.name.String(), importPath, ni.it)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
is = append(is, i)
|
||||
}
|
||||
return &model.Package{
|
||||
Name: file.Name.String(),
|
||||
Interfaces: is,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// parsePackage loads package specified by path, parses it and populates
|
||||
// corresponding imports and importedInterfaces into the fileParser.
|
||||
func (p *fileParser) parsePackage(path string) error {
|
||||
var pkgs map[string]*ast.Package
|
||||
if imp, err := build.Import(path, p.srcDir, build.FindOnly); err != nil {
|
||||
return err
|
||||
} else if pkgs, err = parser.ParseDir(p.fileSet, imp.Dir, nil, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, pkg := range pkgs {
|
||||
file := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates)
|
||||
if _, ok := p.importedInterfaces[path]; !ok {
|
||||
p.importedInterfaces[path] = make(map[string]*ast.InterfaceType)
|
||||
}
|
||||
for ni := range iterInterfaces(file) {
|
||||
p.importedInterfaces[path][ni.name.Name] = ni.it
|
||||
}
|
||||
for pkgName, pkgPath := range importsOfFile(file) {
|
||||
if _, ok := p.imports[pkgName]; !ok {
|
||||
p.imports[pkgName] = pkgPath
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *fileParser) parseInterface(name, pkg string, it *ast.InterfaceType) (*model.Interface, error) {
|
||||
intf := &model.Interface{Name: name}
|
||||
for _, field := range it.Methods.List {
|
||||
switch v := field.Type.(type) {
|
||||
case *ast.FuncType:
|
||||
if nn := len(field.Names); nn != 1 {
|
||||
return nil, fmt.Errorf("expected one name for interface %v, got %d", intf.Name, nn)
|
||||
}
|
||||
m := &model.Method{
|
||||
Name: field.Names[0].String(),
|
||||
}
|
||||
var err error
|
||||
m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
intf.Methods = append(intf.Methods, m)
|
||||
case *ast.Ident:
|
||||
// Embedded interface in this package.
|
||||
ei := p.auxInterfaces[pkg][v.String()]
|
||||
if ei == nil {
|
||||
if ei = p.importedInterfaces[pkg][v.String()]; ei == nil {
|
||||
return nil, p.errorf(v.Pos(), "unknown embedded interface %s", v.String())
|
||||
}
|
||||
}
|
||||
eintf, err := p.parseInterface(v.String(), pkg, ei)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Copy the methods.
|
||||
// TODO: apply shadowing rules.
|
||||
for _, m := range eintf.Methods {
|
||||
intf.Methods = append(intf.Methods, m)
|
||||
}
|
||||
case *ast.SelectorExpr:
|
||||
// Embedded interface in another package.
|
||||
fpkg, sel := v.X.(*ast.Ident).String(), v.Sel.String()
|
||||
epkg, ok := p.imports[fpkg]
|
||||
if !ok {
|
||||
return nil, p.errorf(v.X.Pos(), "unknown package %s", fpkg)
|
||||
}
|
||||
ei := p.auxInterfaces[fpkg][sel]
|
||||
if ei == nil {
|
||||
fpkg = epkg
|
||||
if _, ok = p.importedInterfaces[epkg]; !ok {
|
||||
if err := p.parsePackage(epkg); err != nil {
|
||||
return nil, p.errorf(v.Pos(), "could not parse package %s: %v", fpkg, err)
|
||||
}
|
||||
}
|
||||
if ei = p.importedInterfaces[epkg][sel]; ei == nil {
|
||||
return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", fpkg, sel)
|
||||
}
|
||||
}
|
||||
eintf, err := p.parseInterface(sel, fpkg, ei)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Copy the methods.
|
||||
// TODO: apply shadowing rules.
|
||||
for _, m := range eintf.Methods {
|
||||
intf.Methods = append(intf.Methods, m)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type)
|
||||
}
|
||||
}
|
||||
return intf, nil
|
||||
}
|
||||
|
||||
func (p *fileParser) parseFunc(pkg string, f *ast.FuncType) (in []*model.Parameter, variadic *model.Parameter, out []*model.Parameter, err error) {
|
||||
if f.Params != nil {
|
||||
regParams := f.Params.List
|
||||
if isVariadic(f) {
|
||||
n := len(regParams)
|
||||
varParams := regParams[n-1:]
|
||||
regParams = regParams[:n-1]
|
||||
vp, err := p.parseFieldList(pkg, varParams)
|
||||
if err != nil {
|
||||
return nil, nil, nil, p.errorf(varParams[0].Pos(), "failed parsing variadic argument: %v", err)
|
||||
}
|
||||
variadic = vp[0]
|
||||
}
|
||||
in, err = p.parseFieldList(pkg, regParams)
|
||||
if err != nil {
|
||||
return nil, nil, nil, p.errorf(f.Pos(), "failed parsing arguments: %v", err)
|
||||
}
|
||||
}
|
||||
if f.Results != nil {
|
||||
out, err = p.parseFieldList(pkg, f.Results.List)
|
||||
if err != nil {
|
||||
return nil, nil, nil, p.errorf(f.Pos(), "failed parsing returns: %v", err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field) ([]*model.Parameter, error) {
|
||||
nf := 0
|
||||
for _, f := range fields {
|
||||
nn := len(f.Names)
|
||||
if nn == 0 {
|
||||
nn = 1 // anonymous parameter
|
||||
}
|
||||
nf += nn
|
||||
}
|
||||
if nf == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
ps := make([]*model.Parameter, nf)
|
||||
i := 0 // destination index
|
||||
for _, f := range fields {
|
||||
t, err := p.parseType(pkg, f.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(f.Names) == 0 {
|
||||
// anonymous arg
|
||||
ps[i] = &model.Parameter{Type: t}
|
||||
i++
|
||||
continue
|
||||
}
|
||||
for _, name := range f.Names {
|
||||
ps[i] = &model.Parameter{Name: name.Name, Type: t}
|
||||
i++
|
||||
}
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) {
|
||||
switch v := typ.(type) {
|
||||
case *ast.ArrayType:
|
||||
ln := -1
|
||||
if v.Len != nil {
|
||||
x, err := strconv.Atoi(v.Len.(*ast.BasicLit).Value)
|
||||
if err != nil {
|
||||
return nil, p.errorf(v.Len.Pos(), "bad array size: %v", err)
|
||||
}
|
||||
ln = x
|
||||
}
|
||||
t, err := p.parseType(pkg, v.Elt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.ArrayType{Len: ln, Type: t}, nil
|
||||
case *ast.ChanType:
|
||||
t, err := p.parseType(pkg, v.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var dir model.ChanDir
|
||||
if v.Dir == ast.SEND {
|
||||
dir = model.SendDir
|
||||
}
|
||||
if v.Dir == ast.RECV {
|
||||
dir = model.RecvDir
|
||||
}
|
||||
return &model.ChanType{Dir: dir, Type: t}, nil
|
||||
case *ast.Ellipsis:
|
||||
// assume we're parsing a variadic argument
|
||||
return p.parseType(pkg, v.Elt)
|
||||
case *ast.FuncType:
|
||||
in, variadic, out, err := p.parseFunc(pkg, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.FuncType{In: in, Out: out, Variadic: variadic}, nil
|
||||
case *ast.Ident:
|
||||
if v.IsExported() {
|
||||
// `pkg` may be an aliased imported pkg
|
||||
// if so, patch the import w/ the fully qualified import
|
||||
maybeImportedPkg, ok := p.imports[pkg]
|
||||
if ok {
|
||||
pkg = maybeImportedPkg
|
||||
}
|
||||
// assume type in this package
|
||||
return &model.NamedType{Package: pkg, Type: v.Name}, nil
|
||||
} else {
|
||||
// assume predeclared type
|
||||
return model.PredeclaredType(v.Name), nil
|
||||
}
|
||||
case *ast.InterfaceType:
|
||||
if v.Methods != nil && len(v.Methods.List) > 0 {
|
||||
return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed interface types")
|
||||
}
|
||||
return model.PredeclaredType("interface{}"), nil
|
||||
case *ast.MapType:
|
||||
key, err := p.parseType(pkg, v.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value, err := p.parseType(pkg, v.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.MapType{Key: key, Value: value}, nil
|
||||
case *ast.SelectorExpr:
|
||||
pkgName := v.X.(*ast.Ident).String()
|
||||
pkg, ok := p.imports[pkgName]
|
||||
if !ok {
|
||||
return nil, p.errorf(v.Pos(), "unknown package %q", pkgName)
|
||||
}
|
||||
return &model.NamedType{Package: pkg, Type: v.Sel.String()}, nil
|
||||
case *ast.StarExpr:
|
||||
t, err := p.parseType(pkg, v.X)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.PointerType{Type: t}, nil
|
||||
case *ast.StructType:
|
||||
if v.Fields != nil && len(v.Fields.List) > 0 {
|
||||
return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed struct types")
|
||||
}
|
||||
return model.PredeclaredType("struct{}"), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("don't know how to parse type %T", typ)
|
||||
}
|
||||
|
||||
// importsOfFile returns a map of package name to import path
|
||||
// of the imports in file.
|
||||
func importsOfFile(file *ast.File) map[string]string {
|
||||
m := make(map[string]string)
|
||||
for _, is := range file.Imports {
|
||||
var pkgName string
|
||||
importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes
|
||||
|
||||
if is.Name != nil {
|
||||
// Named imports are always certain.
|
||||
if is.Name.Name == "_" {
|
||||
continue
|
||||
}
|
||||
pkgName = removeDot(is.Name.Name)
|
||||
} else {
|
||||
pkg, err := build.Import(importPath, "", 0)
|
||||
if err != nil {
|
||||
// Fallback to import path suffix. Note that this is uncertain.
|
||||
_, last := path.Split(importPath)
|
||||
// If the last path component has dots, the first dot-delimited
|
||||
// field is used as the name.
|
||||
pkgName = strings.SplitN(last, ".", 2)[0]
|
||||
} else {
|
||||
pkgName = pkg.Name
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := m[pkgName]; ok {
|
||||
log.Fatalf("imported package collision: %q imported twice", pkgName)
|
||||
}
|
||||
m[pkgName] = importPath
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
type namedInterface struct {
|
||||
name *ast.Ident
|
||||
it *ast.InterfaceType
|
||||
}
|
||||
|
||||
// Create an iterator over all interfaces in file.
|
||||
func iterInterfaces(file *ast.File) <-chan namedInterface {
|
||||
ch := make(chan namedInterface)
|
||||
go func() {
|
||||
for _, decl := range file.Decls {
|
||||
gd, ok := decl.(*ast.GenDecl)
|
||||
if !ok || gd.Tok != token.TYPE {
|
||||
continue
|
||||
}
|
||||
for _, spec := range gd.Specs {
|
||||
ts, ok := spec.(*ast.TypeSpec)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
it, ok := ts.Type.(*ast.InterfaceType)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- namedInterface{ts.Name, it}
|
||||
}
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
// isVariadic returns whether the function is variadic.
|
||||
func isVariadic(f *ast.FuncType) bool {
|
||||
nargs := len(f.Params.List)
|
||||
if nargs == 0 {
|
||||
return false
|
||||
}
|
||||
_, ok := f.Params.List[nargs-1].Type.(*ast.Ellipsis)
|
||||
return ok
|
||||
}
|
108
vendor/github.com/golang/mock/mockgen/parse_test.go
generated
vendored
108
vendor/github.com/golang/mock/mockgen/parse_test.go
generated
vendored
@@ -1,108 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFileParser_ParseFile(t *testing.T) {
|
||||
fs := token.NewFileSet()
|
||||
file, err := parser.ParseFile(fs, "tests/custom_package_name/greeter/greeter.go", nil, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
p := fileParser{
|
||||
fileSet: fs,
|
||||
imports: make(map[string]string),
|
||||
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
|
||||
}
|
||||
|
||||
pkg, err := p.parseFile("", file)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
checkGreeterImports(t, p.imports)
|
||||
|
||||
expectedName := "greeter"
|
||||
if pkg.Name != expectedName {
|
||||
t.Fatalf("Expected name to be %v but got %v", expectedName, pkg.Name)
|
||||
}
|
||||
|
||||
expectedInterfaceName := "InputMaker"
|
||||
if pkg.Interfaces[0].Name != expectedInterfaceName {
|
||||
t.Fatalf("Expected interface name to be %v but got %v", expectedInterfaceName, pkg.Interfaces[0].Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileParser_ParsePackage(t *testing.T) {
|
||||
fs := token.NewFileSet()
|
||||
_, err := parser.ParseFile(fs, "tests/custom_package_name/greeter/greeter.go", nil, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
p := fileParser{
|
||||
fileSet: fs,
|
||||
imports: make(map[string]string),
|
||||
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
|
||||
}
|
||||
|
||||
err = p.parsePackage("github.com/golang/mock/mockgen/tests/custom_package_name/greeter")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
checkGreeterImports(t, p.imports)
|
||||
}
|
||||
|
||||
func TestImportsOfFile(t *testing.T) {
|
||||
fs := token.NewFileSet()
|
||||
file, err := parser.ParseFile(fs, "tests/custom_package_name/greeter/greeter.go", nil, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
imports := importsOfFile(file)
|
||||
checkGreeterImports(t, imports)
|
||||
}
|
||||
|
||||
func checkGreeterImports(t *testing.T, imports map[string]string) {
|
||||
// check that imports have stdlib package "fmt"
|
||||
if fmtPackage, ok := imports["fmt"]; !ok {
|
||||
t.Errorf("Expected imports to have key \"fmt\"")
|
||||
} else {
|
||||
expectedFmtPackage := "fmt"
|
||||
if fmtPackage != expectedFmtPackage {
|
||||
t.Errorf("Expected fmt key to have value %s but got %s", expectedFmtPackage, fmtPackage)
|
||||
}
|
||||
}
|
||||
|
||||
// check that imports have package named "validator"
|
||||
if validatorPackage, ok := imports["validator"]; !ok {
|
||||
t.Errorf("Expected imports to have key \"fmt\"")
|
||||
} else {
|
||||
expectedValidatorPackage := "github.com/golang/mock/mockgen/tests/custom_package_name/validator"
|
||||
if validatorPackage != expectedValidatorPackage {
|
||||
t.Errorf("Expected validator key to have value %s but got %s", expectedValidatorPackage, validatorPackage)
|
||||
}
|
||||
}
|
||||
|
||||
// check that imports have package named "client"
|
||||
if clientPackage, ok := imports["client"]; !ok {
|
||||
t.Errorf("Expected imports to have key \"client\"")
|
||||
} else {
|
||||
expectedClientPackage := "github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
|
||||
if clientPackage != expectedClientPackage {
|
||||
t.Errorf("Expected client key to have value %s but got %s", expectedClientPackage, clientPackage)
|
||||
}
|
||||
}
|
||||
|
||||
// check that imports don't have package named "v1"
|
||||
if _, ok := imports["v1"]; ok {
|
||||
t.Errorf("Expected import not to have key \"v1\"")
|
||||
}
|
||||
}
|
197
vendor/github.com/golang/mock/mockgen/reflect.go
generated
vendored
197
vendor/github.com/golang/mock/mockgen/reflect.go
generated
vendored
@@ -1,197 +0,0 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
// This file contains the model construction by reflection.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"flag"
|
||||
"go/build"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"text/template"
|
||||
|
||||
"github.com/golang/mock/mockgen/model"
|
||||
)
|
||||
|
||||
var (
|
||||
progOnly = flag.Bool("prog_only", false, "(reflect mode) Only generate the reflection program; write it to stdout and exit.")
|
||||
execOnly = flag.String("exec_only", "", "(reflect mode) If set, execute this reflection program.")
|
||||
buildFlags = flag.String("build_flags", "", "(reflect mode) Additional flags for go build.")
|
||||
)
|
||||
|
||||
func writeProgram(importPath string, symbols []string) ([]byte, error) {
|
||||
var program bytes.Buffer
|
||||
data := reflectData{
|
||||
ImportPath: importPath,
|
||||
Symbols: symbols,
|
||||
}
|
||||
if err := reflectProgram.Execute(&program, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return program.Bytes(), nil
|
||||
}
|
||||
|
||||
// run the given command and parse the output as a model.Package.
|
||||
func run(command string) (*model.Package, error) {
|
||||
// Run the program.
|
||||
cmd := exec.Command(command)
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Process output.
|
||||
var pkg model.Package
|
||||
if err := gob.NewDecoder(&stdout).Decode(&pkg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pkg, nil
|
||||
}
|
||||
|
||||
// runInDir writes the given program into the given dir, runs it there, and
|
||||
// parses the output as a model.Package.
|
||||
func runInDir(program []byte, dir string) (*model.Package, error) {
|
||||
// We use TempDir instead of TempFile so we can control the filename.
|
||||
tmpDir, err := ioutil.TempDir(dir, "gomock_reflect_")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { os.RemoveAll(tmpDir) }()
|
||||
const progSource = "prog.go"
|
||||
var progBinary = "prog.bin"
|
||||
if runtime.GOOS == "windows" {
|
||||
// Windows won't execute a program unless it has a ".exe" suffix.
|
||||
progBinary += ".exe"
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program, 0600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmdArgs := []string{}
|
||||
cmdArgs = append(cmdArgs, "build")
|
||||
if *buildFlags != "" {
|
||||
cmdArgs = append(cmdArgs, *buildFlags)
|
||||
}
|
||||
cmdArgs = append(cmdArgs, "-o", progBinary, progSource)
|
||||
|
||||
// Build the program.
|
||||
cmd := exec.Command("go", cmdArgs...)
|
||||
cmd.Dir = tmpDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return run(filepath.Join(tmpDir, progBinary))
|
||||
}
|
||||
|
||||
func Reflect(importPath string, symbols []string) (*model.Package, error) {
|
||||
// TODO: sanity check arguments
|
||||
|
||||
if *execOnly != "" {
|
||||
return run(*execOnly)
|
||||
}
|
||||
|
||||
program, err := writeProgram(importPath, symbols)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if *progOnly {
|
||||
os.Stdout.Write(program)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
wd, _ := os.Getwd()
|
||||
|
||||
// Try to run the program in the same directory as the input package.
|
||||
if p, err := build.Import(importPath, wd, build.FindOnly); err == nil {
|
||||
dir := p.Dir
|
||||
if p, err := runInDir(program, dir); err == nil {
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Since that didn't work, try to run it in the current working directory.
|
||||
if p, err := runInDir(program, wd); err == nil {
|
||||
return p, nil
|
||||
}
|
||||
// Since that didn't work, try to run it in a standard temp directory.
|
||||
return runInDir(program, "")
|
||||
}
|
||||
|
||||
type reflectData struct {
|
||||
ImportPath string
|
||||
Symbols []string
|
||||
}
|
||||
|
||||
// This program reflects on an interface value, and prints the
|
||||
// gob encoding of a model.Package to standard output.
|
||||
// JSON doesn't work because of the model.Type interface.
|
||||
var reflectProgram = template.Must(template.New("program").Parse(`
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/mock/mockgen/model"
|
||||
|
||||
pkg_ {{printf "%q" .ImportPath}}
|
||||
)
|
||||
|
||||
func main() {
|
||||
its := []struct{
|
||||
sym string
|
||||
typ reflect.Type
|
||||
}{
|
||||
{{range .Symbols}}
|
||||
{ {{printf "%q" .}}, reflect.TypeOf((*pkg_.{{.}})(nil)).Elem()},
|
||||
{{end}}
|
||||
}
|
||||
pkg := &model.Package{
|
||||
// NOTE: This behaves contrary to documented behaviour if the
|
||||
// package name is not the final component of the import path.
|
||||
// The reflect package doesn't expose the package name, though.
|
||||
Name: path.Base({{printf "%q" .ImportPath}}),
|
||||
}
|
||||
|
||||
for _, it := range its {
|
||||
intf, err := model.InterfaceFromInterfaceType(it.typ)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Reflection: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
intf.Name = it.sym
|
||||
pkg.Interfaces = append(pkg.Interfaces, intf)
|
||||
}
|
||||
if err := gob.NewEncoder(os.Stdout).Encode(pkg); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "gob encode: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
`))
|
36
vendor/github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/README.md
generated
vendored
36
vendor/github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/README.md
generated
vendored
@@ -1,36 +0,0 @@
|
||||
Embedded interfaces in `aux_files` generate `unknown embedded interface XXX` errors.
|
||||
See below for example of the problem:
|
||||
```
|
||||
// source
|
||||
import (
|
||||
alias "some.org/package/imported"
|
||||
)
|
||||
|
||||
type Source interface {
|
||||
alias.Foreign
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
// some.org/package/imported
|
||||
type Foreign interface {
|
||||
Embedded
|
||||
}
|
||||
|
||||
type Embedded interface {}
|
||||
```
|
||||
|
||||
Attempting to generate a mock will result in an `unknown embedded interface Embedded`.
|
||||
The issue is that the `fileParser` stores `auxInterfaces` underneath the package name
|
||||
explicitly specified in the `aux_files` flag.
|
||||
|
||||
In the `parseInterface` method, there is an incorrect assumption about an embedded interface
|
||||
always being in the source file.
|
||||
```
|
||||
case *ast.Ident:
|
||||
// Embedded interface in this package.
|
||||
ei := p.auxInterfaces[""][v.String()]
|
||||
if ei == nil {
|
||||
return nil, p.errorf(v.Pos(), "unknown embedded interface %s", v.String())
|
||||
}
|
||||
```
|
18
vendor/github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/bugreport.go
generated
vendored
18
vendor/github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/bugreport.go
generated
vendored
@@ -1,18 +0,0 @@
|
||||
//go:generate mockgen -aux_files faux=faux/faux.go -destination bugreport_mock.go -package bugreport -source=bugreport.go Example
|
||||
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/faux"
|
||||
)
|
||||
|
||||
// Source is an interface w/ an embedded foreign interface
|
||||
type Source interface {
|
||||
faux.Foreign
|
||||
}
|
||||
|
||||
func CallForeignMethod(s Source) {
|
||||
log.Println(s.Method())
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: bugreport.go
|
||||
|
||||
// Package bugreport is a generated GoMock package.
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
faux "github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/faux"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockSource is a mock of Source interface
|
||||
type MockSource struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockSourceMockRecorder
|
||||
}
|
||||
|
||||
// MockSourceMockRecorder is the mock recorder for MockSource
|
||||
type MockSourceMockRecorder struct {
|
||||
mock *MockSource
|
||||
}
|
||||
|
||||
// NewMockSource creates a new mock instance
|
||||
func NewMockSource(ctrl *gomock.Controller) *MockSource {
|
||||
mock := &MockSource{ctrl: ctrl}
|
||||
mock.recorder = &MockSourceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockSource) EXPECT() *MockSourceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Method mocks base method
|
||||
func (m *MockSource) Method() faux.Return {
|
||||
ret := m.ctrl.Call(m, "Method")
|
||||
ret0, _ := ret[0].(faux.Return)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Method indicates an expected call of Method
|
||||
func (mr *MockSourceMockRecorder) Method() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Method", reflect.TypeOf((*MockSource)(nil).Method))
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// TestValidInterface assesses whether or not the generated mock is valid
|
||||
func TestValidInterface(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
s := NewMockSource(ctrl)
|
||||
s.EXPECT().Method().Return("")
|
||||
|
||||
CallForeignMethod(s)
|
||||
}
|
10
vendor/github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/faux/faux.go
generated
vendored
10
vendor/github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/faux/faux.go
generated
vendored
@@ -1,10 +0,0 @@
|
||||
package faux
|
||||
|
||||
type Foreign interface {
|
||||
Method() Return
|
||||
Embedded
|
||||
}
|
||||
|
||||
type Embedded interface{}
|
||||
|
||||
type Return interface{}
|
22
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/README.md
generated
vendored
22
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/README.md
generated
vendored
@@ -1,22 +0,0 @@
|
||||
# Tests for custom package names
|
||||
|
||||
This directory contains test for mockgen generating mocks when imported package
|
||||
name does not match import path suffix. For example, package with name "client"
|
||||
is located under import path "github.com/golang/mock/mockgen/tests/custom_package_name/client/v1".
|
||||
|
||||
Prior to this patch:
|
||||
|
||||
$ go generate greeter/greeter.go
|
||||
2018/03/05 22:44:52 Loading input failed: greeter.go:17:11: failed parsing returns: greeter.go:17:14: unknown package "client"
|
||||
greeter/greeter.go:1: running "mockgen": exit status 1
|
||||
|
||||
This can be fixed by manually providing `-imports` flag, like `-imports client=github.com/golang/mock/mockgen/tests/custom_package_name/client/v1`.
|
||||
But, mockgen should be able to automatically resolve package names in such situations.
|
||||
|
||||
With this patch applied:
|
||||
|
||||
$ go generate greeter/greeter.go
|
||||
$ echo $?
|
||||
0
|
||||
|
||||
Mockgen runs successfully, produced output is equal to [greeter_mock_test.go](greeter/greeter_mock_test.go) content.
|
13
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/client/v1/client.go
generated
vendored
13
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/client/v1/client.go
generated
vendored
@@ -1,13 +0,0 @@
|
||||
package client
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Client struct{}
|
||||
|
||||
func (c *Client) Greet(in GreetInput) string {
|
||||
return fmt.Sprintf("Hello, %s!", in.Name)
|
||||
}
|
||||
|
||||
type GreetInput struct {
|
||||
Name string
|
||||
}
|
31
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/greeter/greeter.go
generated
vendored
31
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/greeter/greeter.go
generated
vendored
@@ -1,31 +0,0 @@
|
||||
//go:generate mockgen -source greeter.go -destination greeter_mock_test.go -package greeter
|
||||
|
||||
package greeter
|
||||
|
||||
import (
|
||||
// stdlib import
|
||||
"fmt"
|
||||
|
||||
// non-matching import suffix and package name
|
||||
"github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
|
||||
|
||||
// matching import suffix and package name
|
||||
"github.com/golang/mock/mockgen/tests/custom_package_name/validator"
|
||||
)
|
||||
|
||||
type InputMaker interface {
|
||||
MakeInput() client.GreetInput
|
||||
}
|
||||
|
||||
type Greeter struct {
|
||||
InputMaker InputMaker
|
||||
Client *client.Client
|
||||
}
|
||||
|
||||
func (g *Greeter) Greet() (string, error) {
|
||||
in := g.InputMaker.MakeInput()
|
||||
if err := validator.Validate(in.Name); err != nil {
|
||||
return "", fmt.Errorf("validation failed: %v", err)
|
||||
}
|
||||
return g.Client.Greet(in), nil
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: greeter.go
|
||||
|
||||
// Package greeter is a generated GoMock package.
|
||||
package greeter
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
v1 "github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockInputMaker is a mock of InputMaker interface
|
||||
type MockInputMaker struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInputMakerMockRecorder
|
||||
}
|
||||
|
||||
// MockInputMakerMockRecorder is the mock recorder for MockInputMaker
|
||||
type MockInputMakerMockRecorder struct {
|
||||
mock *MockInputMaker
|
||||
}
|
||||
|
||||
// NewMockInputMaker creates a new mock instance
|
||||
func NewMockInputMaker(ctrl *gomock.Controller) *MockInputMaker {
|
||||
mock := &MockInputMaker{ctrl: ctrl}
|
||||
mock.recorder = &MockInputMakerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockInputMaker) EXPECT() *MockInputMakerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// MakeInput mocks base method
|
||||
func (m *MockInputMaker) MakeInput() v1.GreetInput {
|
||||
ret := m.ctrl.Call(m, "MakeInput")
|
||||
ret0, _ := ret[0].(v1.GreetInput)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// MakeInput indicates an expected call of MakeInput
|
||||
func (mr *MockInputMakerMockRecorder) MakeInput() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MakeInput", reflect.TypeOf((*MockInputMaker)(nil).MakeInput))
|
||||
}
|
37
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/greeter/greeter_test.go
generated
vendored
37
vendor/github.com/golang/mock/mockgen/tests/custom_package_name/greeter/greeter_test.go
generated
vendored
@@ -1,37 +0,0 @@
|
||||
package greeter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
|
||||
)
|
||||
|
||||
func TestGreeter_Greet(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
input := client.GreetInput{
|
||||
Name: "Foo",
|
||||
}
|
||||
|
||||
inputMaker := NewMockInputMaker(ctrl)
|
||||
inputMaker.EXPECT().
|
||||
MakeInput().
|
||||
Return(input)
|
||||
|
||||
g := &Greeter{
|
||||
InputMaker: inputMaker,
|
||||
Client: &client.Client{},
|
||||
}
|
||||
|
||||
greeting, err := g.Greet()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
expected := "Hello, Foo!"
|
||||
if greeting != expected {
|
||||
t.Fatalf("Expected greeting to be %v but got %v", expected, greeting)
|
||||
}
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
package validator
|
||||
|
||||
func Validate(s string) error {
|
||||
return nil
|
||||
}
|
4
vendor/github.com/golang/mock/mockgen/tests/empty_interface/input.go
generated
vendored
4
vendor/github.com/golang/mock/mockgen/tests/empty_interface/input.go
generated
vendored
@@ -1,4 +0,0 @@
|
||||
//go:generate mockgen -package empty_interface -destination mock.go -source input.go
|
||||
package empty_interface
|
||||
|
||||
type Empty interface{}
|
32
vendor/github.com/golang/mock/mockgen/tests/empty_interface/mock.go
generated
vendored
32
vendor/github.com/golang/mock/mockgen/tests/empty_interface/mock.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: input.go
|
||||
|
||||
// Package empty_interface is a generated GoMock package.
|
||||
package empty_interface
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockEmpty is a mock of Empty interface
|
||||
type MockEmpty struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockEmptyMockRecorder
|
||||
}
|
||||
|
||||
// MockEmptyMockRecorder is the mock recorder for MockEmpty
|
||||
type MockEmptyMockRecorder struct {
|
||||
mock *MockEmpty
|
||||
}
|
||||
|
||||
// NewMockEmpty creates a new mock instance
|
||||
func NewMockEmpty(ctrl *gomock.Controller) *MockEmpty {
|
||||
mock := &MockEmpty{ctrl: ctrl}
|
||||
mock.recorder = &MockEmptyMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockEmpty) EXPECT() *MockEmptyMockRecorder {
|
||||
return m.recorder
|
||||
}
|
26
vendor/github.com/golang/mock/mockgen/tests/generated_identifier_conflict/README.md
generated
vendored
26
vendor/github.com/golang/mock/mockgen/tests/generated_identifier_conflict/README.md
generated
vendored
@@ -1,26 +0,0 @@
|
||||
The generated mock methods use some hardcoded variable/receiver names that can
|
||||
have conflicts with the argument names that are defined by the code for which
|
||||
the mock is generated when using the source generation method.
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type Example interface {
|
||||
Method(_m, _mr, m, mr int)
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// Method mocks base method
|
||||
func (_m *MockExample) Method(_m int, _mr int, m int, mr int) {
|
||||
_m.ctrl.Call(_m, "Method", _m, _mr, m, mr)
|
||||
}
|
||||
```
|
||||
|
||||
In the above example one of the interface method parameters is called `_m`
|
||||
but unfortunately the generated receiver name is also called `_m` so the
|
||||
mock code won't compile.
|
||||
|
||||
The generator has to make sure that generated identifiers (e.g.: the receiver
|
||||
names) are always different from the arg names that might come from external
|
||||
sources.
|
16
vendor/github.com/golang/mock/mockgen/tests/generated_identifier_conflict/bugreport.go
generated
vendored
16
vendor/github.com/golang/mock/mockgen/tests/generated_identifier_conflict/bugreport.go
generated
vendored
@@ -1,16 +0,0 @@
|
||||
//go:generate mockgen -destination bugreport_mock.go -package bugreport -source=bugreport.go
|
||||
|
||||
package bugreport
|
||||
|
||||
type Example interface {
|
||||
// _m and _mr were used by the buggy code: the '_' prefix was there hoping
|
||||
// that no one will use method argument names starting with '_' reducing
|
||||
// the chance of collision with generated identifiers.
|
||||
// m and mr are used by the bugfixed new code, the '_' prefix has been
|
||||
// removed because the new code generator changes the names of the
|
||||
// generated identifiers in case they would collide with identifiers
|
||||
// coming from argument names.
|
||||
Method(_m, _mr, m, mr int)
|
||||
|
||||
VarargMethod(_s, _x, a, ret int, varargs ...int)
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: bugreport.go
|
||||
|
||||
// Package bugreport is a generated GoMock package.
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockExample is a mock of Example interface
|
||||
type MockExample struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockExampleMockRecorder
|
||||
}
|
||||
|
||||
// MockExampleMockRecorder is the mock recorder for MockExample
|
||||
type MockExampleMockRecorder struct {
|
||||
mock *MockExample
|
||||
}
|
||||
|
||||
// NewMockExample creates a new mock instance
|
||||
func NewMockExample(ctrl *gomock.Controller) *MockExample {
|
||||
mock := &MockExample{ctrl: ctrl}
|
||||
mock.recorder = &MockExampleMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockExample) EXPECT() *MockExampleMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Method mocks base method
|
||||
func (m_2 *MockExample) Method(_m, _mr, m, mr int) {
|
||||
m_2.ctrl.Call(m_2, "Method", _m, _mr, m, mr)
|
||||
}
|
||||
|
||||
// Method indicates an expected call of Method
|
||||
func (mr_2 *MockExampleMockRecorder) Method(_m, _mr, m, mr interface{}) *gomock.Call {
|
||||
return mr_2.mock.ctrl.RecordCallWithMethodType(mr_2.mock, "Method", reflect.TypeOf((*MockExample)(nil).Method), _m, _mr, m, mr)
|
||||
}
|
||||
|
||||
// VarargMethod mocks base method
|
||||
func (m *MockExample) VarargMethod(_s, _x, a, ret int, varargs ...int) {
|
||||
varargs_2 := []interface{}{_s, _x, a, ret}
|
||||
for _, a_2 := range varargs {
|
||||
varargs_2 = append(varargs_2, a_2)
|
||||
}
|
||||
m.ctrl.Call(m, "VarargMethod", varargs_2...)
|
||||
}
|
||||
|
||||
// VarargMethod indicates an expected call of VarargMethod
|
||||
func (mr *MockExampleMockRecorder) VarargMethod(_s, _x, a, ret interface{}, varargs ...interface{}) *gomock.Call {
|
||||
varargs_2 := append([]interface{}{_s, _x, a, ret}, varargs...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VarargMethod", reflect.TypeOf((*MockExample)(nil).VarargMethod), varargs_2...)
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
"github.com/golang/mock/gomock"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExample_Method(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
m := NewMockExample(ctrl)
|
||||
m.EXPECT().Method(1, 2, 3, 4)
|
||||
|
||||
m.Method(1, 2, 3, 4)
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestExample_VarargMethod(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
m := NewMockExample(ctrl)
|
||||
m.EXPECT().VarargMethod(1, 2, 3, 4, 6, 7)
|
||||
|
||||
m.VarargMethod(1, 2, 3, 4, 6, 7)
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
3
vendor/github.com/golang/mock/mockgen/tests/import_source/Readme.md
generated
vendored
3
vendor/github.com/golang/mock/mockgen/tests/import_source/Readme.md
generated
vendored
@@ -1,3 +0,0 @@
|
||||
Test the case where the generated code uses a type defined in the source package (in source mode). There are two test cases:
|
||||
- the output is in a new package
|
||||
- the output is in the same package as the input
|
9
vendor/github.com/golang/mock/mockgen/tests/import_source/definition/source.go
generated
vendored
9
vendor/github.com/golang/mock/mockgen/tests/import_source/definition/source.go
generated
vendored
@@ -1,9 +0,0 @@
|
||||
//go:generate mockgen -destination ../source_mock.go -source=source.go
|
||||
//go:generate mockgen -package source -destination source_mock.go -source=source.go
|
||||
package source
|
||||
|
||||
type X struct{}
|
||||
|
||||
type S interface {
|
||||
F(X)
|
||||
}
|
43
vendor/github.com/golang/mock/mockgen/tests/import_source/definition/source_mock.go
generated
vendored
43
vendor/github.com/golang/mock/mockgen/tests/import_source/definition/source_mock.go
generated
vendored
@@ -1,43 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: source.go
|
||||
|
||||
// Package source is a generated GoMock package.
|
||||
package source
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockS is a mock of S interface
|
||||
type MockS struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockSMockRecorder
|
||||
}
|
||||
|
||||
// MockSMockRecorder is the mock recorder for MockS
|
||||
type MockSMockRecorder struct {
|
||||
mock *MockS
|
||||
}
|
||||
|
||||
// NewMockS creates a new mock instance
|
||||
func NewMockS(ctrl *gomock.Controller) *MockS {
|
||||
mock := &MockS{ctrl: ctrl}
|
||||
mock.recorder = &MockSMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockS) EXPECT() *MockSMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// F mocks base method
|
||||
func (m *MockS) F(arg0 X) {
|
||||
m.ctrl.Call(m, "F", arg0)
|
||||
}
|
||||
|
||||
// F indicates an expected call of F
|
||||
func (mr *MockSMockRecorder) F(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockS)(nil).F), arg0)
|
||||
}
|
44
vendor/github.com/golang/mock/mockgen/tests/import_source/source_mock.go
generated
vendored
44
vendor/github.com/golang/mock/mockgen/tests/import_source/source_mock.go
generated
vendored
@@ -1,44 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: source.go
|
||||
|
||||
// Package mock_source is a generated GoMock package.
|
||||
package mock_source
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
definition "github.com/golang/mock/mockgen/tests/import_source/definition"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockS is a mock of S interface
|
||||
type MockS struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockSMockRecorder
|
||||
}
|
||||
|
||||
// MockSMockRecorder is the mock recorder for MockS
|
||||
type MockSMockRecorder struct {
|
||||
mock *MockS
|
||||
}
|
||||
|
||||
// NewMockS creates a new mock instance
|
||||
func NewMockS(ctrl *gomock.Controller) *MockS {
|
||||
mock := &MockS{ctrl: ctrl}
|
||||
mock.recorder = &MockSMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockS) EXPECT() *MockSMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// F mocks base method
|
||||
func (m *MockS) F(arg0 definition.X) {
|
||||
m.ctrl.Call(m, "F", arg0)
|
||||
}
|
||||
|
||||
// F indicates an expected call of F
|
||||
func (mr *MockSMockRecorder) F(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockS)(nil).F), arg0)
|
||||
}
|
3
vendor/github.com/golang/mock/mockgen/tests/internal_pkg/generate.go
generated
vendored
3
vendor/github.com/golang/mock/mockgen/tests/internal_pkg/generate.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
//go:generate mockgen -destination subdir/internal/pkg/reflect_output/mock.go github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg Intf
|
||||
//go:generate mockgen -source subdir/internal/pkg/input.go -destination subdir/internal/pkg/source_output/mock.go
|
||||
package test
|
@@ -1,9 +0,0 @@
|
||||
package pkg
|
||||
|
||||
type Arg interface {
|
||||
Foo() int
|
||||
}
|
||||
|
||||
type Intf interface {
|
||||
F() Arg
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg (interfaces: Intf)
|
||||
|
||||
// Package mock_pkg is a generated GoMock package.
|
||||
package mock_pkg
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
pkg "github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockIntf is a mock of Intf interface
|
||||
type MockIntf struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockIntfMockRecorder
|
||||
}
|
||||
|
||||
// MockIntfMockRecorder is the mock recorder for MockIntf
|
||||
type MockIntfMockRecorder struct {
|
||||
mock *MockIntf
|
||||
}
|
||||
|
||||
// NewMockIntf creates a new mock instance
|
||||
func NewMockIntf(ctrl *gomock.Controller) *MockIntf {
|
||||
mock := &MockIntf{ctrl: ctrl}
|
||||
mock.recorder = &MockIntfMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockIntf) EXPECT() *MockIntfMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// F mocks base method
|
||||
func (m *MockIntf) F() pkg.Arg {
|
||||
ret := m.ctrl.Call(m, "F")
|
||||
ret0, _ := ret[0].(pkg.Arg)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// F indicates an expected call of F
|
||||
func (mr *MockIntfMockRecorder) F() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockIntf)(nil).F))
|
||||
}
|
@@ -1,81 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: subdir/internal/pkg/input.go
|
||||
|
||||
// Package mock_pkg is a generated GoMock package.
|
||||
package mock_pkg
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
pkg "github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockArg is a mock of Arg interface
|
||||
type MockArg struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockArgMockRecorder
|
||||
}
|
||||
|
||||
// MockArgMockRecorder is the mock recorder for MockArg
|
||||
type MockArgMockRecorder struct {
|
||||
mock *MockArg
|
||||
}
|
||||
|
||||
// NewMockArg creates a new mock instance
|
||||
func NewMockArg(ctrl *gomock.Controller) *MockArg {
|
||||
mock := &MockArg{ctrl: ctrl}
|
||||
mock.recorder = &MockArgMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockArg) EXPECT() *MockArgMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Foo mocks base method
|
||||
func (m *MockArg) Foo() int {
|
||||
ret := m.ctrl.Call(m, "Foo")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Foo indicates an expected call of Foo
|
||||
func (mr *MockArgMockRecorder) Foo() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockArg)(nil).Foo))
|
||||
}
|
||||
|
||||
// MockIntf is a mock of Intf interface
|
||||
type MockIntf struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockIntfMockRecorder
|
||||
}
|
||||
|
||||
// MockIntfMockRecorder is the mock recorder for MockIntf
|
||||
type MockIntfMockRecorder struct {
|
||||
mock *MockIntf
|
||||
}
|
||||
|
||||
// NewMockIntf creates a new mock instance
|
||||
func NewMockIntf(ctrl *gomock.Controller) *MockIntf {
|
||||
mock := &MockIntf{ctrl: ctrl}
|
||||
mock.recorder = &MockIntfMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockIntf) EXPECT() *MockIntfMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// F mocks base method
|
||||
func (m *MockIntf) F() pkg.Arg {
|
||||
ret := m.ctrl.Call(m, "F")
|
||||
ret0, _ := ret[0].(pkg.Arg)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// F indicates an expected call of F
|
||||
func (mr *MockIntfMockRecorder) F() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockIntf)(nil).F))
|
||||
}
|
1
vendor/github.com/golang/mock/mockgen/tests/unexported_method/README.md
generated
vendored
1
vendor/github.com/golang/mock/mockgen/tests/unexported_method/README.md
generated
vendored
@@ -1 +0,0 @@
|
||||
From #52, this tests an unexported method in the mocked interface.
|
15
vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport.go
generated
vendored
15
vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport.go
generated
vendored
@@ -1,15 +0,0 @@
|
||||
//go:generate mockgen -destination bugreport_mock.go -package bugreport -source=bugreport.go Example
|
||||
|
||||
package bugreport
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Example is an interface with a non exported method
|
||||
type Example interface {
|
||||
someMethod(string) string
|
||||
}
|
||||
|
||||
// CallExample is a simple function that uses the interface
|
||||
func CallExample(e Example) {
|
||||
fmt.Println(e.someMethod("test"))
|
||||
}
|
45
vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_mock.go
generated
vendored
45
vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_mock.go
generated
vendored
@@ -1,45 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: bugreport.go
|
||||
|
||||
// Package bugreport is a generated GoMock package.
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockExample is a mock of Example interface
|
||||
type MockExample struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockExampleMockRecorder
|
||||
}
|
||||
|
||||
// MockExampleMockRecorder is the mock recorder for MockExample
|
||||
type MockExampleMockRecorder struct {
|
||||
mock *MockExample
|
||||
}
|
||||
|
||||
// NewMockExample creates a new mock instance
|
||||
func NewMockExample(ctrl *gomock.Controller) *MockExample {
|
||||
mock := &MockExample{ctrl: ctrl}
|
||||
mock.recorder = &MockExampleMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockExample) EXPECT() *MockExampleMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// someMethod mocks base method
|
||||
func (m *MockExample) someMethod(arg0 string) string {
|
||||
ret := m.ctrl.Call(m, "someMethod", arg0)
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// someMethod indicates an expected call of someMethod
|
||||
func (mr *MockExampleMockRecorder) someMethod(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "someMethod", reflect.TypeOf((*MockExample)(nil).someMethod), arg0)
|
||||
}
|
17
vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_test.go
generated
vendored
17
vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_test.go
generated
vendored
@@ -1,17 +0,0 @@
|
||||
package bugreport
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
func TestCallExample(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
e := NewMockExample(ctrl)
|
||||
e.EXPECT().someMethod(gomock.Any()).Return("it works!")
|
||||
|
||||
CallExample(e)
|
||||
}
|
2
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/README.md
generated
vendored
2
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/README.md
generated
vendored
@@ -1,2 +0,0 @@
|
||||
Test for [Issue#4](https://github.com/golang/mock/issues/4).
|
||||
Also see discussion on [#28](https://github.com/golang/mock/pull/28).
|
4
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/doc.go
generated
vendored
4
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/doc.go
generated
vendored
@@ -1,4 +0,0 @@
|
||||
package vendor_dep
|
||||
|
||||
//go:generate mockgen -package vendor_dep -destination mock.go github.com/golang/mock/mockgen/tests/vendor_dep VendorsDep
|
||||
//go:generate mockgen -destination source_mock_package/mock.go -source=vendor_dep.go
|
46
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/mock.go
generated
vendored
46
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/mock.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/golang/mock/mockgen/tests/vendor_dep (interfaces: VendorsDep)
|
||||
|
||||
// Package vendor_dep is a generated GoMock package.
|
||||
package vendor_dep
|
||||
|
||||
import (
|
||||
a "a"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockVendorsDep is a mock of VendorsDep interface
|
||||
type MockVendorsDep struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockVendorsDepMockRecorder
|
||||
}
|
||||
|
||||
// MockVendorsDepMockRecorder is the mock recorder for MockVendorsDep
|
||||
type MockVendorsDepMockRecorder struct {
|
||||
mock *MockVendorsDep
|
||||
}
|
||||
|
||||
// NewMockVendorsDep creates a new mock instance
|
||||
func NewMockVendorsDep(ctrl *gomock.Controller) *MockVendorsDep {
|
||||
mock := &MockVendorsDep{ctrl: ctrl}
|
||||
mock.recorder = &MockVendorsDepMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockVendorsDep) EXPECT() *MockVendorsDepMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Foo mocks base method
|
||||
func (m *MockVendorsDep) Foo() a.Ifc {
|
||||
ret := m.ctrl.Call(m, "Foo")
|
||||
ret0, _ := ret[0].(a.Ifc)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Foo indicates an expected call of Foo
|
||||
func (mr *MockVendorsDepMockRecorder) Foo() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockVendorsDep)(nil).Foo))
|
||||
}
|
46
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/source_mock_package/mock.go
generated
vendored
46
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/source_mock_package/mock.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: vendor_dep.go
|
||||
|
||||
// Package mock_vendor_dep is a generated GoMock package.
|
||||
package mock_vendor_dep
|
||||
|
||||
import (
|
||||
a "a"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockVendorsDep is a mock of VendorsDep interface
|
||||
type MockVendorsDep struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockVendorsDepMockRecorder
|
||||
}
|
||||
|
||||
// MockVendorsDepMockRecorder is the mock recorder for MockVendorsDep
|
||||
type MockVendorsDepMockRecorder struct {
|
||||
mock *MockVendorsDep
|
||||
}
|
||||
|
||||
// NewMockVendorsDep creates a new mock instance
|
||||
func NewMockVendorsDep(ctrl *gomock.Controller) *MockVendorsDep {
|
||||
mock := &MockVendorsDep{ctrl: ctrl}
|
||||
mock.recorder = &MockVendorsDepMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockVendorsDep) EXPECT() *MockVendorsDepMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Foo mocks base method
|
||||
func (m *MockVendorsDep) Foo() a.Ifc {
|
||||
ret := m.ctrl.Call(m, "Foo")
|
||||
ret0, _ := ret[0].(a.Ifc)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Foo indicates an expected call of Foo
|
||||
func (mr *MockVendorsDepMockRecorder) Foo() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockVendorsDep)(nil).Foo))
|
||||
}
|
7
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/vendor_dep.go
generated
vendored
7
vendor/github.com/golang/mock/mockgen/tests/vendor_dep/vendor_dep.go
generated
vendored
@@ -1,7 +0,0 @@
|
||||
package vendor_dep
|
||||
|
||||
import "a"
|
||||
|
||||
type VendorsDep interface {
|
||||
Foo() a.Ifc
|
||||
}
|
1
vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/README.md
generated
vendored
1
vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/README.md
generated
vendored
@@ -1 +0,0 @@
|
||||
Test for [Issue#4](https://github.com/golang/mock/issues/4).
|
3
vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/doc.go
generated
vendored
3
vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/doc.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
package vendor_pkg
|
||||
|
||||
//go:generate mockgen -destination mock.go -package vendor_pkg a Ifc
|
99
vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/mock.go
generated
vendored
99
vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/mock.go
generated
vendored
@@ -1,99 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: a (interfaces: Ifc)
|
||||
|
||||
// Package vendor_pkg is a generated GoMock package.
|
||||
package vendor_pkg
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockIfc is a mock of Ifc interface
|
||||
type MockIfc struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockIfcMockRecorder
|
||||
}
|
||||
|
||||
// MockIfcMockRecorder is the mock recorder for MockIfc
|
||||
type MockIfcMockRecorder struct {
|
||||
mock *MockIfc
|
||||
}
|
||||
|
||||
// NewMockIfc creates a new mock instance
|
||||
func NewMockIfc(ctrl *gomock.Controller) *MockIfc {
|
||||
mock := &MockIfc{ctrl: ctrl}
|
||||
mock.recorder = &MockIfcMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockIfc) EXPECT() *MockIfcMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// A mocks base method
|
||||
func (m *MockIfc) A(arg0 string) string {
|
||||
ret := m.ctrl.Call(m, "A", arg0)
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// A indicates an expected call of A
|
||||
func (mr *MockIfcMockRecorder) A(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "A", reflect.TypeOf((*MockIfc)(nil).A), arg0)
|
||||
}
|
||||
|
||||
// B mocks base method
|
||||
func (m *MockIfc) B(arg0 int) int {
|
||||
ret := m.ctrl.Call(m, "B", arg0)
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// B indicates an expected call of B
|
||||
func (mr *MockIfcMockRecorder) B(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "B", reflect.TypeOf((*MockIfc)(nil).B), arg0)
|
||||
}
|
||||
|
||||
// C mocks base method
|
||||
func (m *MockIfc) C(arg0 chan int) chan int {
|
||||
ret := m.ctrl.Call(m, "C", arg0)
|
||||
ret0, _ := ret[0].(chan int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// C indicates an expected call of C
|
||||
func (mr *MockIfcMockRecorder) C(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "C", reflect.TypeOf((*MockIfc)(nil).C), arg0)
|
||||
}
|
||||
|
||||
// D mocks base method
|
||||
func (m *MockIfc) D(arg0 interface{}) {
|
||||
m.ctrl.Call(m, "D", arg0)
|
||||
}
|
||||
|
||||
// D indicates an expected call of D
|
||||
func (mr *MockIfcMockRecorder) D(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "D", reflect.TypeOf((*MockIfc)(nil).D), arg0)
|
||||
}
|
||||
|
||||
// E mocks base method
|
||||
func (m *MockIfc) E(arg0 map[string]interface{}) {
|
||||
m.ctrl.Call(m, "E", arg0)
|
||||
}
|
||||
|
||||
// E indicates an expected call of E
|
||||
func (mr *MockIfcMockRecorder) E(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "E", reflect.TypeOf((*MockIfc)(nil).E), arg0)
|
||||
}
|
||||
|
||||
// F mocks base method
|
||||
func (m *MockIfc) F(arg0 []float64) {
|
||||
m.ctrl.Call(m, "F", arg0)
|
||||
}
|
||||
|
||||
// F indicates an expected call of F
|
||||
func (mr *MockIfcMockRecorder) F(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockIfc)(nil).F), arg0)
|
||||
}
|
16
vendor/github.com/golang/mock/sample/README.md
generated
vendored
16
vendor/github.com/golang/mock/sample/README.md
generated
vendored
@@ -1,16 +0,0 @@
|
||||
This directory contains an example of a package containing a non-trivial
|
||||
interface that can be mocked with GoMock. The interesting files are:
|
||||
|
||||
* `user.go`: Source code for the sample package, containing interfaces to be
|
||||
mocked. This file depends on the packages named imp[1-4] for various things.
|
||||
|
||||
* `user_test.go`: A test for the sample package, in which mocks of the
|
||||
interfaces from `user.go` are used. This demonstrates how to create mock
|
||||
objects, set up expectations, and so on.
|
||||
|
||||
* `mock_user/mock_user.go`: The generated mock code. See ../update_mocks.sh
|
||||
for the command used to generate it.
|
||||
|
||||
To run the test,
|
||||
|
||||
go test github.com/golang/mock/sample
|
8
vendor/github.com/golang/mock/sample/concurrent/concurrent.go
generated
vendored
8
vendor/github.com/golang/mock/sample/concurrent/concurrent.go
generated
vendored
@@ -1,8 +0,0 @@
|
||||
//go:generate mockgen -destination mock/concurrent_mock.go github.com/golang/mock/sample/concurrent Math
|
||||
|
||||
// Package concurrent demonstrates how to use gomock with goroutines.
|
||||
package concurrent
|
||||
|
||||
type Math interface {
|
||||
Sum(a, b int) int
|
||||
}
|
46
vendor/github.com/golang/mock/sample/concurrent/concurrent_test.go
generated
vendored
46
vendor/github.com/golang/mock/sample/concurrent/concurrent_test.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
mock "github.com/golang/mock/sample/concurrent/mock"
|
||||
)
|
||||
|
||||
func call(ctx context.Context, m Math) (int, error) {
|
||||
result := make(chan int)
|
||||
go func() {
|
||||
result <- m.Sum(1, 2)
|
||||
close(result)
|
||||
}()
|
||||
select {
|
||||
case r := <-result:
|
||||
return r, nil
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// testConcurrentFails is expected to fail (and is disabled). It
|
||||
// demonstrates how to use gomock.WithContext to interrupt the test
|
||||
// from a different goroutine.
|
||||
func testConcurrentFails(t *testing.T) {
|
||||
ctrl, ctx := gomock.WithContext(context.Background(), t)
|
||||
defer ctrl.Finish()
|
||||
m := mock.NewMockMath(ctrl)
|
||||
if _, err := call(ctx, m); err != nil {
|
||||
t.Error("call failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcurrentWorks(t *testing.T) {
|
||||
ctrl, ctx := gomock.WithContext(context.Background(), t)
|
||||
defer ctrl.Finish()
|
||||
m := mock.NewMockMath(ctrl)
|
||||
m.EXPECT().Sum(1, 2).Return(3)
|
||||
if _, err := call(ctx, m); err != nil {
|
||||
t.Error("call failed:", err)
|
||||
}
|
||||
}
|
45
vendor/github.com/golang/mock/sample/concurrent/mock/concurrent_mock.go
generated
vendored
45
vendor/github.com/golang/mock/sample/concurrent/mock/concurrent_mock.go
generated
vendored
@@ -1,45 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/golang/mock/sample/concurrent (interfaces: Math)
|
||||
|
||||
// Package mock_concurrent is a generated GoMock package.
|
||||
package mock_concurrent
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockMath is a mock of Math interface
|
||||
type MockMath struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockMathMockRecorder
|
||||
}
|
||||
|
||||
// MockMathMockRecorder is the mock recorder for MockMath
|
||||
type MockMathMockRecorder struct {
|
||||
mock *MockMath
|
||||
}
|
||||
|
||||
// NewMockMath creates a new mock instance
|
||||
func NewMockMath(ctrl *gomock.Controller) *MockMath {
|
||||
mock := &MockMath{ctrl: ctrl}
|
||||
mock.recorder = &MockMathMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockMath) EXPECT() *MockMathMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Sum mocks base method
|
||||
func (m *MockMath) Sum(arg0, arg1 int) int {
|
||||
ret := m.ctrl.Call(m, "Sum", arg0, arg1)
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Sum indicates an expected call of Sum
|
||||
func (mr *MockMathMockRecorder) Sum(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sum", reflect.TypeOf((*MockMath)(nil).Sum), arg0, arg1)
|
||||
}
|
17
vendor/github.com/golang/mock/sample/imp1/imp1.go
generated
vendored
17
vendor/github.com/golang/mock/sample/imp1/imp1.go
generated
vendored
@@ -1,17 +0,0 @@
|
||||
package imp1
|
||||
|
||||
import "bufio"
|
||||
|
||||
type Imp1 struct{}
|
||||
|
||||
type ImpT int
|
||||
|
||||
type ForeignEmbedded interface {
|
||||
// The return value here also makes sure that
|
||||
// the generated mock picks up the "bufio" import.
|
||||
ForeignEmbeddedMethod() *bufio.Reader
|
||||
|
||||
// This method uses a type in this package,
|
||||
// which should be qualified when this interface is embedded.
|
||||
ImplicitPackage(s string, t ImpT, st []ImpT, pt *ImpT, ct chan ImpT)
|
||||
}
|
3
vendor/github.com/golang/mock/sample/imp2/imp2.go
generated
vendored
3
vendor/github.com/golang/mock/sample/imp2/imp2.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
package imp2
|
||||
|
||||
type Imp2 struct{}
|
3
vendor/github.com/golang/mock/sample/imp3/imp3.go
generated
vendored
3
vendor/github.com/golang/mock/sample/imp3/imp3.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
package imp3
|
||||
|
||||
type Imp3 struct{}
|
3
vendor/github.com/golang/mock/sample/imp4/imp4.go
generated
vendored
3
vendor/github.com/golang/mock/sample/imp4/imp4.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
package imp_four
|
||||
|
||||
type Imp4 struct{}
|
384
vendor/github.com/golang/mock/sample/mock_user/mock_user.go
generated
vendored
384
vendor/github.com/golang/mock/sample/mock_user/mock_user.go
generated
vendored
@@ -1,384 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/golang/mock/sample (interfaces: Index,Embed,Embedded)
|
||||
|
||||
// Package mock_sample is a generated GoMock package.
|
||||
package mock_sample
|
||||
|
||||
import (
|
||||
bufio "bufio"
|
||||
bytes "bytes"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
imp1 "github.com/golang/mock/sample/imp1"
|
||||
imp2 "github.com/golang/mock/sample/imp2"
|
||||
imp3 "github.com/golang/mock/sample/imp3"
|
||||
imp4 "github.com/golang/mock/sample/imp4"
|
||||
hash "hash"
|
||||
template "html/template"
|
||||
io "io"
|
||||
http "net/http"
|
||||
reflect "reflect"
|
||||
template0 "text/template"
|
||||
)
|
||||
|
||||
// MockIndex is a mock of Index interface
|
||||
type MockIndex struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockIndexMockRecorder
|
||||
}
|
||||
|
||||
// MockIndexMockRecorder is the mock recorder for MockIndex
|
||||
type MockIndexMockRecorder struct {
|
||||
mock *MockIndex
|
||||
}
|
||||
|
||||
// NewMockIndex creates a new mock instance
|
||||
func NewMockIndex(ctrl *gomock.Controller) *MockIndex {
|
||||
mock := &MockIndex{ctrl: ctrl}
|
||||
mock.recorder = &MockIndexMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockIndex) EXPECT() *MockIndexMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Anon mocks base method
|
||||
func (m *MockIndex) Anon(arg0 string) {
|
||||
m.ctrl.Call(m, "Anon", arg0)
|
||||
}
|
||||
|
||||
// Anon indicates an expected call of Anon
|
||||
func (mr *MockIndexMockRecorder) Anon(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Anon", reflect.TypeOf((*MockIndex)(nil).Anon), arg0)
|
||||
}
|
||||
|
||||
// Chan mocks base method
|
||||
func (m *MockIndex) Chan(arg0 chan int, arg1 chan<- hash.Hash) {
|
||||
m.ctrl.Call(m, "Chan", arg0, arg1)
|
||||
}
|
||||
|
||||
// Chan indicates an expected call of Chan
|
||||
func (mr *MockIndexMockRecorder) Chan(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chan", reflect.TypeOf((*MockIndex)(nil).Chan), arg0, arg1)
|
||||
}
|
||||
|
||||
// ConcreteRet mocks base method
|
||||
func (m *MockIndex) ConcreteRet() chan<- bool {
|
||||
ret := m.ctrl.Call(m, "ConcreteRet")
|
||||
ret0, _ := ret[0].(chan<- bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ConcreteRet indicates an expected call of ConcreteRet
|
||||
func (mr *MockIndexMockRecorder) ConcreteRet() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConcreteRet", reflect.TypeOf((*MockIndex)(nil).ConcreteRet))
|
||||
}
|
||||
|
||||
// Ellip mocks base method
|
||||
func (m *MockIndex) Ellip(arg0 string, arg1 ...interface{}) {
|
||||
varargs := []interface{}{arg0}
|
||||
for _, a := range arg1 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
m.ctrl.Call(m, "Ellip", varargs...)
|
||||
}
|
||||
|
||||
// Ellip indicates an expected call of Ellip
|
||||
func (mr *MockIndexMockRecorder) Ellip(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
|
||||
varargs := append([]interface{}{arg0}, arg1...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ellip", reflect.TypeOf((*MockIndex)(nil).Ellip), varargs...)
|
||||
}
|
||||
|
||||
// EllipOnly mocks base method
|
||||
func (m *MockIndex) EllipOnly(arg0 ...string) {
|
||||
varargs := []interface{}{}
|
||||
for _, a := range arg0 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
m.ctrl.Call(m, "EllipOnly", varargs...)
|
||||
}
|
||||
|
||||
// EllipOnly indicates an expected call of EllipOnly
|
||||
func (mr *MockIndexMockRecorder) EllipOnly(arg0 ...interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EllipOnly", reflect.TypeOf((*MockIndex)(nil).EllipOnly), arg0...)
|
||||
}
|
||||
|
||||
// ForeignFour mocks base method
|
||||
func (m *MockIndex) ForeignFour(arg0 imp4.Imp4) {
|
||||
m.ctrl.Call(m, "ForeignFour", arg0)
|
||||
}
|
||||
|
||||
// ForeignFour indicates an expected call of ForeignFour
|
||||
func (mr *MockIndexMockRecorder) ForeignFour(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForeignFour", reflect.TypeOf((*MockIndex)(nil).ForeignFour), arg0)
|
||||
}
|
||||
|
||||
// ForeignOne mocks base method
|
||||
func (m *MockIndex) ForeignOne(arg0 imp1.Imp1) {
|
||||
m.ctrl.Call(m, "ForeignOne", arg0)
|
||||
}
|
||||
|
||||
// ForeignOne indicates an expected call of ForeignOne
|
||||
func (mr *MockIndexMockRecorder) ForeignOne(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForeignOne", reflect.TypeOf((*MockIndex)(nil).ForeignOne), arg0)
|
||||
}
|
||||
|
||||
// ForeignThree mocks base method
|
||||
func (m *MockIndex) ForeignThree(arg0 imp3.Imp3) {
|
||||
m.ctrl.Call(m, "ForeignThree", arg0)
|
||||
}
|
||||
|
||||
// ForeignThree indicates an expected call of ForeignThree
|
||||
func (mr *MockIndexMockRecorder) ForeignThree(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForeignThree", reflect.TypeOf((*MockIndex)(nil).ForeignThree), arg0)
|
||||
}
|
||||
|
||||
// ForeignTwo mocks base method
|
||||
func (m *MockIndex) ForeignTwo(arg0 imp2.Imp2) {
|
||||
m.ctrl.Call(m, "ForeignTwo", arg0)
|
||||
}
|
||||
|
||||
// ForeignTwo indicates an expected call of ForeignTwo
|
||||
func (mr *MockIndexMockRecorder) ForeignTwo(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForeignTwo", reflect.TypeOf((*MockIndex)(nil).ForeignTwo), arg0)
|
||||
}
|
||||
|
||||
// Func mocks base method
|
||||
func (m *MockIndex) Func(arg0 func(http.Request) (int, bool)) {
|
||||
m.ctrl.Call(m, "Func", arg0)
|
||||
}
|
||||
|
||||
// Func indicates an expected call of Func
|
||||
func (mr *MockIndexMockRecorder) Func(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Func", reflect.TypeOf((*MockIndex)(nil).Func), arg0)
|
||||
}
|
||||
|
||||
// Get mocks base method
|
||||
func (m *MockIndex) Get(arg0 string) interface{} {
|
||||
ret := m.ctrl.Call(m, "Get", arg0)
|
||||
ret0, _ := ret[0].(interface{})
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get
|
||||
func (mr *MockIndexMockRecorder) Get(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockIndex)(nil).Get), arg0)
|
||||
}
|
||||
|
||||
// GetTwo mocks base method
|
||||
func (m *MockIndex) GetTwo(arg0, arg1 string) (interface{}, interface{}) {
|
||||
ret := m.ctrl.Call(m, "GetTwo", arg0, arg1)
|
||||
ret0, _ := ret[0].(interface{})
|
||||
ret1, _ := ret[1].(interface{})
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetTwo indicates an expected call of GetTwo
|
||||
func (mr *MockIndexMockRecorder) GetTwo(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTwo", reflect.TypeOf((*MockIndex)(nil).GetTwo), arg0, arg1)
|
||||
}
|
||||
|
||||
// Map mocks base method
|
||||
func (m *MockIndex) Map(arg0 map[int]hash.Hash) {
|
||||
m.ctrl.Call(m, "Map", arg0)
|
||||
}
|
||||
|
||||
// Map indicates an expected call of Map
|
||||
func (mr *MockIndexMockRecorder) Map(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockIndex)(nil).Map), arg0)
|
||||
}
|
||||
|
||||
// NillableRet mocks base method
|
||||
func (m *MockIndex) NillableRet() error {
|
||||
ret := m.ctrl.Call(m, "NillableRet")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// NillableRet indicates an expected call of NillableRet
|
||||
func (mr *MockIndexMockRecorder) NillableRet() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NillableRet", reflect.TypeOf((*MockIndex)(nil).NillableRet))
|
||||
}
|
||||
|
||||
// Other mocks base method
|
||||
func (m *MockIndex) Other() hash.Hash {
|
||||
ret := m.ctrl.Call(m, "Other")
|
||||
ret0, _ := ret[0].(hash.Hash)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Other indicates an expected call of Other
|
||||
func (mr *MockIndexMockRecorder) Other() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Other", reflect.TypeOf((*MockIndex)(nil).Other))
|
||||
}
|
||||
|
||||
// Ptr mocks base method
|
||||
func (m *MockIndex) Ptr(arg0 *int) {
|
||||
m.ctrl.Call(m, "Ptr", arg0)
|
||||
}
|
||||
|
||||
// Ptr indicates an expected call of Ptr
|
||||
func (mr *MockIndexMockRecorder) Ptr(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ptr", reflect.TypeOf((*MockIndex)(nil).Ptr), arg0)
|
||||
}
|
||||
|
||||
// Put mocks base method
|
||||
func (m *MockIndex) Put(arg0 string, arg1 interface{}) {
|
||||
m.ctrl.Call(m, "Put", arg0, arg1)
|
||||
}
|
||||
|
||||
// Put indicates an expected call of Put
|
||||
func (mr *MockIndexMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockIndex)(nil).Put), arg0, arg1)
|
||||
}
|
||||
|
||||
// Slice mocks base method
|
||||
func (m *MockIndex) Slice(arg0 []int, arg1 []byte) [3]int {
|
||||
ret := m.ctrl.Call(m, "Slice", arg0, arg1)
|
||||
ret0, _ := ret[0].([3]int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Slice indicates an expected call of Slice
|
||||
func (mr *MockIndexMockRecorder) Slice(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Slice", reflect.TypeOf((*MockIndex)(nil).Slice), arg0, arg1)
|
||||
}
|
||||
|
||||
// Struct mocks base method
|
||||
func (m *MockIndex) Struct(arg0 struct{}) {
|
||||
m.ctrl.Call(m, "Struct", arg0)
|
||||
}
|
||||
|
||||
// Struct indicates an expected call of Struct
|
||||
func (mr *MockIndexMockRecorder) Struct(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Struct", reflect.TypeOf((*MockIndex)(nil).Struct), arg0)
|
||||
}
|
||||
|
||||
// StructChan mocks base method
|
||||
func (m *MockIndex) StructChan(arg0 chan struct{}) {
|
||||
m.ctrl.Call(m, "StructChan", arg0)
|
||||
}
|
||||
|
||||
// StructChan indicates an expected call of StructChan
|
||||
func (mr *MockIndexMockRecorder) StructChan(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StructChan", reflect.TypeOf((*MockIndex)(nil).StructChan), arg0)
|
||||
}
|
||||
|
||||
// Summary mocks base method
|
||||
func (m *MockIndex) Summary(arg0 *bytes.Buffer, arg1 io.Writer) {
|
||||
m.ctrl.Call(m, "Summary", arg0, arg1)
|
||||
}
|
||||
|
||||
// Summary indicates an expected call of Summary
|
||||
func (mr *MockIndexMockRecorder) Summary(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Summary", reflect.TypeOf((*MockIndex)(nil).Summary), arg0, arg1)
|
||||
}
|
||||
|
||||
// Templates mocks base method
|
||||
func (m *MockIndex) Templates(arg0 template.CSS, arg1 template0.FuncMap) {
|
||||
m.ctrl.Call(m, "Templates", arg0, arg1)
|
||||
}
|
||||
|
||||
// Templates indicates an expected call of Templates
|
||||
func (mr *MockIndexMockRecorder) Templates(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Templates", reflect.TypeOf((*MockIndex)(nil).Templates), arg0, arg1)
|
||||
}
|
||||
|
||||
// MockEmbed is a mock of Embed interface
|
||||
type MockEmbed struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockEmbedMockRecorder
|
||||
}
|
||||
|
||||
// MockEmbedMockRecorder is the mock recorder for MockEmbed
|
||||
type MockEmbedMockRecorder struct {
|
||||
mock *MockEmbed
|
||||
}
|
||||
|
||||
// NewMockEmbed creates a new mock instance
|
||||
func NewMockEmbed(ctrl *gomock.Controller) *MockEmbed {
|
||||
mock := &MockEmbed{ctrl: ctrl}
|
||||
mock.recorder = &MockEmbedMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockEmbed) EXPECT() *MockEmbedMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// EmbeddedMethod mocks base method
|
||||
func (m *MockEmbed) EmbeddedMethod() {
|
||||
m.ctrl.Call(m, "EmbeddedMethod")
|
||||
}
|
||||
|
||||
// EmbeddedMethod indicates an expected call of EmbeddedMethod
|
||||
func (mr *MockEmbedMockRecorder) EmbeddedMethod() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmbeddedMethod", reflect.TypeOf((*MockEmbed)(nil).EmbeddedMethod))
|
||||
}
|
||||
|
||||
// ForeignEmbeddedMethod mocks base method
|
||||
func (m *MockEmbed) ForeignEmbeddedMethod() *bufio.Reader {
|
||||
ret := m.ctrl.Call(m, "ForeignEmbeddedMethod")
|
||||
ret0, _ := ret[0].(*bufio.Reader)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ForeignEmbeddedMethod indicates an expected call of ForeignEmbeddedMethod
|
||||
func (mr *MockEmbedMockRecorder) ForeignEmbeddedMethod() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForeignEmbeddedMethod", reflect.TypeOf((*MockEmbed)(nil).ForeignEmbeddedMethod))
|
||||
}
|
||||
|
||||
// ImplicitPackage mocks base method
|
||||
func (m *MockEmbed) ImplicitPackage(arg0 string, arg1 imp1.ImpT, arg2 []imp1.ImpT, arg3 *imp1.ImpT, arg4 chan imp1.ImpT) {
|
||||
m.ctrl.Call(m, "ImplicitPackage", arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// ImplicitPackage indicates an expected call of ImplicitPackage
|
||||
func (mr *MockEmbedMockRecorder) ImplicitPackage(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImplicitPackage", reflect.TypeOf((*MockEmbed)(nil).ImplicitPackage), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// RegularMethod mocks base method
|
||||
func (m *MockEmbed) RegularMethod() {
|
||||
m.ctrl.Call(m, "RegularMethod")
|
||||
}
|
||||
|
||||
// RegularMethod indicates an expected call of RegularMethod
|
||||
func (mr *MockEmbedMockRecorder) RegularMethod() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegularMethod", reflect.TypeOf((*MockEmbed)(nil).RegularMethod))
|
||||
}
|
||||
|
||||
// MockEmbedded is a mock of Embedded interface
|
||||
type MockEmbedded struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockEmbeddedMockRecorder
|
||||
}
|
||||
|
||||
// MockEmbeddedMockRecorder is the mock recorder for MockEmbedded
|
||||
type MockEmbeddedMockRecorder struct {
|
||||
mock *MockEmbedded
|
||||
}
|
||||
|
||||
// NewMockEmbedded creates a new mock instance
|
||||
func NewMockEmbedded(ctrl *gomock.Controller) *MockEmbedded {
|
||||
mock := &MockEmbedded{ctrl: ctrl}
|
||||
mock.recorder = &MockEmbeddedMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockEmbedded) EXPECT() *MockEmbeddedMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// EmbeddedMethod mocks base method
|
||||
func (m *MockEmbedded) EmbeddedMethod() {
|
||||
m.ctrl.Call(m, "EmbeddedMethod")
|
||||
}
|
||||
|
||||
// EmbeddedMethod indicates an expected call of EmbeddedMethod
|
||||
func (mr *MockEmbeddedMockRecorder) EmbeddedMethod() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmbeddedMethod", reflect.TypeOf((*MockEmbedded)(nil).EmbeddedMethod))
|
||||
}
|
114
vendor/github.com/golang/mock/sample/user.go
generated
vendored
114
vendor/github.com/golang/mock/sample/user.go
generated
vendored
@@ -1,114 +0,0 @@
|
||||
//go:generate mockgen -destination mock_user/mock_user.go github.com/golang/mock/sample Index,Embed,Embedded
|
||||
|
||||
// An example package with an interface.
|
||||
package user
|
||||
|
||||
// Random bunch of imports to test mockgen.
|
||||
import "io"
|
||||
import (
|
||||
btz "bytes"
|
||||
"hash"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
// Two imports with the same base name.
|
||||
t1 "html/template"
|
||||
t2 "text/template"
|
||||
)
|
||||
|
||||
// Dependencies outside the standard library.
|
||||
import (
|
||||
"github.com/golang/mock/sample/imp1"
|
||||
renamed2 "github.com/golang/mock/sample/imp2"
|
||||
. "github.com/golang/mock/sample/imp3"
|
||||
"github.com/golang/mock/sample/imp4" // calls itself "imp_four"
|
||||
)
|
||||
|
||||
// A bizarre interface to test corner cases in mockgen.
|
||||
// This would normally be in its own file or package,
|
||||
// separate from the user of it (e.g. io.Reader).
|
||||
type Index interface {
|
||||
Get(key string) interface{}
|
||||
GetTwo(key1, key2 string) (v1, v2 interface{})
|
||||
Put(key string, value interface{})
|
||||
|
||||
// Check that imports are handled correctly.
|
||||
Summary(buf *btz.Buffer, w io.Writer)
|
||||
Other() hash.Hash
|
||||
Templates(a t1.CSS, b t2.FuncMap)
|
||||
|
||||
// A method with an anonymous argument.
|
||||
Anon(string)
|
||||
|
||||
// Methods using foreign types outside the standard library.
|
||||
ForeignOne(imp1.Imp1)
|
||||
ForeignTwo(renamed2.Imp2)
|
||||
ForeignThree(Imp3)
|
||||
ForeignFour(imp_four.Imp4)
|
||||
|
||||
// A method that returns a nillable type.
|
||||
NillableRet() error
|
||||
// A method that returns a non-interface type.
|
||||
ConcreteRet() chan<- bool
|
||||
|
||||
// Methods with an ellipsis argument.
|
||||
Ellip(fmt string, args ...interface{})
|
||||
EllipOnly(...string)
|
||||
|
||||
// A method with a pointer argument that we will set.
|
||||
Ptr(arg *int)
|
||||
|
||||
// A method with a slice argument and an array return.
|
||||
Slice(a []int, b []byte) [3]int
|
||||
|
||||
// A method with channel arguments.
|
||||
Chan(a chan int, b chan<- hash.Hash)
|
||||
|
||||
// A method with a function argument.
|
||||
Func(f func(http.Request) (int, bool))
|
||||
|
||||
// A method with a map argument.
|
||||
Map(a map[int]hash.Hash)
|
||||
|
||||
// Methods with an unnamed empty struct argument.
|
||||
Struct(a struct{}) // not so likely
|
||||
StructChan(a chan struct{}) // a bit more common
|
||||
}
|
||||
|
||||
// An interface with an embedded interface.
|
||||
type Embed interface {
|
||||
RegularMethod()
|
||||
Embedded
|
||||
imp1.ForeignEmbedded
|
||||
}
|
||||
|
||||
type Embedded interface {
|
||||
EmbeddedMethod()
|
||||
}
|
||||
|
||||
// some random use of another package that isn't needed by the interface.
|
||||
var _ net.Addr
|
||||
|
||||
// A function that we will test that uses the above interface.
|
||||
// It takes a list of keys and values, and puts them in the index.
|
||||
func Remember(index Index, keys []string, values []interface{}) {
|
||||
for i, k := range keys {
|
||||
index.Put(k, values[i])
|
||||
}
|
||||
err := index.NillableRet()
|
||||
if err != nil {
|
||||
log.Fatalf("Woah! %v", err)
|
||||
}
|
||||
if len(keys) > 0 && keys[0] == "a" {
|
||||
index.Ellip("%d", 0, 1, 1, 2, 3)
|
||||
index.Ellip("%d", 1, 3, 6, 10, 15)
|
||||
index.EllipOnly("arg")
|
||||
}
|
||||
}
|
||||
|
||||
func GrabPointer(index Index) int {
|
||||
var a int
|
||||
index.Ptr(&a)
|
||||
return a
|
||||
}
|
161
vendor/github.com/golang/mock/sample/user_test.go
generated
vendored
161
vendor/github.com/golang/mock/sample/user_test.go
generated
vendored
@@ -1,161 +0,0 @@
|
||||
// A test that uses a mock.
|
||||
package user_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/golang/mock/sample"
|
||||
"github.com/golang/mock/sample/imp1"
|
||||
mock_user "github.com/golang/mock/sample/mock_user"
|
||||
)
|
||||
|
||||
func TestRemember(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockIndex := mock_user.NewMockIndex(ctrl)
|
||||
mockIndex.EXPECT().Put("a", 1) // literals work
|
||||
mockIndex.EXPECT().Put("b", gomock.Eq(2)) // matchers work too
|
||||
|
||||
// NillableRet returns error. Not declaring it should result in a nil return.
|
||||
mockIndex.EXPECT().NillableRet()
|
||||
// Calls that returns something assignable to the return type.
|
||||
boolc := make(chan bool)
|
||||
// In this case, "chan bool" is assignable to "chan<- bool".
|
||||
mockIndex.EXPECT().ConcreteRet().Return(boolc)
|
||||
// In this case, nil is assignable to "chan<- bool".
|
||||
mockIndex.EXPECT().ConcreteRet().Return(nil)
|
||||
|
||||
// Should be able to place expectations on variadic methods.
|
||||
mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) // direct args
|
||||
tri := []interface{}{1, 3, 6, 10, 15}
|
||||
mockIndex.EXPECT().Ellip("%d", tri...) // args from slice
|
||||
mockIndex.EXPECT().EllipOnly(gomock.Eq("arg"))
|
||||
|
||||
user.Remember(mockIndex, []string{"a", "b"}, []interface{}{1, 2})
|
||||
// Check the ConcreteRet calls.
|
||||
if c := mockIndex.ConcreteRet(); c != boolc {
|
||||
t.Errorf("ConcreteRet: got %v, want %v", c, boolc)
|
||||
}
|
||||
if c := mockIndex.ConcreteRet(); c != nil {
|
||||
t.Errorf("ConcreteRet: got %v, want nil", c)
|
||||
}
|
||||
|
||||
// Try one with an action.
|
||||
calledString := ""
|
||||
mockIndex.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(key string, _ interface{}) {
|
||||
calledString = key
|
||||
})
|
||||
mockIndex.EXPECT().NillableRet()
|
||||
user.Remember(mockIndex, []string{"blah"}, []interface{}{7})
|
||||
if calledString != "blah" {
|
||||
t.Fatalf(`Uh oh. %q != "blah"`, calledString)
|
||||
}
|
||||
|
||||
// Use Do with a nil arg.
|
||||
mockIndex.EXPECT().Put("nil-key", gomock.Any()).Do(func(key string, value interface{}) {
|
||||
if value != nil {
|
||||
t.Errorf("Put did not pass through nil; got %v", value)
|
||||
}
|
||||
})
|
||||
mockIndex.EXPECT().NillableRet()
|
||||
user.Remember(mockIndex, []string{"nil-key"}, []interface{}{nil})
|
||||
}
|
||||
|
||||
func TestVariadicFunction(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockIndex := mock_user.NewMockIndex(ctrl)
|
||||
mockIndex.EXPECT().Ellip("%d", 5, 6, 7, 8).Do(func(format string, nums ...int) {
|
||||
sum := 0
|
||||
for _, value := range nums {
|
||||
sum += value
|
||||
}
|
||||
if sum != 26 {
|
||||
t.Errorf("Expected 7, got %d", sum)
|
||||
}
|
||||
})
|
||||
mockIndex.EXPECT().Ellip("%d", gomock.Any()).Do(func(format string, nums ...int) {
|
||||
sum := 0
|
||||
for _, value := range nums {
|
||||
sum += value
|
||||
}
|
||||
if sum != 10 {
|
||||
t.Errorf("Expected 7, got %d", sum)
|
||||
}
|
||||
})
|
||||
mockIndex.EXPECT().Ellip("%d", gomock.Any()).Do(func(format string, nums ...int) {
|
||||
sum := 0
|
||||
for _, value := range nums {
|
||||
sum += value
|
||||
}
|
||||
if sum != 0 {
|
||||
t.Errorf("Expected 0, got %d", sum)
|
||||
}
|
||||
})
|
||||
mockIndex.EXPECT().Ellip("%d", gomock.Any()).Do(func(format string, nums ...int) {
|
||||
sum := 0
|
||||
for _, value := range nums {
|
||||
sum += value
|
||||
}
|
||||
if sum != 0 {
|
||||
t.Errorf("Expected 0, got %d", sum)
|
||||
}
|
||||
})
|
||||
mockIndex.EXPECT().Ellip("%d").Do(func(format string, nums ...int) {
|
||||
sum := 0
|
||||
for _, value := range nums {
|
||||
sum += value
|
||||
}
|
||||
if sum != 0 {
|
||||
t.Errorf("Expected 0, got %d", sum)
|
||||
}
|
||||
})
|
||||
|
||||
mockIndex.Ellip("%d", 1, 2, 3, 4) // Match second matcher.
|
||||
mockIndex.Ellip("%d", 5, 6, 7, 8) // Match first matcher.
|
||||
mockIndex.Ellip("%d", 0)
|
||||
mockIndex.Ellip("%d")
|
||||
mockIndex.Ellip("%d")
|
||||
}
|
||||
|
||||
func TestGrabPointer(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockIndex := mock_user.NewMockIndex(ctrl)
|
||||
mockIndex.EXPECT().Ptr(gomock.Any()).SetArg(0, 7) // set first argument to 7
|
||||
|
||||
i := user.GrabPointer(mockIndex)
|
||||
if i != 7 {
|
||||
t.Errorf("Expected 7, got %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmbeddedInterface(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockEmbed := mock_user.NewMockEmbed(ctrl)
|
||||
mockEmbed.EXPECT().RegularMethod()
|
||||
mockEmbed.EXPECT().EmbeddedMethod()
|
||||
mockEmbed.EXPECT().ForeignEmbeddedMethod()
|
||||
|
||||
mockEmbed.RegularMethod()
|
||||
mockEmbed.EmbeddedMethod()
|
||||
var emb imp1.ForeignEmbedded = mockEmbed // also does interface check
|
||||
emb.ForeignEmbeddedMethod()
|
||||
}
|
||||
|
||||
func TestExpectTrueNil(t *testing.T) {
|
||||
// Make sure that passing "nil" to EXPECT (thus as a nil interface value),
|
||||
// will correctly match a nil concrete type.
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockIndex := mock_user.NewMockIndex(ctrl)
|
||||
mockIndex.EXPECT().Ptr(nil) // this nil is a nil interface{}
|
||||
mockIndex.Ptr(nil) // this nil is a nil *int
|
||||
}
|
20
vendor/github.com/golang/protobuf/.github/ISSUE_TEMPLATE/bug_report.md
generated
vendored
20
vendor/github.com/golang/protobuf/.github/ISSUE_TEMPLATE/bug_report.md
generated
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**What version of protobuf and what language are you using?**
|
||||
Version: (e.g., `v1.1.0`, `89a0c16f`, etc)
|
||||
|
||||
**What did you do?**
|
||||
If possible, provide a recipe for reproducing the error.
|
||||
A complete runnable program is good with `.proto` and `.go` source code.
|
||||
|
||||
**What did you expect to see?**
|
||||
|
||||
**What did you see instead?**
|
||||
|
||||
Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).
|
||||
|
||||
**Anything else we should know about your project / environment?**
|
17
vendor/github.com/golang/protobuf/.github/ISSUE_TEMPLATE/feature_request.md
generated
vendored
17
vendor/github.com/golang/protobuf/.github/ISSUE_TEMPLATE/feature_request.md
generated
vendored
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is.
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
7
vendor/github.com/golang/protobuf/.github/ISSUE_TEMPLATE/question.md
generated
vendored
7
vendor/github.com/golang/protobuf/.github/ISSUE_TEMPLATE/question.md
generated
vendored
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Questions and troubleshooting
|
||||
|
||||
---
|
||||
|
||||
|
17
vendor/github.com/golang/protobuf/.gitignore
generated
vendored
17
vendor/github.com/golang/protobuf/.gitignore
generated
vendored
@@ -1,17 +0,0 @@
|
||||
.DS_Store
|
||||
*.[568ao]
|
||||
*.ao
|
||||
*.so
|
||||
*.pyc
|
||||
._*
|
||||
.nfs.*
|
||||
[568a].out
|
||||
*~
|
||||
*.orig
|
||||
core
|
||||
_obj
|
||||
_test
|
||||
_testmain.go
|
||||
|
||||
# Conformance test output and transient files.
|
||||
conformance/failing_tests.txt
|
31
vendor/github.com/golang/protobuf/.travis.yml
generated
vendored
31
vendor/github.com/golang/protobuf/.travis.yml
generated
vendored
@@ -1,31 +0,0 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- 1.6.x
|
||||
- 1.10.x
|
||||
- 1.x
|
||||
|
||||
install:
|
||||
- go get -v -d google.golang.org/grpc
|
||||
- go get -v -d -t github.com/golang/protobuf/...
|
||||
- curl -L https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-linux-x86_64.zip -o /tmp/protoc.zip
|
||||
- unzip /tmp/protoc.zip -d "$HOME"/protoc
|
||||
- mkdir -p "$HOME"/src && ln -s "$HOME"/protoc "$HOME"/src/protobuf
|
||||
|
||||
env:
|
||||
- PATH=$HOME/protoc/bin:$PATH
|
||||
|
||||
script:
|
||||
- make all
|
||||
- make regenerate
|
||||
# TODO(tamird): When https://github.com/travis-ci/gimme/pull/130 is
|
||||
# released, make this look for "1.x".
|
||||
- if [[ "$TRAVIS_GO_VERSION" == 1.10* ]]; then
|
||||
if [[ "$(git status --porcelain 2>&1)" != "" ]]; then
|
||||
git status >&2;
|
||||
git diff -a >&2;
|
||||
exit 1;
|
||||
fi;
|
||||
echo "git status is clean.";
|
||||
fi;
|
||||
- make test
|
50
vendor/github.com/golang/protobuf/Makefile
generated
vendored
50
vendor/github.com/golang/protobuf/Makefile
generated
vendored
@@ -1,50 +0,0 @@
|
||||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2010 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
all: install
|
||||
|
||||
install:
|
||||
go install ./proto ./jsonpb ./ptypes ./protoc-gen-go
|
||||
|
||||
test:
|
||||
go test ./... ./protoc-gen-go/testdata
|
||||
go test -tags purego ./... ./protoc-gen-go/testdata
|
||||
go build ./protoc-gen-go/testdata/grpc/grpc.pb.go
|
||||
make -C conformance test
|
||||
|
||||
clean:
|
||||
go clean ./...
|
||||
|
||||
nuke:
|
||||
go clean -i ./...
|
||||
|
||||
regenerate:
|
||||
./regenerate.sh
|
281
vendor/github.com/golang/protobuf/README.md
generated
vendored
281
vendor/github.com/golang/protobuf/README.md
generated
vendored
@@ -1,281 +0,0 @@
|
||||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
|
||||
[](https://travis-ci.org/golang/protobuf)
|
||||
[](https://godoc.org/github.com/golang/protobuf)
|
||||
|
||||
Google's data interchange format.
|
||||
Copyright 2010 The Go Authors.
|
||||
https://github.com/golang/protobuf
|
||||
|
||||
This package and the code it generates requires at least Go 1.6.
|
||||
|
||||
This software implements Go bindings for protocol buffers. For
|
||||
information about protocol buffers themselves, see
|
||||
https://developers.google.com/protocol-buffers/
|
||||
|
||||
## Installation ##
|
||||
|
||||
To use this software, you must:
|
||||
- Install the standard C++ implementation of protocol buffers from
|
||||
https://developers.google.com/protocol-buffers/
|
||||
- Of course, install the Go compiler and tools from
|
||||
https://golang.org/
|
||||
See
|
||||
https://golang.org/doc/install
|
||||
for details or, if you are using gccgo, follow the instructions at
|
||||
https://golang.org/doc/install/gccgo
|
||||
- Grab the code from the repository and install the proto package.
|
||||
The simplest way is to run `go get -u github.com/golang/protobuf/protoc-gen-go`.
|
||||
The compiler plugin, protoc-gen-go, will be installed in $GOBIN,
|
||||
defaulting to $GOPATH/bin. It must be in your $PATH for the protocol
|
||||
compiler, protoc, to find it.
|
||||
|
||||
This software has two parts: a 'protocol compiler plugin' that
|
||||
generates Go source files that, once compiled, can access and manage
|
||||
protocol buffers; and a library that implements run-time support for
|
||||
encoding (marshaling), decoding (unmarshaling), and accessing protocol
|
||||
buffers.
|
||||
|
||||
There is support for gRPC in Go using protocol buffers.
|
||||
See the note at the bottom of this file for details.
|
||||
|
||||
There are no insertion points in the plugin.
|
||||
|
||||
|
||||
## Using protocol buffers with Go ##
|
||||
|
||||
Once the software is installed, there are two steps to using it.
|
||||
First you must compile the protocol buffer definitions and then import
|
||||
them, with the support library, into your program.
|
||||
|
||||
To compile the protocol buffer definition, run protoc with the --go_out
|
||||
parameter set to the directory you want to output the Go code to.
|
||||
|
||||
protoc --go_out=. *.proto
|
||||
|
||||
The generated files will be suffixed .pb.go. See the Test code below
|
||||
for an example using such a file.
|
||||
|
||||
## Packages and input paths ##
|
||||
|
||||
The protocol buffer language has a concept of "packages" which does not
|
||||
correspond well to the Go notion of packages. In generated Go code,
|
||||
each source `.proto` file is associated with a single Go package. The
|
||||
name and import path for this package is specified with the `go_package`
|
||||
proto option:
|
||||
|
||||
option go_package = "github.com/golang/protobuf/ptypes/any";
|
||||
|
||||
The protocol buffer compiler will attempt to derive a package name and
|
||||
import path if a `go_package` option is not present, but it is
|
||||
best to always specify one explicitly.
|
||||
|
||||
There is a one-to-one relationship between source `.proto` files and
|
||||
generated `.pb.go` files, but any number of `.pb.go` files may be
|
||||
contained in the same Go package.
|
||||
|
||||
The output name of a generated file is produced by replacing the
|
||||
`.proto` suffix with `.pb.go` (e.g., `foo.proto` produces `foo.pb.go`).
|
||||
However, the output directory is selected in one of two ways. Let
|
||||
us say we have `inputs/x.proto` with a `go_package` option of
|
||||
`github.com/golang/protobuf/p`. The corresponding output file may
|
||||
be:
|
||||
|
||||
- Relative to the import path:
|
||||
|
||||
```shell
|
||||
protoc --go_out=. inputs/x.proto
|
||||
# writes ./github.com/golang/protobuf/p/x.pb.go
|
||||
```
|
||||
|
||||
(This can work well with `--go_out=$GOPATH`.)
|
||||
|
||||
- Relative to the input file:
|
||||
|
||||
```shell
|
||||
protoc --go_out=paths=source_relative:. inputs/x.proto
|
||||
# generate ./inputs/x.pb.go
|
||||
```
|
||||
|
||||
## Generated code ##
|
||||
|
||||
The package comment for the proto library contains text describing
|
||||
the interface provided in Go for protocol buffers. Here is an edited
|
||||
version.
|
||||
|
||||
The proto package converts data structures to and from the
|
||||
wire format of protocol buffers. It works in concert with the
|
||||
Go source code generated for .proto files by the protocol compiler.
|
||||
|
||||
A summary of the properties of the protocol buffer interface
|
||||
for a protocol buffer variable v:
|
||||
|
||||
- Names are turned from camel_case to CamelCase for export.
|
||||
- There are no methods on v to set fields; just treat
|
||||
them as structure fields.
|
||||
- There are getters that return a field's value if set,
|
||||
and return the field's default value if unset.
|
||||
The getters work even if the receiver is a nil message.
|
||||
- The zero value for a struct is its correct initialization state.
|
||||
All desired fields must be set before marshaling.
|
||||
- A Reset() method will restore a protobuf struct to its zero state.
|
||||
- Non-repeated fields are pointers to the values; nil means unset.
|
||||
That is, optional or required field int32 f becomes F *int32.
|
||||
- Repeated fields are slices.
|
||||
- Helper functions are available to aid the setting of fields.
|
||||
Helpers for getting values are superseded by the
|
||||
GetFoo methods and their use is deprecated.
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
- Constants are defined to hold the default values of all fields that
|
||||
have them. They have the form Default_StructName_FieldName.
|
||||
Because the getter methods handle defaulted values,
|
||||
direct use of these constants should be rare.
|
||||
- Enums are given type names and maps from names to values.
|
||||
Enum values are prefixed with the enum's type name. Enum types have
|
||||
a String method, and a Enum method to assist in message construction.
|
||||
- Nested groups and enums have type names prefixed with the name of
|
||||
the surrounding message type.
|
||||
- Extensions are given descriptor names that start with E_,
|
||||
followed by an underscore-delimited list of the nested messages
|
||||
that contain it (if any) followed by the CamelCased name of the
|
||||
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||
and SetExtension are functions for manipulating extensions.
|
||||
- Oneof field sets are given a single field in their message,
|
||||
with distinguished wrapper types for each possible field value.
|
||||
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
- Non-repeated fields of non-message type are values instead of pointers.
|
||||
- Enum types do not get an Enum method.
|
||||
|
||||
Consider file test.proto, containing
|
||||
|
||||
```proto
|
||||
syntax = "proto2";
|
||||
package example;
|
||||
|
||||
enum FOO { X = 17; };
|
||||
|
||||
message Test {
|
||||
required string label = 1;
|
||||
optional int32 type = 2 [default=77];
|
||||
repeated int64 reps = 3;
|
||||
}
|
||||
```
|
||||
|
||||
To create and play with a Test object from the example package,
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"path/to/example"
|
||||
)
|
||||
|
||||
func main() {
|
||||
test := &example.Test{
|
||||
Label: proto.String("hello"),
|
||||
Type: proto.Int32(17),
|
||||
Reps: []int64{1, 2, 3},
|
||||
}
|
||||
data, err := proto.Marshal(test)
|
||||
if err != nil {
|
||||
log.Fatal("marshaling error: ", err)
|
||||
}
|
||||
newTest := &example.Test{}
|
||||
err = proto.Unmarshal(data, newTest)
|
||||
if err != nil {
|
||||
log.Fatal("unmarshaling error: ", err)
|
||||
}
|
||||
// Now test and newTest contain the same data.
|
||||
if test.GetLabel() != newTest.GetLabel() {
|
||||
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
|
||||
}
|
||||
// etc.
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters ##
|
||||
|
||||
To pass extra parameters to the plugin, use a comma-separated
|
||||
parameter list separated from the output directory by a colon:
|
||||
|
||||
protoc --go_out=plugins=grpc,import_path=mypackage:. *.proto
|
||||
|
||||
- `paths=(import | source_relative)` - specifies how the paths of
|
||||
generated files are structured. See the "Packages and imports paths"
|
||||
section above. The default is `import`.
|
||||
- `plugins=plugin1+plugin2` - specifies the list of sub-plugins to
|
||||
load. The only plugin in this repo is `grpc`.
|
||||
- `Mfoo/bar.proto=quux/shme` - declares that foo/bar.proto is
|
||||
associated with Go package quux/shme. This is subject to the
|
||||
import_prefix parameter.
|
||||
|
||||
The following parameters are deprecated and should not be used:
|
||||
|
||||
- `import_prefix=xxx` - a prefix that is added onto the beginning of
|
||||
all imports.
|
||||
- `import_path=foo/bar` - used as the package if no input files
|
||||
declare `go_package`. If it contains slashes, everything up to the
|
||||
rightmost slash is ignored.
|
||||
|
||||
## gRPC Support ##
|
||||
|
||||
If a proto file specifies RPC services, protoc-gen-go can be instructed to
|
||||
generate code compatible with gRPC (http://www.grpc.io/). To do this, pass
|
||||
the `plugins` parameter to protoc-gen-go; the usual way is to insert it into
|
||||
the --go_out argument to protoc:
|
||||
|
||||
protoc --go_out=plugins=grpc:. *.proto
|
||||
|
||||
## Compatibility ##
|
||||
|
||||
The library and the generated code are expected to be stable over time.
|
||||
However, we reserve the right to make breaking changes without notice for the
|
||||
following reasons:
|
||||
|
||||
- Security. A security issue in the specification or implementation may come to
|
||||
light whose resolution requires breaking compatibility. We reserve the right
|
||||
to address such security issues.
|
||||
- Unspecified behavior. There are some aspects of the Protocol Buffers
|
||||
specification that are undefined. Programs that depend on such unspecified
|
||||
behavior may break in future releases.
|
||||
- Specification errors or changes. If it becomes necessary to address an
|
||||
inconsistency, incompleteness, or change in the Protocol Buffers
|
||||
specification, resolving the issue could affect the meaning or legality of
|
||||
existing programs. We reserve the right to address such issues, including
|
||||
updating the implementations.
|
||||
- Bugs. If the library has a bug that violates the specification, a program
|
||||
that depends on the buggy behavior may break if the bug is fixed. We reserve
|
||||
the right to fix such bugs.
|
||||
- Adding methods or fields to generated structs. These may conflict with field
|
||||
names that already exist in a schema, causing applications to break. When the
|
||||
code generator encounters a field in the schema that would collide with a
|
||||
generated field or method name, the code generator will append an underscore
|
||||
to the generated field or method name.
|
||||
- Adding, removing, or changing methods or fields in generated structs that
|
||||
start with `XXX`. These parts of the generated code are exported out of
|
||||
necessity, but should not be considered part of the public API.
|
||||
- Adding, removing, or changing unexported symbols in generated code.
|
||||
|
||||
Any breaking changes outside of these will be announced 6 months in advance to
|
||||
protobuf@googlegroups.com.
|
||||
|
||||
You should, whenever possible, use generated code created by the `protoc-gen-go`
|
||||
tool built at the same commit as the `proto` package. The `proto` package
|
||||
declares package-level constants in the form `ProtoPackageIsVersionX`.
|
||||
Application code and generated code may depend on one of these constants to
|
||||
ensure that compilation will fail if the available version of the proto library
|
||||
is too old. Whenever we make a change to the generated code that requires newer
|
||||
library support, in the same commit we will increment the version number of the
|
||||
generated code and declare a new package-level constant whose name incorporates
|
||||
the latest version number. Removing a compatibility constant is considered a
|
||||
breaking change and would be subject to the announcement policy stated above.
|
||||
|
||||
The `protoc-gen-go/generator` package exposes a plugin interface,
|
||||
which is used by the gRPC code generation. This interface is not
|
||||
supported and is subject to incompatible changes without notice.
|
49
vendor/github.com/golang/protobuf/conformance/Makefile
generated
vendored
49
vendor/github.com/golang/protobuf/conformance/Makefile
generated
vendored
@@ -1,49 +0,0 @@
|
||||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2016 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
PROTOBUF_ROOT=$(HOME)/src/protobuf
|
||||
|
||||
all:
|
||||
@echo To run the tests in this directory, acquire the main protobuf
|
||||
@echo distribution from:
|
||||
@echo
|
||||
@echo ' https://github.com/google/protobuf'
|
||||
@echo
|
||||
@echo Build the test runner with:
|
||||
@echo
|
||||
@echo ' cd conformance && make conformance-test-runner'
|
||||
@echo
|
||||
@echo And run the tests in this directory with:
|
||||
@echo
|
||||
@echo ' make test PROTOBUF_ROOT=<protobuf distribution>'
|
||||
|
||||
test:
|
||||
./test.sh $(PROTOBUF_ROOT)
|
154
vendor/github.com/golang/protobuf/conformance/conformance.go
generated
vendored
154
vendor/github.com/golang/protobuf/conformance/conformance.go
generated
vendored
@@ -1,154 +0,0 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// conformance implements the conformance test subprocess protocol as
|
||||
// documented in conformance.proto.
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
pb "github.com/golang/protobuf/conformance/internal/conformance_proto"
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var sizeBuf [4]byte
|
||||
inbuf := make([]byte, 0, 4096)
|
||||
outbuf := proto.NewBuffer(nil)
|
||||
for {
|
||||
if _, err := io.ReadFull(os.Stdin, sizeBuf[:]); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "go conformance: read request:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
size := binary.LittleEndian.Uint32(sizeBuf[:])
|
||||
if int(size) > cap(inbuf) {
|
||||
inbuf = make([]byte, size)
|
||||
}
|
||||
inbuf = inbuf[:size]
|
||||
if _, err := io.ReadFull(os.Stdin, inbuf); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "go conformance: read request:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
req := new(pb.ConformanceRequest)
|
||||
if err := proto.Unmarshal(inbuf, req); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "go conformance: parse request:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
res := handle(req)
|
||||
|
||||
if err := outbuf.Marshal(res); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "go conformance: marshal response:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(outbuf.Bytes())))
|
||||
if _, err := os.Stdout.Write(sizeBuf[:]); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "go conformance: write response:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if _, err := os.Stdout.Write(outbuf.Bytes()); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "go conformance: write response:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
outbuf.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
var jsonMarshaler = jsonpb.Marshaler{
|
||||
OrigName: true,
|
||||
}
|
||||
|
||||
func handle(req *pb.ConformanceRequest) *pb.ConformanceResponse {
|
||||
var err error
|
||||
var msg pb.TestAllTypes
|
||||
switch p := req.Payload.(type) {
|
||||
case *pb.ConformanceRequest_ProtobufPayload:
|
||||
err = proto.Unmarshal(p.ProtobufPayload, &msg)
|
||||
case *pb.ConformanceRequest_JsonPayload:
|
||||
err = jsonpb.UnmarshalString(p.JsonPayload, &msg)
|
||||
default:
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_RuntimeError{
|
||||
RuntimeError: "unknown request payload type",
|
||||
},
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_ParseError{
|
||||
ParseError: err.Error(),
|
||||
},
|
||||
}
|
||||
}
|
||||
switch req.RequestedOutputFormat {
|
||||
case pb.WireFormat_PROTOBUF:
|
||||
p, err := proto.Marshal(&msg)
|
||||
if err != nil {
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_SerializeError{
|
||||
SerializeError: err.Error(),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_ProtobufPayload{
|
||||
ProtobufPayload: p,
|
||||
},
|
||||
}
|
||||
case pb.WireFormat_JSON:
|
||||
p, err := jsonMarshaler.MarshalToString(&msg)
|
||||
if err != nil {
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_SerializeError{
|
||||
SerializeError: err.Error(),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_JsonPayload{
|
||||
JsonPayload: p,
|
||||
},
|
||||
}
|
||||
default:
|
||||
return &pb.ConformanceResponse{
|
||||
Result: &pb.ConformanceResponse_RuntimeError{
|
||||
RuntimeError: "unknown output format",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
4
vendor/github.com/golang/protobuf/conformance/conformance.sh
generated
vendored
4
vendor/github.com/golang/protobuf/conformance/conformance.sh
generated
vendored
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd $(dirname $0)
|
||||
exec go run conformance.go $*
|
61
vendor/github.com/golang/protobuf/conformance/failure_list_go.txt
generated
vendored
61
vendor/github.com/golang/protobuf/conformance/failure_list_go.txt
generated
vendored
@@ -1,61 +0,0 @@
|
||||
# This is the list of conformance tests that are known ot fail right now.
|
||||
# TODO: These should be fixed.
|
||||
|
||||
DurationProtoInputTooLarge.JsonOutput
|
||||
DurationProtoInputTooSmall.JsonOutput
|
||||
FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||
FieldMaskPathsDontRoundTrip.JsonOutput
|
||||
FieldMaskTooManyUnderscore.JsonOutput
|
||||
JsonInput.AnyWithFieldMask.JsonOutput
|
||||
JsonInput.AnyWithFieldMask.ProtobufOutput
|
||||
JsonInput.DoubleFieldQuotedValue.JsonOutput
|
||||
JsonInput.DoubleFieldQuotedValue.ProtobufOutput
|
||||
JsonInput.DurationHas3FractionalDigits.Validator
|
||||
JsonInput.DurationHas6FractionalDigits.Validator
|
||||
JsonInput.DurationHas9FractionalDigits.Validator
|
||||
JsonInput.DurationHasZeroFractionalDigit.Validator
|
||||
JsonInput.DurationMaxValue.JsonOutput
|
||||
JsonInput.DurationMaxValue.ProtobufOutput
|
||||
JsonInput.DurationMinValue.JsonOutput
|
||||
JsonInput.DurationMinValue.ProtobufOutput
|
||||
JsonInput.EnumFieldUnknownValue.Validator
|
||||
JsonInput.FieldMask.JsonOutput
|
||||
JsonInput.FieldMask.ProtobufOutput
|
||||
JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
JsonInput.FieldNameWithMixedCases.JsonOutput
|
||||
JsonInput.FieldNameWithMixedCases.ProtobufOutput
|
||||
JsonInput.FieldNameWithMixedCases.Validator
|
||||
JsonInput.FieldNameWithNumbers.Validator
|
||||
JsonInput.FloatFieldQuotedValue.JsonOutput
|
||||
JsonInput.FloatFieldQuotedValue.ProtobufOutput
|
||||
JsonInput.Int32FieldExponentialFormat.JsonOutput
|
||||
JsonInput.Int32FieldExponentialFormat.ProtobufOutput
|
||||
JsonInput.Int32FieldFloatTrailingZero.JsonOutput
|
||||
JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
|
||||
JsonInput.Int32FieldMaxFloatValue.JsonOutput
|
||||
JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
|
||||
JsonInput.Int32FieldMinFloatValue.JsonOutput
|
||||
JsonInput.Int32FieldMinFloatValue.ProtobufOutput
|
||||
JsonInput.Int32FieldStringValue.JsonOutput
|
||||
JsonInput.Int32FieldStringValue.ProtobufOutput
|
||||
JsonInput.Int32FieldStringValueEscaped.JsonOutput
|
||||
JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
|
||||
JsonInput.Int64FieldBeString.Validator
|
||||
JsonInput.MapFieldValueIsNull
|
||||
JsonInput.OneofFieldDuplicate
|
||||
JsonInput.RepeatedFieldMessageElementIsNull
|
||||
JsonInput.RepeatedFieldPrimitiveElementIsNull
|
||||
JsonInput.StringFieldSurrogateInWrongOrder
|
||||
JsonInput.StringFieldUnpairedHighSurrogate
|
||||
JsonInput.StringFieldUnpairedLowSurrogate
|
||||
JsonInput.TimestampHas3FractionalDigits.Validator
|
||||
JsonInput.TimestampHas6FractionalDigits.Validator
|
||||
JsonInput.TimestampHas9FractionalDigits.Validator
|
||||
JsonInput.TimestampHasZeroFractionalDigit.Validator
|
||||
JsonInput.TimestampJsonInputTooSmall
|
||||
JsonInput.TimestampZeroNormalized.Validator
|
||||
JsonInput.Uint32FieldMaxFloatValue.JsonOutput
|
||||
JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
|
||||
JsonInput.Uint64FieldBeString.Validator
|
||||
TimestampProtoInputTooLarge.JsonOutput
|
||||
TimestampProtoInputTooSmall.JsonOutput
|
1834
vendor/github.com/golang/protobuf/conformance/internal/conformance_proto/conformance.pb.go
generated
vendored
1834
vendor/github.com/golang/protobuf/conformance/internal/conformance_proto/conformance.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
273
vendor/github.com/golang/protobuf/conformance/internal/conformance_proto/conformance.proto
generated
vendored
273
vendor/github.com/golang/protobuf/conformance/internal/conformance_proto/conformance.proto
generated
vendored
@@ -1,273 +0,0 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
package conformance;
|
||||
option java_package = "com.google.protobuf.conformance";
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/field_mask.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/wrappers.proto";
|
||||
|
||||
// This defines the conformance testing protocol. This protocol exists between
|
||||
// the conformance test suite itself and the code being tested. For each test,
|
||||
// the suite will send a ConformanceRequest message and expect a
|
||||
// ConformanceResponse message.
|
||||
//
|
||||
// You can either run the tests in two different ways:
|
||||
//
|
||||
// 1. in-process (using the interface in conformance_test.h).
|
||||
//
|
||||
// 2. as a sub-process communicating over a pipe. Information about how to
|
||||
// do this is in conformance_test_runner.cc.
|
||||
//
|
||||
// Pros/cons of the two approaches:
|
||||
//
|
||||
// - running as a sub-process is much simpler for languages other than C/C++.
|
||||
//
|
||||
// - running as a sub-process may be more tricky in unusual environments like
|
||||
// iOS apps, where fork/stdin/stdout are not available.
|
||||
|
||||
enum WireFormat {
|
||||
UNSPECIFIED = 0;
|
||||
PROTOBUF = 1;
|
||||
JSON = 2;
|
||||
}
|
||||
|
||||
// Represents a single test case's input. The testee should:
|
||||
//
|
||||
// 1. parse this proto (which should always succeed)
|
||||
// 2. parse the protobuf or JSON payload in "payload" (which may fail)
|
||||
// 3. if the parse succeeded, serialize the message in the requested format.
|
||||
message ConformanceRequest {
|
||||
// The payload (whether protobuf of JSON) is always for a TestAllTypes proto
|
||||
// (see below).
|
||||
oneof payload {
|
||||
bytes protobuf_payload = 1;
|
||||
string json_payload = 2;
|
||||
}
|
||||
|
||||
// Which format should the testee serialize its message to?
|
||||
WireFormat requested_output_format = 3;
|
||||
}
|
||||
|
||||
// Represents a single test case's output.
|
||||
message ConformanceResponse {
|
||||
oneof result {
|
||||
// This string should be set to indicate parsing failed. The string can
|
||||
// provide more information about the parse error if it is available.
|
||||
//
|
||||
// Setting this string does not necessarily mean the testee failed the
|
||||
// test. Some of the test cases are intentionally invalid input.
|
||||
string parse_error = 1;
|
||||
|
||||
// If the input was successfully parsed but errors occurred when
|
||||
// serializing it to the requested output format, set the error message in
|
||||
// this field.
|
||||
string serialize_error = 6;
|
||||
|
||||
// This should be set if some other error occurred. This will always
|
||||
// indicate that the test failed. The string can provide more information
|
||||
// about the failure.
|
||||
string runtime_error = 2;
|
||||
|
||||
// If the input was successfully parsed and the requested output was
|
||||
// protobuf, serialize it to protobuf and set it in this field.
|
||||
bytes protobuf_payload = 3;
|
||||
|
||||
// If the input was successfully parsed and the requested output was JSON,
|
||||
// serialize to JSON and set it in this field.
|
||||
string json_payload = 4;
|
||||
|
||||
// For when the testee skipped the test, likely because a certain feature
|
||||
// wasn't supported, like JSON input/output.
|
||||
string skipped = 5;
|
||||
}
|
||||
}
|
||||
|
||||
// This proto includes every type of field in both singular and repeated
|
||||
// forms.
|
||||
message TestAllTypes {
|
||||
message NestedMessage {
|
||||
int32 a = 1;
|
||||
TestAllTypes corecursive = 2;
|
||||
}
|
||||
|
||||
enum NestedEnum {
|
||||
FOO = 0;
|
||||
BAR = 1;
|
||||
BAZ = 2;
|
||||
NEG = -1; // Intentionally negative.
|
||||
}
|
||||
|
||||
// Singular
|
||||
int32 optional_int32 = 1;
|
||||
int64 optional_int64 = 2;
|
||||
uint32 optional_uint32 = 3;
|
||||
uint64 optional_uint64 = 4;
|
||||
sint32 optional_sint32 = 5;
|
||||
sint64 optional_sint64 = 6;
|
||||
fixed32 optional_fixed32 = 7;
|
||||
fixed64 optional_fixed64 = 8;
|
||||
sfixed32 optional_sfixed32 = 9;
|
||||
sfixed64 optional_sfixed64 = 10;
|
||||
float optional_float = 11;
|
||||
double optional_double = 12;
|
||||
bool optional_bool = 13;
|
||||
string optional_string = 14;
|
||||
bytes optional_bytes = 15;
|
||||
|
||||
NestedMessage optional_nested_message = 18;
|
||||
ForeignMessage optional_foreign_message = 19;
|
||||
|
||||
NestedEnum optional_nested_enum = 21;
|
||||
ForeignEnum optional_foreign_enum = 22;
|
||||
|
||||
string optional_string_piece = 24 [ctype=STRING_PIECE];
|
||||
string optional_cord = 25 [ctype=CORD];
|
||||
|
||||
TestAllTypes recursive_message = 27;
|
||||
|
||||
// Repeated
|
||||
repeated int32 repeated_int32 = 31;
|
||||
repeated int64 repeated_int64 = 32;
|
||||
repeated uint32 repeated_uint32 = 33;
|
||||
repeated uint64 repeated_uint64 = 34;
|
||||
repeated sint32 repeated_sint32 = 35;
|
||||
repeated sint64 repeated_sint64 = 36;
|
||||
repeated fixed32 repeated_fixed32 = 37;
|
||||
repeated fixed64 repeated_fixed64 = 38;
|
||||
repeated sfixed32 repeated_sfixed32 = 39;
|
||||
repeated sfixed64 repeated_sfixed64 = 40;
|
||||
repeated float repeated_float = 41;
|
||||
repeated double repeated_double = 42;
|
||||
repeated bool repeated_bool = 43;
|
||||
repeated string repeated_string = 44;
|
||||
repeated bytes repeated_bytes = 45;
|
||||
|
||||
repeated NestedMessage repeated_nested_message = 48;
|
||||
repeated ForeignMessage repeated_foreign_message = 49;
|
||||
|
||||
repeated NestedEnum repeated_nested_enum = 51;
|
||||
repeated ForeignEnum repeated_foreign_enum = 52;
|
||||
|
||||
repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
|
||||
repeated string repeated_cord = 55 [ctype=CORD];
|
||||
|
||||
// Map
|
||||
map < int32, int32> map_int32_int32 = 56;
|
||||
map < int64, int64> map_int64_int64 = 57;
|
||||
map < uint32, uint32> map_uint32_uint32 = 58;
|
||||
map < uint64, uint64> map_uint64_uint64 = 59;
|
||||
map < sint32, sint32> map_sint32_sint32 = 60;
|
||||
map < sint64, sint64> map_sint64_sint64 = 61;
|
||||
map < fixed32, fixed32> map_fixed32_fixed32 = 62;
|
||||
map < fixed64, fixed64> map_fixed64_fixed64 = 63;
|
||||
map <sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
|
||||
map <sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
|
||||
map < int32, float> map_int32_float = 66;
|
||||
map < int32, double> map_int32_double = 67;
|
||||
map < bool, bool> map_bool_bool = 68;
|
||||
map < string, string> map_string_string = 69;
|
||||
map < string, bytes> map_string_bytes = 70;
|
||||
map < string, NestedMessage> map_string_nested_message = 71;
|
||||
map < string, ForeignMessage> map_string_foreign_message = 72;
|
||||
map < string, NestedEnum> map_string_nested_enum = 73;
|
||||
map < string, ForeignEnum> map_string_foreign_enum = 74;
|
||||
|
||||
oneof oneof_field {
|
||||
uint32 oneof_uint32 = 111;
|
||||
NestedMessage oneof_nested_message = 112;
|
||||
string oneof_string = 113;
|
||||
bytes oneof_bytes = 114;
|
||||
}
|
||||
|
||||
// Well-known types
|
||||
google.protobuf.BoolValue optional_bool_wrapper = 201;
|
||||
google.protobuf.Int32Value optional_int32_wrapper = 202;
|
||||
google.protobuf.Int64Value optional_int64_wrapper = 203;
|
||||
google.protobuf.UInt32Value optional_uint32_wrapper = 204;
|
||||
google.protobuf.UInt64Value optional_uint64_wrapper = 205;
|
||||
google.protobuf.FloatValue optional_float_wrapper = 206;
|
||||
google.protobuf.DoubleValue optional_double_wrapper = 207;
|
||||
google.protobuf.StringValue optional_string_wrapper = 208;
|
||||
google.protobuf.BytesValue optional_bytes_wrapper = 209;
|
||||
|
||||
repeated google.protobuf.BoolValue repeated_bool_wrapper = 211;
|
||||
repeated google.protobuf.Int32Value repeated_int32_wrapper = 212;
|
||||
repeated google.protobuf.Int64Value repeated_int64_wrapper = 213;
|
||||
repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214;
|
||||
repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215;
|
||||
repeated google.protobuf.FloatValue repeated_float_wrapper = 216;
|
||||
repeated google.protobuf.DoubleValue repeated_double_wrapper = 217;
|
||||
repeated google.protobuf.StringValue repeated_string_wrapper = 218;
|
||||
repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219;
|
||||
|
||||
google.protobuf.Duration optional_duration = 301;
|
||||
google.protobuf.Timestamp optional_timestamp = 302;
|
||||
google.protobuf.FieldMask optional_field_mask = 303;
|
||||
google.protobuf.Struct optional_struct = 304;
|
||||
google.protobuf.Any optional_any = 305;
|
||||
google.protobuf.Value optional_value = 306;
|
||||
|
||||
repeated google.protobuf.Duration repeated_duration = 311;
|
||||
repeated google.protobuf.Timestamp repeated_timestamp = 312;
|
||||
repeated google.protobuf.FieldMask repeated_fieldmask = 313;
|
||||
repeated google.protobuf.Struct repeated_struct = 324;
|
||||
repeated google.protobuf.Any repeated_any = 315;
|
||||
repeated google.protobuf.Value repeated_value = 316;
|
||||
|
||||
// Test field-name-to-JSON-name convention.
|
||||
int32 fieldname1 = 401;
|
||||
int32 field_name2 = 402;
|
||||
int32 _field_name3 = 403;
|
||||
int32 field__name4_ = 404;
|
||||
int32 field0name5 = 405;
|
||||
int32 field_0_name6 = 406;
|
||||
int32 fieldName7 = 407;
|
||||
int32 FieldName8 = 408;
|
||||
int32 field_Name9 = 409;
|
||||
int32 Field_Name10 = 410;
|
||||
int32 FIELD_NAME11 = 411;
|
||||
int32 FIELD_name12 = 412;
|
||||
}
|
||||
|
||||
message ForeignMessage {
|
||||
int32 c = 1;
|
||||
}
|
||||
|
||||
enum ForeignEnum {
|
||||
FOREIGN_FOO = 0;
|
||||
FOREIGN_BAR = 1;
|
||||
FOREIGN_BAZ = 2;
|
||||
}
|
26
vendor/github.com/golang/protobuf/conformance/test.sh
generated
vendored
26
vendor/github.com/golang/protobuf/conformance/test.sh
generated
vendored
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PROTOBUF_ROOT=$1
|
||||
CONFORMANCE_ROOT=$1/conformance
|
||||
CONFORMANCE_TEST_RUNNER=$CONFORMANCE_ROOT/conformance-test-runner
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
if [[ $PROTOBUF_ROOT == "" ]]; then
|
||||
echo "usage: test.sh <protobuf-root>" >/dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -x $CONFORMANCE_TEST_RUNNER ]]; then
|
||||
echo "SKIP: conformance test runner not installed" >/dev/stderr
|
||||
exit 0
|
||||
fi
|
||||
|
||||
a=$CONFORMANCE_ROOT/conformance.proto
|
||||
b=internal/conformance_proto/conformance.proto
|
||||
if [[ $(diff $a $b) != "" ]]; then
|
||||
cp $a $b
|
||||
echo "WARNING: conformance.proto is out of date" >/dev/stderr
|
||||
fi
|
||||
|
||||
$CONFORMANCE_TEST_RUNNER --failure_list failure_list_go.txt ./conformance.sh
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user