CRI Provider implementation (#195)

* First commit of CRI provider. Vendor deps not included

* First commit of CRI provider. Vendor deps not included

* Tidy up comments and format code

* vendor grpc, CRI APIs, update protobuf and tidy logging

* First commit of CRI provider. Vendor deps not included

* Tidy up comments and format code

* vendor grpc, CRI APIs, update protobuf and tidy logging

* Add README

* Fix errors in make test
This commit is contained in:
Ben Corrie
2018-05-15 08:50:52 -07:00
committed by Ria Bhatia
parent 4b61932ac1
commit c6c89f062f
702 changed files with 456968 additions and 11190 deletions

244
vendor/google.golang.org/grpc/test/bufconn/bufconn.go generated vendored Normal file
View File

@@ -0,0 +1,244 @@
/*
*
* Copyright 2017 gRPC authors.
*
* 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 bufconn provides a net.Conn implemented by a buffer and related
// dialing and listening functionality.
package bufconn
import (
"fmt"
"io"
"net"
"sync"
"time"
)
// Listener implements a net.Listener that creates local, buffered net.Conns
// via its Accept and Dial method.
type Listener struct {
mu sync.Mutex
sz int
ch chan net.Conn
done chan struct{}
}
var errClosed = fmt.Errorf("Closed")
// Listen returns a Listener that can only be contacted by its own Dialers and
// creates buffered connections between the two.
func Listen(sz int) *Listener {
return &Listener{sz: sz, ch: make(chan net.Conn), done: make(chan struct{})}
}
// Accept blocks until Dial is called, then returns a net.Conn for the server
// half of the connection.
func (l *Listener) Accept() (net.Conn, error) {
select {
case <-l.done:
return nil, errClosed
case c := <-l.ch:
return c, nil
}
}
// Close stops the listener.
func (l *Listener) Close() error {
l.mu.Lock()
defer l.mu.Unlock()
select {
case <-l.done:
// Already closed.
break
default:
close(l.done)
}
return nil
}
// Addr reports the address of the listener.
func (l *Listener) Addr() net.Addr { return addr{} }
// Dial creates an in-memory full-duplex network connection, unblocks Accept by
// providing it the server half of the connection, and returns the client half
// of the connection.
func (l *Listener) Dial() (net.Conn, error) {
p1, p2 := newPipe(l.sz), newPipe(l.sz)
select {
case <-l.done:
return nil, errClosed
case l.ch <- &conn{p1, p2}:
return &conn{p2, p1}, nil
}
}
type pipe struct {
mu sync.Mutex
// buf contains the data in the pipe. It is a ring buffer of fixed capacity,
// with r and w pointing to the offset to read and write, respsectively.
//
// Data is read between [r, w) and written to [w, r), wrapping around the end
// of the slice if necessary.
//
// The buffer is empty if r == len(buf), otherwise if r == w, it is full.
//
// w and r are always in the range [0, cap(buf)) and [0, len(buf)].
buf []byte
w, r int
wwait sync.Cond
rwait sync.Cond
closed bool
writeClosed bool
}
func newPipe(sz int) *pipe {
p := &pipe{buf: make([]byte, 0, sz)}
p.wwait.L = &p.mu
p.rwait.L = &p.mu
return p
}
func (p *pipe) empty() bool {
return p.r == len(p.buf)
}
func (p *pipe) full() bool {
return p.r < len(p.buf) && p.r == p.w
}
func (p *pipe) Read(b []byte) (n int, err error) {
p.mu.Lock()
defer p.mu.Unlock()
// Block until p has data.
for {
if p.closed {
return 0, io.ErrClosedPipe
}
if !p.empty() {
break
}
if p.writeClosed {
return 0, io.EOF
}
p.rwait.Wait()
}
wasFull := p.full()
n = copy(b, p.buf[p.r:len(p.buf)])
p.r += n
if p.r == cap(p.buf) {
p.r = 0
p.buf = p.buf[:p.w]
}
// Signal a blocked writer, if any
if wasFull {
p.wwait.Signal()
}
return n, nil
}
func (p *pipe) Write(b []byte) (n int, err error) {
p.mu.Lock()
defer p.mu.Unlock()
if p.closed {
return 0, io.ErrClosedPipe
}
for len(b) > 0 {
// Block until p is not full.
for {
if p.closed || p.writeClosed {
return 0, io.ErrClosedPipe
}
if !p.full() {
break
}
p.wwait.Wait()
}
wasEmpty := p.empty()
end := cap(p.buf)
if p.w < p.r {
end = p.r
}
x := copy(p.buf[p.w:end], b)
b = b[x:]
n += x
p.w += x
if p.w > len(p.buf) {
p.buf = p.buf[:p.w]
}
if p.w == cap(p.buf) {
p.w = 0
}
// Signal a blocked reader, if any.
if wasEmpty {
p.rwait.Signal()
}
}
return n, nil
}
func (p *pipe) Close() error {
p.mu.Lock()
defer p.mu.Unlock()
p.closed = true
// Signal all blocked readers and writers to return an error.
p.rwait.Broadcast()
p.wwait.Broadcast()
return nil
}
func (p *pipe) closeWrite() error {
p.mu.Lock()
defer p.mu.Unlock()
p.writeClosed = true
// Signal all blocked readers and writers to return an error.
p.rwait.Broadcast()
p.wwait.Broadcast()
return nil
}
type conn struct {
io.Reader
io.Writer
}
func (c *conn) Close() error {
err1 := c.Reader.(*pipe).Close()
err2 := c.Writer.(*pipe).closeWrite()
if err1 != nil {
return err1
}
return err2
}
func (*conn) LocalAddr() net.Addr { return addr{} }
func (*conn) RemoteAddr() net.Addr { return addr{} }
func (c *conn) SetDeadline(t time.Time) error { return fmt.Errorf("unsupported") }
func (c *conn) SetReadDeadline(t time.Time) error { return fmt.Errorf("unsupported") }
func (c *conn) SetWriteDeadline(t time.Time) error { return fmt.Errorf("unsupported") }
type addr struct{}
func (addr) Network() string { return "bufconn" }
func (addr) String() string { return "bufconn" }

View File

@@ -0,0 +1,199 @@
/*
*
* Copyright 2017 gRPC authors.
*
* 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 bufconn
import (
"fmt"
"io"
"net"
"reflect"
"testing"
"time"
)
func testRW(r io.Reader, w io.Writer) error {
for i := 0; i < 20; i++ {
d := make([]byte, i)
for j := 0; j < i; j++ {
d[j] = byte(i - j)
}
var rn int
var rerr error
b := make([]byte, i)
done := make(chan struct{})
go func() {
for rn < len(b) && rerr == nil {
var x int
x, rerr = r.Read(b[rn:])
rn += x
}
close(done)
}()
wn, werr := w.Write(d)
if wn != i || werr != nil {
return fmt.Errorf("%v: w.Write(%v) = %v, %v; want %v, nil", i, d, wn, werr, i)
}
select {
case <-done:
case <-time.After(500 * time.Millisecond):
return fmt.Errorf("%v: r.Read never returned", i)
}
if rn != i || rerr != nil {
return fmt.Errorf("%v: r.Read = %v, %v; want %v, nil", i, rn, rerr, i)
}
if !reflect.DeepEqual(b, d) {
return fmt.Errorf("%v: r.Read read %v; want %v", i, b, d)
}
}
return nil
}
func TestPipe(t *testing.T) {
p := newPipe(10)
if err := testRW(p, p); err != nil {
t.Fatalf(err.Error())
}
}
func TestPipeClose(t *testing.T) {
p := newPipe(10)
p.Close()
if _, err := p.Write(nil); err != io.ErrClosedPipe {
t.Fatalf("p.Write = _, %v; want _, %v", err, io.ErrClosedPipe)
}
if _, err := p.Read(nil); err != io.ErrClosedPipe {
t.Fatalf("p.Read = _, %v; want _, %v", err, io.ErrClosedPipe)
}
}
func TestConn(t *testing.T) {
p1, p2 := newPipe(10), newPipe(10)
c1, c2 := &conn{p1, p2}, &conn{p2, p1}
if err := testRW(c1, c2); err != nil {
t.Fatalf(err.Error())
}
if err := testRW(c2, c1); err != nil {
t.Fatalf(err.Error())
}
}
func TestConnCloseWithData(t *testing.T) {
lis := Listen(7)
errChan := make(chan error)
var lisConn net.Conn
go func() {
var err error
if lisConn, err = lis.Accept(); err != nil {
errChan <- err
}
close(errChan)
}()
dialConn, err := lis.Dial()
if err != nil {
t.Fatalf("Dial error: %v", err)
}
if err := <-errChan; err != nil {
t.Fatalf("Listen error: %v", err)
}
// Write some data on both sides of the connection.
n, err := dialConn.Write([]byte("hello"))
if n != 5 || err != nil {
t.Fatalf("dialConn.Write([]byte{\"hello\"}) = %v, %v; want 5, <nil>", n, err)
}
n, err = lisConn.Write([]byte("hello"))
if n != 5 || err != nil {
t.Fatalf("lisConn.Write([]byte{\"hello\"}) = %v, %v; want 5, <nil>", n, err)
}
// Close dial-side; writes from either side should fail.
dialConn.Close()
if _, err := lisConn.Write([]byte("hello")); err != io.ErrClosedPipe {
t.Fatalf("lisConn.Write() = _, <nil>; want _, <non-nil>")
}
if _, err := dialConn.Write([]byte("hello")); err != io.ErrClosedPipe {
t.Fatalf("dialConn.Write() = _, <nil>; want _, <non-nil>")
}
// Read from both sides; reads on lisConn should work, but dialConn should
// fail.
buf := make([]byte, 6)
if _, err := dialConn.Read(buf); err != io.ErrClosedPipe {
t.Fatalf("dialConn.Read(buf) = %v, %v; want _, io.ErrClosedPipe", n, err)
}
n, err = lisConn.Read(buf)
if n != 5 || err != nil {
t.Fatalf("lisConn.Read(buf) = %v, %v; want 5, <nil>", n, err)
}
}
func TestListener(t *testing.T) {
l := Listen(7)
var s net.Conn
var serr error
done := make(chan struct{})
go func() {
s, serr = l.Accept()
close(done)
}()
c, cerr := l.Dial()
<-done
if cerr != nil || serr != nil {
t.Fatalf("cerr = %v, serr = %v; want nil, nil", cerr, serr)
}
if err := testRW(c, s); err != nil {
t.Fatalf(err.Error())
}
if err := testRW(s, c); err != nil {
t.Fatalf(err.Error())
}
}
func TestCloseWhileDialing(t *testing.T) {
l := Listen(7)
var c net.Conn
var err error
done := make(chan struct{})
go func() {
c, err = l.Dial()
close(done)
}()
l.Close()
<-done
if c != nil || err != errClosed {
t.Fatalf("c, err = %v, %v; want nil, %v", c, err, errClosed)
}
}
func TestCloseWhileAccepting(t *testing.T) {
l := Listen(7)
var c net.Conn
var err error
done := make(chan struct{})
go func() {
c, err = l.Accept()
close(done)
}()
l.Close()
<-done
if c != nil || err != errClosed {
t.Fatalf("c, err = %v, %v; want nil, %v", c, err, errClosed)
}
}

1198
vendor/google.golang.org/grpc/test/channelz_test.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: codec_perf/perf.proto
package codec_perf
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Buffer is a message that contains a body of bytes that is used to exercise
// encoding and decoding overheads.
type Buffer struct {
Body []byte `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Buffer) Reset() { *m = Buffer{} }
func (m *Buffer) String() string { return proto.CompactTextString(m) }
func (*Buffer) ProtoMessage() {}
func (*Buffer) Descriptor() ([]byte, []int) {
return fileDescriptor_perf_6cc81a33b24d08e7, []int{0}
}
func (m *Buffer) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Buffer.Unmarshal(m, b)
}
func (m *Buffer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Buffer.Marshal(b, m, deterministic)
}
func (dst *Buffer) XXX_Merge(src proto.Message) {
xxx_messageInfo_Buffer.Merge(dst, src)
}
func (m *Buffer) XXX_Size() int {
return xxx_messageInfo_Buffer.Size(m)
}
func (m *Buffer) XXX_DiscardUnknown() {
xxx_messageInfo_Buffer.DiscardUnknown(m)
}
var xxx_messageInfo_Buffer proto.InternalMessageInfo
func (m *Buffer) GetBody() []byte {
if m != nil {
return m.Body
}
return nil
}
func init() {
proto.RegisterType((*Buffer)(nil), "codec.perf.Buffer")
}
func init() { proto.RegisterFile("codec_perf/perf.proto", fileDescriptor_perf_6cc81a33b24d08e7) }
var fileDescriptor_perf_6cc81a33b24d08e7 = []byte{
// 83 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4d, 0xce, 0x4f, 0x49,
0x4d, 0x8e, 0x2f, 0x48, 0x2d, 0x4a, 0xd3, 0x07, 0x11, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42,
0x5c, 0x60, 0x61, 0x3d, 0x90, 0x88, 0x92, 0x0c, 0x17, 0x9b, 0x53, 0x69, 0x5a, 0x5a, 0x6a, 0x91,
0x90, 0x10, 0x17, 0x4b, 0x52, 0x7e, 0x4a, 0xa5, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x98,
0x9d, 0xc4, 0x06, 0xd6, 0x60, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x5f, 0x4f, 0x3c, 0x49,
0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,25 @@
// Copyright 2017 gRPC authors.
//
// 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.
// Messages used for performance tests that may not reference grpc directly for
// reasons of import cycles.
syntax = "proto3";
package codec.perf;
// Buffer is a message that contains a body of bytes that is used to exercise
// encoding and decoding overheads.
message Buffer {
bytes body = 1;
}

6274
vendor/google.golang.org/grpc/test/end2end_test.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

215
vendor/google.golang.org/grpc/test/gracefulstop_test.go generated vendored Normal file
View File

@@ -0,0 +1,215 @@
/*
*
* Copyright 2017 gRPC authors.
*
* 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 test
import (
"fmt"
"net"
"sync"
"testing"
"time"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/test/leakcheck"
testpb "google.golang.org/grpc/test/grpc_testing"
)
type delayListener struct {
net.Listener
closeCalled chan struct{}
acceptCalled chan struct{}
allowCloseCh chan struct{}
cc *delayConn
dialed bool
}
func (d *delayListener) Accept() (net.Conn, error) {
select {
case <-d.acceptCalled:
// On the second call, block until closed, then return an error.
<-d.closeCalled
<-d.allowCloseCh
return nil, fmt.Errorf("listener is closed")
default:
close(d.acceptCalled)
return d.Listener.Accept()
}
}
func (d *delayListener) allowClose() {
close(d.allowCloseCh)
}
func (d *delayListener) Close() error {
close(d.closeCalled)
go func() {
<-d.allowCloseCh
d.Listener.Close()
}()
return nil
}
func (d *delayListener) allowClientRead() {
d.cc.allowRead()
}
func (d *delayListener) Dial(to time.Duration) (net.Conn, error) {
if d.dialed {
// Only hand out one connection (net.Dial can return more even after the
// listener is closed). This is not thread-safe, but Dial should never be
// called concurrently in this environment.
return nil, fmt.Errorf("no more conns")
}
d.dialed = true
c, err := net.DialTimeout("tcp", d.Listener.Addr().String(), to)
if err != nil {
return nil, err
}
d.cc = &delayConn{Conn: c, blockRead: make(chan struct{})}
return d.cc, nil
}
func (d *delayListener) clientWriteCalledChan() <-chan struct{} {
return d.cc.writeCalledChan()
}
type delayConn struct {
net.Conn
blockRead chan struct{}
mu sync.Mutex
writeCalled chan struct{}
}
func (d *delayConn) writeCalledChan() <-chan struct{} {
d.mu.Lock()
defer d.mu.Unlock()
d.writeCalled = make(chan struct{})
return d.writeCalled
}
func (d *delayConn) allowRead() {
close(d.blockRead)
}
func (d *delayConn) Read(b []byte) (n int, err error) {
<-d.blockRead
return d.Conn.Read(b)
}
func (d *delayConn) Write(b []byte) (n int, err error) {
d.mu.Lock()
if d.writeCalled != nil {
close(d.writeCalled)
d.writeCalled = nil
}
d.mu.Unlock()
return d.Conn.Write(b)
}
func TestGracefulStop(t *testing.T) {
defer leakcheck.Check(t)
// This test ensures GracefulStop cannot race and break RPCs on new
// connections created after GracefulStop was called but before
// listener.Accept() returns a "closing" error.
//
// Steps of this test:
// 1. Start Server
// 2. GracefulStop() Server after listener's Accept is called, but don't
// allow Accept() to exit when Close() is called on it.
// 3. Create a new connection to the server after listener.Close() is called.
// Server will want to send a GoAway on the new conn, but we delay client
// reads until 5.
// 4. Send an RPC on the new connection.
// 5. Allow the client to read the GoAway. The RPC should complete
// successfully.
lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("Error listenening: %v", err)
}
dlis := &delayListener{
Listener: lis,
acceptCalled: make(chan struct{}),
closeCalled: make(chan struct{}),
allowCloseCh: make(chan struct{}),
}
d := func(_ string, to time.Duration) (net.Conn, error) { return dlis.Dial(to) }
ss := &stubServer{
emptyCall: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
return &testpb.Empty{}, nil
},
}
s := grpc.NewServer()
testpb.RegisterTestServiceServer(s, ss)
// 1. Start Server
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
s.Serve(dlis)
wg.Done()
}()
// 2. GracefulStop() Server after listener's Accept is called, but don't
// allow Accept() to exit when Close() is called on it.
<-dlis.acceptCalled
wg.Add(1)
go func() {
s.GracefulStop()
wg.Done()
}()
// 3. Create a new connection to the server after listener.Close() is called.
// Server will want to send a GoAway on the new conn, but we delay it
// until 5.
<-dlis.closeCalled // Block until GracefulStop calls dlis.Close()
// Now dial. The listener's Accept method will return a valid connection,
// even though GracefulStop has closed the listener.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
cc, err := grpc.DialContext(ctx, "", grpc.WithInsecure(), grpc.WithBlock(), grpc.WithDialer(d))
if err != nil {
t.Fatalf("grpc.Dial(%q) = %v", lis.Addr().String(), err)
}
cancel()
client := testpb.NewTestServiceClient(cc)
defer cc.Close()
dlis.allowClose()
wcch := dlis.clientWriteCalledChan()
go func() {
// 5. Allow the client to read the GoAway. The RPC should complete
// successfully.
<-wcch
dlis.allowClientRead()
}()
// 4. Send an RPC on the new connection.
// The server would send a GOAWAY first, but we are delaying the server's
// writes for now until the client writes more than the preface.
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
if _, err := client.EmptyCall(ctx, &testpb.Empty{}); err != nil {
t.Fatalf("EmptyCall() = %v; want <nil>", err)
}
// 5. happens above, then we finish the call.
cancel()
wg.Wait()
}

View File

@@ -0,0 +1,949 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: grpc_testing/test.proto
package grpc_testing
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// The type of payload that should be returned.
type PayloadType int32
const (
// Compressable text format.
PayloadType_COMPRESSABLE PayloadType = 0
// Uncompressable binary format.
PayloadType_UNCOMPRESSABLE PayloadType = 1
// Randomly chosen from all other formats defined in this enum.
PayloadType_RANDOM PayloadType = 2
)
var PayloadType_name = map[int32]string{
0: "COMPRESSABLE",
1: "UNCOMPRESSABLE",
2: "RANDOM",
}
var PayloadType_value = map[string]int32{
"COMPRESSABLE": 0,
"UNCOMPRESSABLE": 1,
"RANDOM": 2,
}
func (x PayloadType) String() string {
return proto.EnumName(PayloadType_name, int32(x))
}
func (PayloadType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{0}
}
type Empty struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{0}
}
func (m *Empty) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Empty.Unmarshal(m, b)
}
func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
}
func (dst *Empty) XXX_Merge(src proto.Message) {
xxx_messageInfo_Empty.Merge(dst, src)
}
func (m *Empty) XXX_Size() int {
return xxx_messageInfo_Empty.Size(m)
}
func (m *Empty) XXX_DiscardUnknown() {
xxx_messageInfo_Empty.DiscardUnknown(m)
}
var xxx_messageInfo_Empty proto.InternalMessageInfo
// A block of data, to simply increase gRPC message size.
type Payload struct {
// The type of data in body.
Type PayloadType `protobuf:"varint,1,opt,name=type,enum=grpc.testing.PayloadType" json:"type,omitempty"`
// Primary contents of payload.
Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Payload) Reset() { *m = Payload{} }
func (m *Payload) String() string { return proto.CompactTextString(m) }
func (*Payload) ProtoMessage() {}
func (*Payload) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{1}
}
func (m *Payload) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Payload.Unmarshal(m, b)
}
func (m *Payload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Payload.Marshal(b, m, deterministic)
}
func (dst *Payload) XXX_Merge(src proto.Message) {
xxx_messageInfo_Payload.Merge(dst, src)
}
func (m *Payload) XXX_Size() int {
return xxx_messageInfo_Payload.Size(m)
}
func (m *Payload) XXX_DiscardUnknown() {
xxx_messageInfo_Payload.DiscardUnknown(m)
}
var xxx_messageInfo_Payload proto.InternalMessageInfo
func (m *Payload) GetType() PayloadType {
if m != nil {
return m.Type
}
return PayloadType_COMPRESSABLE
}
func (m *Payload) GetBody() []byte {
if m != nil {
return m.Body
}
return nil
}
// Unary request.
type SimpleRequest struct {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
ResponseType PayloadType `protobuf:"varint,1,opt,name=response_type,json=responseType,enum=grpc.testing.PayloadType" json:"response_type,omitempty"`
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
ResponseSize int32 `protobuf:"varint,2,opt,name=response_size,json=responseSize" json:"response_size,omitempty"`
// Optional input payload sent along with the request.
Payload *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"`
// Whether SimpleResponse should include username.
FillUsername bool `protobuf:"varint,4,opt,name=fill_username,json=fillUsername" json:"fill_username,omitempty"`
// Whether SimpleResponse should include OAuth scope.
FillOauthScope bool `protobuf:"varint,5,opt,name=fill_oauth_scope,json=fillOauthScope" json:"fill_oauth_scope,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SimpleRequest) Reset() { *m = SimpleRequest{} }
func (m *SimpleRequest) String() string { return proto.CompactTextString(m) }
func (*SimpleRequest) ProtoMessage() {}
func (*SimpleRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{2}
}
func (m *SimpleRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SimpleRequest.Unmarshal(m, b)
}
func (m *SimpleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SimpleRequest.Marshal(b, m, deterministic)
}
func (dst *SimpleRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SimpleRequest.Merge(dst, src)
}
func (m *SimpleRequest) XXX_Size() int {
return xxx_messageInfo_SimpleRequest.Size(m)
}
func (m *SimpleRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SimpleRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SimpleRequest proto.InternalMessageInfo
func (m *SimpleRequest) GetResponseType() PayloadType {
if m != nil {
return m.ResponseType
}
return PayloadType_COMPRESSABLE
}
func (m *SimpleRequest) GetResponseSize() int32 {
if m != nil {
return m.ResponseSize
}
return 0
}
func (m *SimpleRequest) GetPayload() *Payload {
if m != nil {
return m.Payload
}
return nil
}
func (m *SimpleRequest) GetFillUsername() bool {
if m != nil {
return m.FillUsername
}
return false
}
func (m *SimpleRequest) GetFillOauthScope() bool {
if m != nil {
return m.FillOauthScope
}
return false
}
// Unary response, as configured by the request.
type SimpleResponse struct {
// Payload to increase message size.
Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
// The user the request came from, for verifying authentication was
// successful when the client expected it.
Username string `protobuf:"bytes,2,opt,name=username" json:"username,omitempty"`
// OAuth scope.
OauthScope string `protobuf:"bytes,3,opt,name=oauth_scope,json=oauthScope" json:"oauth_scope,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SimpleResponse) Reset() { *m = SimpleResponse{} }
func (m *SimpleResponse) String() string { return proto.CompactTextString(m) }
func (*SimpleResponse) ProtoMessage() {}
func (*SimpleResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{3}
}
func (m *SimpleResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SimpleResponse.Unmarshal(m, b)
}
func (m *SimpleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SimpleResponse.Marshal(b, m, deterministic)
}
func (dst *SimpleResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SimpleResponse.Merge(dst, src)
}
func (m *SimpleResponse) XXX_Size() int {
return xxx_messageInfo_SimpleResponse.Size(m)
}
func (m *SimpleResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SimpleResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SimpleResponse proto.InternalMessageInfo
func (m *SimpleResponse) GetPayload() *Payload {
if m != nil {
return m.Payload
}
return nil
}
func (m *SimpleResponse) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *SimpleResponse) GetOauthScope() string {
if m != nil {
return m.OauthScope
}
return ""
}
// Client-streaming request.
type StreamingInputCallRequest struct {
// Optional input payload sent along with the request.
Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StreamingInputCallRequest) Reset() { *m = StreamingInputCallRequest{} }
func (m *StreamingInputCallRequest) String() string { return proto.CompactTextString(m) }
func (*StreamingInputCallRequest) ProtoMessage() {}
func (*StreamingInputCallRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{4}
}
func (m *StreamingInputCallRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StreamingInputCallRequest.Unmarshal(m, b)
}
func (m *StreamingInputCallRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StreamingInputCallRequest.Marshal(b, m, deterministic)
}
func (dst *StreamingInputCallRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_StreamingInputCallRequest.Merge(dst, src)
}
func (m *StreamingInputCallRequest) XXX_Size() int {
return xxx_messageInfo_StreamingInputCallRequest.Size(m)
}
func (m *StreamingInputCallRequest) XXX_DiscardUnknown() {
xxx_messageInfo_StreamingInputCallRequest.DiscardUnknown(m)
}
var xxx_messageInfo_StreamingInputCallRequest proto.InternalMessageInfo
func (m *StreamingInputCallRequest) GetPayload() *Payload {
if m != nil {
return m.Payload
}
return nil
}
// Client-streaming response.
type StreamingInputCallResponse struct {
// Aggregated size of payloads received from the client.
AggregatedPayloadSize int32 `protobuf:"varint,1,opt,name=aggregated_payload_size,json=aggregatedPayloadSize" json:"aggregated_payload_size,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StreamingInputCallResponse) Reset() { *m = StreamingInputCallResponse{} }
func (m *StreamingInputCallResponse) String() string { return proto.CompactTextString(m) }
func (*StreamingInputCallResponse) ProtoMessage() {}
func (*StreamingInputCallResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{5}
}
func (m *StreamingInputCallResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StreamingInputCallResponse.Unmarshal(m, b)
}
func (m *StreamingInputCallResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StreamingInputCallResponse.Marshal(b, m, deterministic)
}
func (dst *StreamingInputCallResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_StreamingInputCallResponse.Merge(dst, src)
}
func (m *StreamingInputCallResponse) XXX_Size() int {
return xxx_messageInfo_StreamingInputCallResponse.Size(m)
}
func (m *StreamingInputCallResponse) XXX_DiscardUnknown() {
xxx_messageInfo_StreamingInputCallResponse.DiscardUnknown(m)
}
var xxx_messageInfo_StreamingInputCallResponse proto.InternalMessageInfo
func (m *StreamingInputCallResponse) GetAggregatedPayloadSize() int32 {
if m != nil {
return m.AggregatedPayloadSize
}
return 0
}
// Configuration for a particular response.
type ResponseParameters struct {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
Size int32 `protobuf:"varint,1,opt,name=size" json:"size,omitempty"`
// Desired interval between consecutive responses in the response stream in
// microseconds.
IntervalUs int32 `protobuf:"varint,2,opt,name=interval_us,json=intervalUs" json:"interval_us,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ResponseParameters) Reset() { *m = ResponseParameters{} }
func (m *ResponseParameters) String() string { return proto.CompactTextString(m) }
func (*ResponseParameters) ProtoMessage() {}
func (*ResponseParameters) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{6}
}
func (m *ResponseParameters) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ResponseParameters.Unmarshal(m, b)
}
func (m *ResponseParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ResponseParameters.Marshal(b, m, deterministic)
}
func (dst *ResponseParameters) XXX_Merge(src proto.Message) {
xxx_messageInfo_ResponseParameters.Merge(dst, src)
}
func (m *ResponseParameters) XXX_Size() int {
return xxx_messageInfo_ResponseParameters.Size(m)
}
func (m *ResponseParameters) XXX_DiscardUnknown() {
xxx_messageInfo_ResponseParameters.DiscardUnknown(m)
}
var xxx_messageInfo_ResponseParameters proto.InternalMessageInfo
func (m *ResponseParameters) GetSize() int32 {
if m != nil {
return m.Size
}
return 0
}
func (m *ResponseParameters) GetIntervalUs() int32 {
if m != nil {
return m.IntervalUs
}
return 0
}
// Server-streaming request.
type StreamingOutputCallRequest struct {
// Desired payload type in the response from the server.
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
ResponseType PayloadType `protobuf:"varint,1,opt,name=response_type,json=responseType,enum=grpc.testing.PayloadType" json:"response_type,omitempty"`
// Configuration for each expected response message.
ResponseParameters []*ResponseParameters `protobuf:"bytes,2,rep,name=response_parameters,json=responseParameters" json:"response_parameters,omitempty"`
// Optional input payload sent along with the request.
Payload *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StreamingOutputCallRequest) Reset() { *m = StreamingOutputCallRequest{} }
func (m *StreamingOutputCallRequest) String() string { return proto.CompactTextString(m) }
func (*StreamingOutputCallRequest) ProtoMessage() {}
func (*StreamingOutputCallRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{7}
}
func (m *StreamingOutputCallRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StreamingOutputCallRequest.Unmarshal(m, b)
}
func (m *StreamingOutputCallRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StreamingOutputCallRequest.Marshal(b, m, deterministic)
}
func (dst *StreamingOutputCallRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_StreamingOutputCallRequest.Merge(dst, src)
}
func (m *StreamingOutputCallRequest) XXX_Size() int {
return xxx_messageInfo_StreamingOutputCallRequest.Size(m)
}
func (m *StreamingOutputCallRequest) XXX_DiscardUnknown() {
xxx_messageInfo_StreamingOutputCallRequest.DiscardUnknown(m)
}
var xxx_messageInfo_StreamingOutputCallRequest proto.InternalMessageInfo
func (m *StreamingOutputCallRequest) GetResponseType() PayloadType {
if m != nil {
return m.ResponseType
}
return PayloadType_COMPRESSABLE
}
func (m *StreamingOutputCallRequest) GetResponseParameters() []*ResponseParameters {
if m != nil {
return m.ResponseParameters
}
return nil
}
func (m *StreamingOutputCallRequest) GetPayload() *Payload {
if m != nil {
return m.Payload
}
return nil
}
// Server-streaming response, as configured by the request and parameters.
type StreamingOutputCallResponse struct {
// Payload to increase response size.
Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StreamingOutputCallResponse) Reset() { *m = StreamingOutputCallResponse{} }
func (m *StreamingOutputCallResponse) String() string { return proto.CompactTextString(m) }
func (*StreamingOutputCallResponse) ProtoMessage() {}
func (*StreamingOutputCallResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_test_c9f6c5af4267cb88, []int{8}
}
func (m *StreamingOutputCallResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StreamingOutputCallResponse.Unmarshal(m, b)
}
func (m *StreamingOutputCallResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StreamingOutputCallResponse.Marshal(b, m, deterministic)
}
func (dst *StreamingOutputCallResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_StreamingOutputCallResponse.Merge(dst, src)
}
func (m *StreamingOutputCallResponse) XXX_Size() int {
return xxx_messageInfo_StreamingOutputCallResponse.Size(m)
}
func (m *StreamingOutputCallResponse) XXX_DiscardUnknown() {
xxx_messageInfo_StreamingOutputCallResponse.DiscardUnknown(m)
}
var xxx_messageInfo_StreamingOutputCallResponse proto.InternalMessageInfo
func (m *StreamingOutputCallResponse) GetPayload() *Payload {
if m != nil {
return m.Payload
}
return nil
}
func init() {
proto.RegisterType((*Empty)(nil), "grpc.testing.Empty")
proto.RegisterType((*Payload)(nil), "grpc.testing.Payload")
proto.RegisterType((*SimpleRequest)(nil), "grpc.testing.SimpleRequest")
proto.RegisterType((*SimpleResponse)(nil), "grpc.testing.SimpleResponse")
proto.RegisterType((*StreamingInputCallRequest)(nil), "grpc.testing.StreamingInputCallRequest")
proto.RegisterType((*StreamingInputCallResponse)(nil), "grpc.testing.StreamingInputCallResponse")
proto.RegisterType((*ResponseParameters)(nil), "grpc.testing.ResponseParameters")
proto.RegisterType((*StreamingOutputCallRequest)(nil), "grpc.testing.StreamingOutputCallRequest")
proto.RegisterType((*StreamingOutputCallResponse)(nil), "grpc.testing.StreamingOutputCallResponse")
proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value)
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for TestService service
type TestServiceClient interface {
// One empty request followed by one empty response.
EmptyCall(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
// One request followed by one response.
// The server returns the client payload as-is.
UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error)
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
StreamingOutputCall(ctx context.Context, in *StreamingOutputCallRequest, opts ...grpc.CallOption) (TestService_StreamingOutputCallClient, error)
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
StreamingInputCall(ctx context.Context, opts ...grpc.CallOption) (TestService_StreamingInputCallClient, error)
// A sequence of requests with each request served by the server immediately.
// As one request could lead to multiple responses, this interface
// demonstrates the idea of full duplexing.
FullDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_FullDuplexCallClient, error)
// A sequence of requests followed by a sequence of responses.
// The server buffers all the client requests and then serves them in order. A
// stream of responses are returned to the client when the server starts with
// first request.
HalfDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_HalfDuplexCallClient, error)
}
type testServiceClient struct {
cc *grpc.ClientConn
}
func NewTestServiceClient(cc *grpc.ClientConn) TestServiceClient {
return &testServiceClient{cc}
}
func (c *testServiceClient) EmptyCall(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
out := new(Empty)
err := grpc.Invoke(ctx, "/grpc.testing.TestService/EmptyCall", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error) {
out := new(SimpleResponse)
err := grpc.Invoke(ctx, "/grpc.testing.TestService/UnaryCall", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *testServiceClient) StreamingOutputCall(ctx context.Context, in *StreamingOutputCallRequest, opts ...grpc.CallOption) (TestService_StreamingOutputCallClient, error) {
stream, err := grpc.NewClientStream(ctx, &_TestService_serviceDesc.Streams[0], c.cc, "/grpc.testing.TestService/StreamingOutputCall", opts...)
if err != nil {
return nil, err
}
x := &testServiceStreamingOutputCallClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type TestService_StreamingOutputCallClient interface {
Recv() (*StreamingOutputCallResponse, error)
grpc.ClientStream
}
type testServiceStreamingOutputCallClient struct {
grpc.ClientStream
}
func (x *testServiceStreamingOutputCallClient) Recv() (*StreamingOutputCallResponse, error) {
m := new(StreamingOutputCallResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *testServiceClient) StreamingInputCall(ctx context.Context, opts ...grpc.CallOption) (TestService_StreamingInputCallClient, error) {
stream, err := grpc.NewClientStream(ctx, &_TestService_serviceDesc.Streams[1], c.cc, "/grpc.testing.TestService/StreamingInputCall", opts...)
if err != nil {
return nil, err
}
x := &testServiceStreamingInputCallClient{stream}
return x, nil
}
type TestService_StreamingInputCallClient interface {
Send(*StreamingInputCallRequest) error
CloseAndRecv() (*StreamingInputCallResponse, error)
grpc.ClientStream
}
type testServiceStreamingInputCallClient struct {
grpc.ClientStream
}
func (x *testServiceStreamingInputCallClient) Send(m *StreamingInputCallRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *testServiceStreamingInputCallClient) CloseAndRecv() (*StreamingInputCallResponse, error) {
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
m := new(StreamingInputCallResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *testServiceClient) FullDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_FullDuplexCallClient, error) {
stream, err := grpc.NewClientStream(ctx, &_TestService_serviceDesc.Streams[2], c.cc, "/grpc.testing.TestService/FullDuplexCall", opts...)
if err != nil {
return nil, err
}
x := &testServiceFullDuplexCallClient{stream}
return x, nil
}
type TestService_FullDuplexCallClient interface {
Send(*StreamingOutputCallRequest) error
Recv() (*StreamingOutputCallResponse, error)
grpc.ClientStream
}
type testServiceFullDuplexCallClient struct {
grpc.ClientStream
}
func (x *testServiceFullDuplexCallClient) Send(m *StreamingOutputCallRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *testServiceFullDuplexCallClient) Recv() (*StreamingOutputCallResponse, error) {
m := new(StreamingOutputCallResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *testServiceClient) HalfDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_HalfDuplexCallClient, error) {
stream, err := grpc.NewClientStream(ctx, &_TestService_serviceDesc.Streams[3], c.cc, "/grpc.testing.TestService/HalfDuplexCall", opts...)
if err != nil {
return nil, err
}
x := &testServiceHalfDuplexCallClient{stream}
return x, nil
}
type TestService_HalfDuplexCallClient interface {
Send(*StreamingOutputCallRequest) error
Recv() (*StreamingOutputCallResponse, error)
grpc.ClientStream
}
type testServiceHalfDuplexCallClient struct {
grpc.ClientStream
}
func (x *testServiceHalfDuplexCallClient) Send(m *StreamingOutputCallRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *testServiceHalfDuplexCallClient) Recv() (*StreamingOutputCallResponse, error) {
m := new(StreamingOutputCallResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// Server API for TestService service
type TestServiceServer interface {
// One empty request followed by one empty response.
EmptyCall(context.Context, *Empty) (*Empty, error)
// One request followed by one response.
// The server returns the client payload as-is.
UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error)
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
StreamingInputCall(TestService_StreamingInputCallServer) error
// A sequence of requests with each request served by the server immediately.
// As one request could lead to multiple responses, this interface
// demonstrates the idea of full duplexing.
FullDuplexCall(TestService_FullDuplexCallServer) error
// A sequence of requests followed by a sequence of responses.
// The server buffers all the client requests and then serves them in order. A
// stream of responses are returned to the client when the server starts with
// first request.
HalfDuplexCall(TestService_HalfDuplexCallServer) error
}
func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) {
s.RegisterService(&_TestService_serviceDesc, srv)
}
func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TestServiceServer).EmptyCall(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/grpc.testing.TestService/EmptyCall",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TestServiceServer).EmptyCall(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SimpleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TestServiceServer).UnaryCall(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/grpc.testing.TestService/UnaryCall",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TestServiceServer).UnaryCall(ctx, req.(*SimpleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _TestService_StreamingOutputCall_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(StreamingOutputCallRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(TestServiceServer).StreamingOutputCall(m, &testServiceStreamingOutputCallServer{stream})
}
type TestService_StreamingOutputCallServer interface {
Send(*StreamingOutputCallResponse) error
grpc.ServerStream
}
type testServiceStreamingOutputCallServer struct {
grpc.ServerStream
}
func (x *testServiceStreamingOutputCallServer) Send(m *StreamingOutputCallResponse) error {
return x.ServerStream.SendMsg(m)
}
func _TestService_StreamingInputCall_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(TestServiceServer).StreamingInputCall(&testServiceStreamingInputCallServer{stream})
}
type TestService_StreamingInputCallServer interface {
SendAndClose(*StreamingInputCallResponse) error
Recv() (*StreamingInputCallRequest, error)
grpc.ServerStream
}
type testServiceStreamingInputCallServer struct {
grpc.ServerStream
}
func (x *testServiceStreamingInputCallServer) SendAndClose(m *StreamingInputCallResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *testServiceStreamingInputCallServer) Recv() (*StreamingInputCallRequest, error) {
m := new(StreamingInputCallRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _TestService_FullDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(TestServiceServer).FullDuplexCall(&testServiceFullDuplexCallServer{stream})
}
type TestService_FullDuplexCallServer interface {
Send(*StreamingOutputCallResponse) error
Recv() (*StreamingOutputCallRequest, error)
grpc.ServerStream
}
type testServiceFullDuplexCallServer struct {
grpc.ServerStream
}
func (x *testServiceFullDuplexCallServer) Send(m *StreamingOutputCallResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *testServiceFullDuplexCallServer) Recv() (*StreamingOutputCallRequest, error) {
m := new(StreamingOutputCallRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _TestService_HalfDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(TestServiceServer).HalfDuplexCall(&testServiceHalfDuplexCallServer{stream})
}
type TestService_HalfDuplexCallServer interface {
Send(*StreamingOutputCallResponse) error
Recv() (*StreamingOutputCallRequest, error)
grpc.ServerStream
}
type testServiceHalfDuplexCallServer struct {
grpc.ServerStream
}
func (x *testServiceHalfDuplexCallServer) Send(m *StreamingOutputCallResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *testServiceHalfDuplexCallServer) Recv() (*StreamingOutputCallRequest, error) {
m := new(StreamingOutputCallRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
var _TestService_serviceDesc = grpc.ServiceDesc{
ServiceName: "grpc.testing.TestService",
HandlerType: (*TestServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "EmptyCall",
Handler: _TestService_EmptyCall_Handler,
},
{
MethodName: "UnaryCall",
Handler: _TestService_UnaryCall_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "StreamingOutputCall",
Handler: _TestService_StreamingOutputCall_Handler,
ServerStreams: true,
},
{
StreamName: "StreamingInputCall",
Handler: _TestService_StreamingInputCall_Handler,
ClientStreams: true,
},
{
StreamName: "FullDuplexCall",
Handler: _TestService_FullDuplexCall_Handler,
ServerStreams: true,
ClientStreams: true,
},
{
StreamName: "HalfDuplexCall",
Handler: _TestService_HalfDuplexCall_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "grpc_testing/test.proto",
}
func init() { proto.RegisterFile("grpc_testing/test.proto", fileDescriptor_test_c9f6c5af4267cb88) }
var fileDescriptor_test_c9f6c5af4267cb88 = []byte{
// 587 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xdb, 0x6e, 0xd3, 0x40,
0x10, 0x65, 0xdb, 0xf4, 0x36, 0x49, 0xad, 0x68, 0xab, 0xaa, 0xae, 0x8b, 0x84, 0x65, 0x1e, 0x30,
0x48, 0xa4, 0x28, 0x08, 0x1e, 0x41, 0xa5, 0x17, 0x51, 0x29, 0x4d, 0x82, 0x9d, 0x3c, 0x47, 0xdb,
0x64, 0x6b, 0x2c, 0x39, 0xf6, 0xb2, 0x5e, 0x57, 0xa4, 0x0f, 0xfc, 0x18, 0x3f, 0xc3, 0x47, 0xf0,
0x01, 0x68, 0xd7, 0x76, 0xe2, 0x24, 0xae, 0x48, 0x41, 0xf0, 0x14, 0x7b, 0xe6, 0xcc, 0x99, 0x73,
0x3c, 0xb3, 0x1b, 0x38, 0xf0, 0x38, 0x1b, 0x0e, 0x04, 0x8d, 0x85, 0x1f, 0x7a, 0xc7, 0xf2, 0xb7,
0xc1, 0x78, 0x24, 0x22, 0x5c, 0x93, 0x89, 0x46, 0x96, 0xb0, 0xb6, 0x60, 0xe3, 0x7c, 0xcc, 0xc4,
0xc4, 0x6a, 0xc1, 0x56, 0x97, 0x4c, 0x82, 0x88, 0x8c, 0xf0, 0x4b, 0xa8, 0x88, 0x09, 0xa3, 0x3a,
0x32, 0x91, 0xad, 0x35, 0x0f, 0x1b, 0xc5, 0x82, 0x46, 0x06, 0xea, 0x4d, 0x18, 0x75, 0x14, 0x0c,
0x63, 0xa8, 0x5c, 0x47, 0xa3, 0x89, 0xbe, 0x66, 0x22, 0xbb, 0xe6, 0xa8, 0x67, 0xeb, 0x27, 0x82,
0x5d, 0xd7, 0x1f, 0xb3, 0x80, 0x3a, 0xf4, 0x4b, 0x42, 0x63, 0x81, 0xdf, 0xc1, 0x2e, 0xa7, 0x31,
0x8b, 0xc2, 0x98, 0x0e, 0x56, 0x63, 0xaf, 0xe5, 0x78, 0xf9, 0x86, 0x9f, 0x16, 0xea, 0x63, 0xff,
0x8e, 0xaa, 0x76, 0x1b, 0x33, 0x90, 0xeb, 0xdf, 0x51, 0x7c, 0x0c, 0x5b, 0x2c, 0x65, 0xd0, 0xd7,
0x4d, 0x64, 0x57, 0x9b, 0xfb, 0xa5, 0xf4, 0x4e, 0x8e, 0x92, 0xac, 0x37, 0x7e, 0x10, 0x0c, 0x92,
0x98, 0xf2, 0x90, 0x8c, 0xa9, 0x5e, 0x31, 0x91, 0xbd, 0xed, 0xd4, 0x64, 0xb0, 0x9f, 0xc5, 0xb0,
0x0d, 0x75, 0x05, 0x8a, 0x48, 0x22, 0x3e, 0x0f, 0xe2, 0x61, 0xc4, 0xa8, 0xbe, 0xa1, 0x70, 0x9a,
0x8c, 0x77, 0x64, 0xd8, 0x95, 0x51, 0xeb, 0x1b, 0x68, 0xb9, 0xeb, 0x54, 0x55, 0x51, 0x11, 0x5a,
0x49, 0x91, 0x01, 0xdb, 0x53, 0x31, 0xd2, 0xe2, 0x8e, 0x33, 0x7d, 0xc7, 0x4f, 0xa0, 0x5a, 0xd4,
0xb0, 0xae, 0xd2, 0x10, 0xcd, 0xfa, 0xb7, 0xe0, 0xd0, 0x15, 0x9c, 0x92, 0xb1, 0x1f, 0x7a, 0x97,
0x21, 0x4b, 0xc4, 0x29, 0x09, 0x82, 0x7c, 0x02, 0x0f, 0x95, 0x62, 0xf5, 0xc0, 0x28, 0x63, 0xcb,
0x9c, 0xbd, 0x85, 0x03, 0xe2, 0x79, 0x9c, 0x7a, 0x44, 0xd0, 0xd1, 0x20, 0xab, 0x49, 0x47, 0x83,
0xd4, 0x68, 0xf6, 0x67, 0xe9, 0x8c, 0x5a, 0xce, 0xc8, 0xba, 0x04, 0x9c, 0x73, 0x74, 0x09, 0x27,
0x63, 0x2a, 0x28, 0x8f, 0xe5, 0x12, 0x15, 0x4a, 0xd5, 0xb3, 0xb4, 0xeb, 0x87, 0x82, 0xf2, 0x5b,
0x22, 0x07, 0x94, 0x0d, 0x1c, 0xf2, 0x50, 0x3f, 0xb6, 0x7e, 0xa0, 0x82, 0xc2, 0x4e, 0x22, 0x16,
0x0c, 0xff, 0xed, 0xca, 0x7d, 0x82, 0xbd, 0x69, 0x3d, 0x9b, 0x4a, 0xd5, 0xd7, 0xcc, 0x75, 0xbb,
0xda, 0x34, 0xe7, 0x59, 0x96, 0x2d, 0x39, 0x98, 0x2f, 0xdb, 0x7c, 0xe8, 0x82, 0x5a, 0x6d, 0x38,
0x2a, 0x75, 0xf8, 0x87, 0xeb, 0xf5, 0xe2, 0x3d, 0x54, 0x0b, 0x86, 0x71, 0x1d, 0x6a, 0xa7, 0x9d,
0xab, 0xae, 0x73, 0xee, 0xba, 0x27, 0x1f, 0x5a, 0xe7, 0xf5, 0x47, 0x18, 0x83, 0xd6, 0x6f, 0xcf,
0xc5, 0x10, 0x06, 0xd8, 0x74, 0x4e, 0xda, 0x67, 0x9d, 0xab, 0xfa, 0x5a, 0xf3, 0x7b, 0x05, 0xaa,
0x3d, 0x1a, 0x0b, 0x97, 0xf2, 0x5b, 0x7f, 0x48, 0xf1, 0x1b, 0xd8, 0x51, 0x17, 0x88, 0x94, 0x85,
0xf7, 0xe6, 0xbb, 0xab, 0x84, 0x51, 0x16, 0xc4, 0x17, 0xb0, 0xd3, 0x0f, 0x09, 0x4f, 0xcb, 0x8e,
0xe6, 0x11, 0x73, 0x17, 0x87, 0xf1, 0xb8, 0x3c, 0x99, 0x7d, 0x80, 0x00, 0xf6, 0x4a, 0xbe, 0x0f,
0xb6, 0x17, 0x8a, 0xee, 0x5d, 0x12, 0xe3, 0xf9, 0x0a, 0xc8, 0xb4, 0xd7, 0x2b, 0x84, 0x7d, 0xc0,
0xcb, 0x27, 0x02, 0x3f, 0xbb, 0x87, 0x62, 0xf1, 0x04, 0x1a, 0xf6, 0xef, 0x81, 0x69, 0x2b, 0x5b,
0xb6, 0xd2, 0x2e, 0x92, 0x20, 0x38, 0x4b, 0x58, 0x40, 0xbf, 0xfe, 0x33, 0x4f, 0x36, 0x52, 0xae,
0xb4, 0x8f, 0x24, 0xb8, 0xf9, 0x0f, 0xad, 0xae, 0x37, 0xd5, 0x7f, 0xd0, 0xeb, 0x5f, 0x01, 0x00,
0x00, 0xff, 0xff, 0x07, 0xc7, 0x76, 0x69, 0x9e, 0x06, 0x00, 0x00,
}

View File

@@ -0,0 +1,154 @@
// Copyright 2017 gRPC authors.
//
// 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.
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto3";
package grpc.testing;
message Empty {}
// The type of payload that should be returned.
enum PayloadType {
// Compressable text format.
COMPRESSABLE = 0;
// Uncompressable binary format.
UNCOMPRESSABLE = 1;
// Randomly chosen from all other formats defined in this enum.
RANDOM = 2;
}
// A block of data, to simply increase gRPC message size.
message Payload {
// The type of data in body.
PayloadType type = 1;
// Primary contents of payload.
bytes body = 2;
}
// Unary request.
message SimpleRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
PayloadType response_type = 1;
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
int32 response_size = 2;
// Optional input payload sent along with the request.
Payload payload = 3;
// Whether SimpleResponse should include username.
bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope.
bool fill_oauth_scope = 5;
}
// Unary response, as configured by the request.
message SimpleResponse {
// Payload to increase message size.
Payload payload = 1;
// The user the request came from, for verifying authentication was
// successful when the client expected it.
string username = 2;
// OAuth scope.
string oauth_scope = 3;
}
// Client-streaming request.
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
Payload payload = 1;
// Not expecting any payload from the response.
}
// Client-streaming response.
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
int32 aggregated_payload_size = 1;
}
// Configuration for a particular response.
message ResponseParameters {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
int32 interval_us = 2;
}
// Server-streaming request.
message StreamingOutputCallRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
PayloadType response_type = 1;
// Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
Payload payload = 3;
}
// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
// Payload to increase response size.
Payload payload = 1;
}
// A simple service to test the various types of RPCs and experiment with
// performance with various types of payload.
service TestService {
// One empty request followed by one empty response.
rpc EmptyCall(Empty) returns (Empty);
// One request followed by one response.
// The server returns the client payload as-is.
rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
rpc StreamingOutputCall(StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
rpc StreamingInputCall(stream StreamingInputCallRequest)
returns (StreamingInputCallResponse);
// A sequence of requests with each request served by the server immediately.
// As one request could lead to multiple responses, this interface
// demonstrates the idea of full duplexing.
rpc FullDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by a sequence of responses.
// The server buffers all the client requests and then serves them in order. A
// stream of responses are returned to the client when the server starts with
// first request.
rpc HalfDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
}

View File

@@ -0,0 +1,118 @@
/*
*
* Copyright 2017 gRPC authors.
*
* 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 leakcheck contains functions to check leaked goroutines.
//
// Call "defer leakcheck.Check(t)" at the beginning of tests.
package leakcheck
import (
"runtime"
"sort"
"strings"
"time"
)
var goroutinesToIgnore = []string{
"testing.Main(",
"testing.tRunner(",
"testing.(*M).",
"runtime.goexit",
"created by runtime.gc",
"created by runtime/trace.Start",
"interestingGoroutines",
"runtime.MHeap_Scavenger",
"signal.signal_recv",
"sigterm.handler",
"runtime_mcall",
"(*loggingT).flushDaemon",
"goroutine in C code",
}
// RegisterIgnoreGoroutine appends s into the ignore goroutine list. The
// goroutines whose stack trace contains s will not be identified as leaked
// goroutines. Not thread-safe, only call this function in init().
func RegisterIgnoreGoroutine(s string) {
goroutinesToIgnore = append(goroutinesToIgnore, s)
}
func ignore(g string) bool {
sl := strings.SplitN(g, "\n", 2)
if len(sl) != 2 {
return true
}
stack := strings.TrimSpace(sl[1])
if strings.HasPrefix(stack, "testing.RunTests") {
return true
}
if stack == "" {
return true
}
for _, s := range goroutinesToIgnore {
if strings.Contains(stack, s) {
return true
}
}
return false
}
// interestingGoroutines returns all goroutines we care about for the purpose of
// leak checking. It excludes testing or runtime ones.
func interestingGoroutines() (gs []string) {
buf := make([]byte, 2<<20)
buf = buf[:runtime.Stack(buf, true)]
for _, g := range strings.Split(string(buf), "\n\n") {
if !ignore(g) {
gs = append(gs, g)
}
}
sort.Strings(gs)
return
}
// Errorfer is the interface that wraps the Errorf method. It's a subset of
// testing.TB to make it easy to use Check.
type Errorfer interface {
Errorf(format string, args ...interface{})
}
func check(efer Errorfer, timeout time.Duration) {
// Loop, waiting for goroutines to shut down.
// Wait up to timeout, but finish as quickly as possible.
deadline := time.Now().Add(timeout)
var leaked []string
for time.Now().Before(deadline) {
if leaked = interestingGoroutines(); len(leaked) == 0 {
return
}
time.Sleep(50 * time.Millisecond)
}
for _, g := range leaked {
efer.Errorf("Leaked goroutine: %v", g)
}
}
// Check looks at the currently-running goroutines and checks if there are any
// interestring (created by gRPC) goroutines leaked. It waits up to 10 seconds
// in the error cases.
func Check(efer Errorfer) {
check(efer, 10*time.Second)
}

View File

@@ -0,0 +1,76 @@
/*
*
* Copyright 2017 gRPC authors.
*
* 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 leakcheck
import (
"fmt"
"strings"
"testing"
"time"
)
type testErrorfer struct {
errorCount int
errors []string
}
func (e *testErrorfer) Errorf(format string, args ...interface{}) {
e.errors = append(e.errors, fmt.Sprintf(format, args...))
e.errorCount++
}
func TestCheck(t *testing.T) {
const leakCount = 3
for i := 0; i < leakCount; i++ {
go func() { time.Sleep(2 * time.Second) }()
}
if ig := interestingGoroutines(); len(ig) == 0 {
t.Error("blah")
}
e := &testErrorfer{}
check(e, time.Second)
if e.errorCount != leakCount {
t.Errorf("check found %v leaks, want %v leaks", e.errorCount, leakCount)
t.Logf("leaked goroutines:\n%v", strings.Join(e.errors, "\n"))
}
check(t, 3*time.Second)
}
func ignoredTestingLeak(d time.Duration) {
time.Sleep(d)
}
func TestCheckRegisterIgnore(t *testing.T) {
RegisterIgnoreGoroutine("ignoredTestingLeak")
const leakCount = 3
for i := 0; i < leakCount; i++ {
go func() { time.Sleep(2 * time.Second) }()
}
go func() { ignoredTestingLeak(3 * time.Second) }()
if ig := interestingGoroutines(); len(ig) == 0 {
t.Error("blah")
}
e := &testErrorfer{}
check(e, time.Second)
if e.errorCount != leakCount {
t.Errorf("check found %v leaks, want %v leaks", e.errorCount, leakCount)
t.Logf("leaked goroutines:\n%v", strings.Join(e.errors, "\n"))
}
check(t, 3*time.Second)
}

24
vendor/google.golang.org/grpc/test/race.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// +build race
/*
* Copyright 2016 gRPC authors.
*
* 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 test
func init() {
raceMode = true
}

345
vendor/google.golang.org/grpc/test/rawConnWrapper.go generated vendored Normal file
View File

@@ -0,0 +1,345 @@
/*
* Copyright 2018 gRPC authors.
*
* 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 test
import (
"bytes"
"fmt"
"io"
"net"
"strings"
"sync"
"time"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
)
type listenerWrapper struct {
net.Listener
mu sync.Mutex
rcw *rawConnWrapper
}
func listenWithConnControl(network, address string) (net.Listener, error) {
l, err := net.Listen(network, address)
if err != nil {
return nil, err
}
return &listenerWrapper{Listener: l}, nil
}
// Accept blocks until Dial is called, then returns a net.Conn for the server
// half of the connection.
func (l *listenerWrapper) Accept() (net.Conn, error) {
c, err := l.Listener.Accept()
if err != nil {
return nil, err
}
l.mu.Lock()
l.rcw = newRawConnWrapperFromConn(c)
l.mu.Unlock()
return c, nil
}
func (l *listenerWrapper) getLastConn() *rawConnWrapper {
l.mu.Lock()
defer l.mu.Unlock()
return l.rcw
}
type dialerWrapper struct {
c net.Conn
rcw *rawConnWrapper
}
func (d *dialerWrapper) dialer(target string, t time.Duration) (net.Conn, error) {
c, err := net.DialTimeout("tcp", target, t)
d.c = c
d.rcw = newRawConnWrapperFromConn(c)
return c, err
}
func (d *dialerWrapper) getRawConnWrapper() *rawConnWrapper {
return d.rcw
}
type rawConnWrapper struct {
cc io.ReadWriteCloser
fr *http2.Framer
// writing headers:
headerBuf bytes.Buffer
hpackEnc *hpack.Encoder
// reading frames:
frc chan http2.Frame
frErrc chan error
readTimer *time.Timer
}
func newRawConnWrapperFromConn(cc io.ReadWriteCloser) *rawConnWrapper {
rcw := &rawConnWrapper{
cc: cc,
frc: make(chan http2.Frame, 1),
frErrc: make(chan error, 1),
}
rcw.hpackEnc = hpack.NewEncoder(&rcw.headerBuf)
rcw.fr = http2.NewFramer(cc, cc)
rcw.fr.ReadMetaHeaders = hpack.NewDecoder(4096 /*initialHeaderTableSize*/, nil)
return rcw
}
func (rcw *rawConnWrapper) Close() error {
return rcw.cc.Close()
}
func (rcw *rawConnWrapper) readFrame() (http2.Frame, error) {
go func() {
fr, err := rcw.fr.ReadFrame()
if err != nil {
rcw.frErrc <- err
} else {
rcw.frc <- fr
}
}()
t := time.NewTimer(2 * time.Second)
defer t.Stop()
select {
case f := <-rcw.frc:
return f, nil
case err := <-rcw.frErrc:
return nil, err
case <-t.C:
return nil, fmt.Errorf("timeout waiting for frame")
}
}
// greet initiates the client's HTTP/2 connection into a state where
// frames may be sent.
func (rcw *rawConnWrapper) greet() error {
rcw.writePreface()
rcw.writeInitialSettings()
rcw.wantSettings()
rcw.writeSettingsAck()
for {
f, err := rcw.readFrame()
if err != nil {
return err
}
switch f := f.(type) {
case *http2.WindowUpdateFrame:
// grpc's transport/http2_server sends this
// before the settings ack. The Go http2
// server uses a setting instead.
case *http2.SettingsFrame:
if f.IsAck() {
return nil
}
return fmt.Errorf("during greet, got non-ACK settings frame")
default:
return fmt.Errorf("during greet, unexpected frame type %T", f)
}
}
}
func (rcw *rawConnWrapper) writePreface() error {
n, err := rcw.cc.Write([]byte(http2.ClientPreface))
if err != nil {
return fmt.Errorf("Error writing client preface: %v", err)
}
if n != len(http2.ClientPreface) {
return fmt.Errorf("Writing client preface, wrote %d bytes; want %d", n, len(http2.ClientPreface))
}
return nil
}
func (rcw *rawConnWrapper) writeInitialSettings() error {
if err := rcw.fr.WriteSettings(); err != nil {
return fmt.Errorf("Error writing initial SETTINGS frame from client to server: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) writeSettingsAck() error {
if err := rcw.fr.WriteSettingsAck(); err != nil {
return fmt.Errorf("Error writing ACK of server's SETTINGS: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) wantSettings() (*http2.SettingsFrame, error) {
f, err := rcw.readFrame()
if err != nil {
return nil, fmt.Errorf("Error while expecting a SETTINGS frame: %v", err)
}
sf, ok := f.(*http2.SettingsFrame)
if !ok {
return nil, fmt.Errorf("got a %T; want *SettingsFrame", f)
}
return sf, nil
}
func (rcw *rawConnWrapper) wantSettingsAck() error {
f, err := rcw.readFrame()
if err != nil {
return err
}
sf, ok := f.(*http2.SettingsFrame)
if !ok {
return fmt.Errorf("Wanting a settings ACK, received a %T", f)
}
if !sf.IsAck() {
return fmt.Errorf("Settings Frame didn't have ACK set")
}
return nil
}
// wait for any activity from the server
func (rcw *rawConnWrapper) wantAnyFrame() (http2.Frame, error) {
f, err := rcw.fr.ReadFrame()
if err != nil {
return nil, err
}
return f, nil
}
func (rcw *rawConnWrapper) encodeHeaderField(k, v string) error {
err := rcw.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
if err != nil {
return fmt.Errorf("HPACK encoding error for %q/%q: %v", k, v, err)
}
return nil
}
// encodeHeader encodes headers and returns their HPACK bytes. headers
// must contain an even number of key/value pairs. There may be
// multiple pairs for keys (e.g. "cookie"). The :method, :path, and
// :scheme headers default to GET, / and https.
func (rcw *rawConnWrapper) encodeHeader(headers ...string) []byte {
if len(headers)%2 == 1 {
panic("odd number of kv args")
}
rcw.headerBuf.Reset()
if len(headers) == 0 {
// Fast path, mostly for benchmarks, so test code doesn't pollute
// profiles when we're looking to improve server allocations.
rcw.encodeHeaderField(":method", "GET")
rcw.encodeHeaderField(":path", "/")
rcw.encodeHeaderField(":scheme", "https")
return rcw.headerBuf.Bytes()
}
if len(headers) == 2 && headers[0] == ":method" {
// Another fast path for benchmarks.
rcw.encodeHeaderField(":method", headers[1])
rcw.encodeHeaderField(":path", "/")
rcw.encodeHeaderField(":scheme", "https")
return rcw.headerBuf.Bytes()
}
pseudoCount := map[string]int{}
keys := []string{":method", ":path", ":scheme"}
vals := map[string][]string{
":method": {"GET"},
":path": {"/"},
":scheme": {"https"},
}
for len(headers) > 0 {
k, v := headers[0], headers[1]
headers = headers[2:]
if _, ok := vals[k]; !ok {
keys = append(keys, k)
}
if strings.HasPrefix(k, ":") {
pseudoCount[k]++
if pseudoCount[k] == 1 {
vals[k] = []string{v}
} else {
// Allows testing of invalid headers w/ dup pseudo fields.
vals[k] = append(vals[k], v)
}
} else {
vals[k] = append(vals[k], v)
}
}
for _, k := range keys {
for _, v := range vals[k] {
rcw.encodeHeaderField(k, v)
}
}
return rcw.headerBuf.Bytes()
}
func (rcw *rawConnWrapper) writeHeadersGRPC(streamID uint32, path string) {
rcw.writeHeaders(http2.HeadersFrameParam{
StreamID: streamID,
BlockFragment: rcw.encodeHeader(
":method", "POST",
":path", path,
"content-type", "application/grpc",
"te", "trailers",
),
EndStream: false,
EndHeaders: true,
})
}
func (rcw *rawConnWrapper) writeHeaders(p http2.HeadersFrameParam) error {
if err := rcw.fr.WriteHeaders(p); err != nil {
return fmt.Errorf("Error writing HEADERS: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) writeData(streamID uint32, endStream bool, data []byte) error {
if err := rcw.fr.WriteData(streamID, endStream, data); err != nil {
return fmt.Errorf("Error writing DATA: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) writeRSTStream(streamID uint32, code http2.ErrCode) error {
if err := rcw.fr.WriteRSTStream(streamID, code); err != nil {
return fmt.Errorf("Error writing RST_STREAM: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) writeDataPadded(streamID uint32, endStream bool, data, padding []byte) error {
if err := rcw.fr.WriteDataPadded(streamID, endStream, data, padding); err != nil {
return fmt.Errorf("Error writing DATA with padding: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) writeGoAway(maxStreamID uint32, code http2.ErrCode, debugData []byte) error {
if err := rcw.fr.WriteGoAway(maxStreamID, code, debugData); err != nil {
return fmt.Errorf("Error writing GoAway: %v", err)
}
return nil
}
func (rcw *rawConnWrapper) writeRawFrame(t http2.FrameType, flags http2.Flags, streamID uint32, payload []byte) error {
if err := rcw.fr.WriteRawFrame(t, flags, streamID, payload); err != nil {
return fmt.Errorf("Error writing Raw Frame: %v", err)
}
return nil
}

280
vendor/google.golang.org/grpc/test/servertester.go generated vendored Normal file
View File

@@ -0,0 +1,280 @@
/*
* Copyright 2016 gRPC authors.
*
* 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 test
import (
"bytes"
"errors"
"io"
"strings"
"testing"
"time"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
)
// This is a subset of http2's serverTester type.
//
// serverTester wraps a io.ReadWriter (acting like the underlying
// network connection) and provides utility methods to read and write
// http2 frames.
//
// NOTE(bradfitz): this could eventually be exported somewhere. Others
// have asked for it too. For now I'm still experimenting with the
// API and don't feel like maintaining a stable testing API.
type serverTester struct {
cc io.ReadWriteCloser // client conn
t testing.TB
fr *http2.Framer
// writing headers:
headerBuf bytes.Buffer
hpackEnc *hpack.Encoder
// reading frames:
frc chan http2.Frame
frErrc chan error
readTimer *time.Timer
}
func newServerTesterFromConn(t testing.TB, cc io.ReadWriteCloser) *serverTester {
st := &serverTester{
t: t,
cc: cc,
frc: make(chan http2.Frame, 1),
frErrc: make(chan error, 1),
}
st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
st.fr = http2.NewFramer(cc, cc)
st.fr.ReadMetaHeaders = hpack.NewDecoder(4096 /*initialHeaderTableSize*/, nil)
return st
}
func (st *serverTester) readFrame() (http2.Frame, error) {
go func() {
fr, err := st.fr.ReadFrame()
if err != nil {
st.frErrc <- err
} else {
st.frc <- fr
}
}()
t := time.NewTimer(2 * time.Second)
defer t.Stop()
select {
case f := <-st.frc:
return f, nil
case err := <-st.frErrc:
return nil, err
case <-t.C:
return nil, errors.New("timeout waiting for frame")
}
}
// greet initiates the client's HTTP/2 connection into a state where
// frames may be sent.
func (st *serverTester) greet() {
st.writePreface()
st.writeInitialSettings()
st.wantSettings()
st.writeSettingsAck()
for {
f, err := st.readFrame()
if err != nil {
st.t.Fatal(err)
}
switch f := f.(type) {
case *http2.WindowUpdateFrame:
// grpc's transport/http2_server sends this
// before the settings ack. The Go http2
// server uses a setting instead.
case *http2.SettingsFrame:
if f.IsAck() {
return
}
st.t.Fatalf("during greet, got non-ACK settings frame")
default:
st.t.Fatalf("during greet, unexpected frame type %T", f)
}
}
}
func (st *serverTester) writePreface() {
n, err := st.cc.Write([]byte(http2.ClientPreface))
if err != nil {
st.t.Fatalf("Error writing client preface: %v", err)
}
if n != len(http2.ClientPreface) {
st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(http2.ClientPreface))
}
}
func (st *serverTester) writeInitialSettings() {
if err := st.fr.WriteSettings(); err != nil {
st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
}
}
func (st *serverTester) writeSettingsAck() {
if err := st.fr.WriteSettingsAck(); err != nil {
st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err)
}
}
func (st *serverTester) wantSettings() *http2.SettingsFrame {
f, err := st.readFrame()
if err != nil {
st.t.Fatalf("Error while expecting a SETTINGS frame: %v", err)
}
sf, ok := f.(*http2.SettingsFrame)
if !ok {
st.t.Fatalf("got a %T; want *SettingsFrame", f)
}
return sf
}
func (st *serverTester) wantSettingsAck() {
f, err := st.readFrame()
if err != nil {
st.t.Fatal(err)
}
sf, ok := f.(*http2.SettingsFrame)
if !ok {
st.t.Fatalf("Wanting a settings ACK, received a %T", f)
}
if !sf.IsAck() {
st.t.Fatal("Settings Frame didn't have ACK set")
}
}
// wait for any activity from the server
func (st *serverTester) wantAnyFrame() http2.Frame {
f, err := st.fr.ReadFrame()
if err != nil {
st.t.Fatal(err)
}
return f
}
func (st *serverTester) encodeHeaderField(k, v string) {
err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
if err != nil {
st.t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
}
}
// encodeHeader encodes headers and returns their HPACK bytes. headers
// must contain an even number of key/value pairs. There may be
// multiple pairs for keys (e.g. "cookie"). The :method, :path, and
// :scheme headers default to GET, / and https.
func (st *serverTester) encodeHeader(headers ...string) []byte {
if len(headers)%2 == 1 {
panic("odd number of kv args")
}
st.headerBuf.Reset()
if len(headers) == 0 {
// Fast path, mostly for benchmarks, so test code doesn't pollute
// profiles when we're looking to improve server allocations.
st.encodeHeaderField(":method", "GET")
st.encodeHeaderField(":path", "/")
st.encodeHeaderField(":scheme", "https")
return st.headerBuf.Bytes()
}
if len(headers) == 2 && headers[0] == ":method" {
// Another fast path for benchmarks.
st.encodeHeaderField(":method", headers[1])
st.encodeHeaderField(":path", "/")
st.encodeHeaderField(":scheme", "https")
return st.headerBuf.Bytes()
}
pseudoCount := map[string]int{}
keys := []string{":method", ":path", ":scheme"}
vals := map[string][]string{
":method": {"GET"},
":path": {"/"},
":scheme": {"https"},
}
for len(headers) > 0 {
k, v := headers[0], headers[1]
headers = headers[2:]
if _, ok := vals[k]; !ok {
keys = append(keys, k)
}
if strings.HasPrefix(k, ":") {
pseudoCount[k]++
if pseudoCount[k] == 1 {
vals[k] = []string{v}
} else {
// Allows testing of invalid headers w/ dup pseudo fields.
vals[k] = append(vals[k], v)
}
} else {
vals[k] = append(vals[k], v)
}
}
for _, k := range keys {
for _, v := range vals[k] {
st.encodeHeaderField(k, v)
}
}
return st.headerBuf.Bytes()
}
func (st *serverTester) writeHeadersGRPC(streamID uint32, path string) {
st.writeHeaders(http2.HeadersFrameParam{
StreamID: streamID,
BlockFragment: st.encodeHeader(
":method", "POST",
":path", path,
"content-type", "application/grpc",
"te", "trailers",
),
EndStream: false,
EndHeaders: true,
})
}
func (st *serverTester) writeHeaders(p http2.HeadersFrameParam) {
if err := st.fr.WriteHeaders(p); err != nil {
st.t.Fatalf("Error writing HEADERS: %v", err)
}
}
func (st *serverTester) writeData(streamID uint32, endStream bool, data []byte) {
if err := st.fr.WriteData(streamID, endStream, data); err != nil {
st.t.Fatalf("Error writing DATA: %v", err)
}
}
func (st *serverTester) writeRSTStream(streamID uint32, code http2.ErrCode) {
if err := st.fr.WriteRSTStream(streamID, code); err != nil {
st.t.Fatalf("Error writing RST_STREAM: %v", err)
}
}
func (st *serverTester) writeDataPadded(streamID uint32, endStream bool, data, padding []byte) {
if err := st.fr.WriteDataPadded(streamID, endStream, data, padding); err != nil {
st.t.Fatalf("Error writing DATA with padding: %v", err)
}
}