mirror of
https://github.com/restic/restic.git
synced 2025-10-27 12:08:33 +00:00
Vendor dependencies for GCS
This commit is contained in:
255
vendor/cloud.google.com/go/spanner/internal/testutil/mockserver.go
generated
vendored
Normal file
255
vendor/cloud.google.com/go/spanner/internal/testutil/mockserver.go
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
Copyright 2017 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 testutil
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
proto3 "github.com/golang/protobuf/ptypes/struct"
|
||||
pbt "github.com/golang/protobuf/ptypes/timestamp"
|
||||
|
||||
sppb "google.golang.org/genproto/googleapis/spanner/v1"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
)
|
||||
|
||||
var (
|
||||
// KvMeta is the Metadata for mocked KV table.
|
||||
KvMeta = sppb.ResultSetMetadata{
|
||||
RowType: &sppb.StructType{
|
||||
Fields: []*sppb.StructType_Field{
|
||||
{
|
||||
Name: "Key",
|
||||
Type: &sppb.Type{Code: sppb.TypeCode_STRING},
|
||||
},
|
||||
{
|
||||
Name: "Value",
|
||||
Type: &sppb.Type{Code: sppb.TypeCode_STRING},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// MockCtlMsg encapsulates PartialResultSet/error that might be sent to
|
||||
// client
|
||||
type MockCtlMsg struct {
|
||||
// If ResumeToken == true, mock server will generate a row with
|
||||
// resume token.
|
||||
ResumeToken bool
|
||||
// If Err != nil, mock server will return error in RPC response.
|
||||
Err error
|
||||
}
|
||||
|
||||
// MockCloudSpanner is a mock implementation of SpannerServer interface.
|
||||
// TODO: make MockCloudSpanner a full-fleged Cloud Spanner implementation.
|
||||
type MockCloudSpanner struct {
|
||||
s *grpc.Server
|
||||
t *testing.T
|
||||
addr string
|
||||
msgs chan MockCtlMsg
|
||||
readTs time.Time
|
||||
next int
|
||||
}
|
||||
|
||||
// Addr returns the listening address of mock server.
|
||||
func (m *MockCloudSpanner) Addr() string {
|
||||
return m.addr
|
||||
}
|
||||
|
||||
// AddMsg generates a new mocked row which can be received by client.
|
||||
func (m *MockCloudSpanner) AddMsg(err error, resumeToken bool) {
|
||||
msg := MockCtlMsg{
|
||||
ResumeToken: resumeToken,
|
||||
Err: err,
|
||||
}
|
||||
if err == io.EOF {
|
||||
close(m.msgs)
|
||||
} else {
|
||||
m.msgs <- msg
|
||||
}
|
||||
}
|
||||
|
||||
// Done signals an end to a mocked stream.
|
||||
func (m *MockCloudSpanner) Done() {
|
||||
close(m.msgs)
|
||||
}
|
||||
|
||||
// CreateSession is a placeholder for SpannerServer.CreateSession.
|
||||
func (m *MockCloudSpanner) CreateSession(c context.Context, r *sppb.CreateSessionRequest) (*sppb.Session, error) {
|
||||
m.t.Fatalf("CreateSession is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// GetSession is a placeholder for SpannerServer.GetSession.
|
||||
func (m *MockCloudSpanner) GetSession(c context.Context, r *sppb.GetSessionRequest) (*sppb.Session, error) {
|
||||
m.t.Fatalf("GetSession is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// DeleteSession is a placeholder for SpannerServer.DeleteSession.
|
||||
func (m *MockCloudSpanner) DeleteSession(c context.Context, r *sppb.DeleteSessionRequest) (*empty.Empty, error) {
|
||||
m.t.Fatalf("DeleteSession is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// ExecuteSql is a placeholder for SpannerServer.ExecuteSql.
|
||||
func (m *MockCloudSpanner) ExecuteSql(c context.Context, r *sppb.ExecuteSqlRequest) (*sppb.ResultSet, error) {
|
||||
m.t.Fatalf("ExecuteSql is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// EncodeResumeToken return mock resume token encoding for an uint64 integer.
|
||||
func EncodeResumeToken(t uint64) []byte {
|
||||
rt := make([]byte, 16)
|
||||
binary.PutUvarint(rt, t)
|
||||
return rt
|
||||
}
|
||||
|
||||
// DecodeResumeToken decodes a mock resume token into an uint64 integer.
|
||||
func DecodeResumeToken(t []byte) (uint64, error) {
|
||||
s, n := binary.Uvarint(t)
|
||||
if n <= 0 {
|
||||
return 0, fmt.Errorf("invalid resume token: %v", t)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ExecuteStreamingSql is a mock implementation of SpannerServer.ExecuteStreamingSql.
|
||||
func (m *MockCloudSpanner) ExecuteStreamingSql(r *sppb.ExecuteSqlRequest, s sppb.Spanner_ExecuteStreamingSqlServer) error {
|
||||
switch r.Sql {
|
||||
case "SELECT * from t_unavailable":
|
||||
return grpc.Errorf(codes.Unavailable, "mock table unavailable")
|
||||
case "SELECT t.key key, t.value value FROM t_mock t":
|
||||
if r.ResumeToken != nil {
|
||||
s, err := DecodeResumeToken(r.ResumeToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.next = int(s) + 1
|
||||
}
|
||||
for {
|
||||
msg, more := <-m.msgs
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
if msg.Err == nil {
|
||||
var rt []byte
|
||||
if msg.ResumeToken {
|
||||
rt = EncodeResumeToken(uint64(m.next))
|
||||
}
|
||||
meta := KvMeta
|
||||
meta.Transaction = &sppb.Transaction{
|
||||
ReadTimestamp: &pbt.Timestamp{
|
||||
Seconds: m.readTs.Unix(),
|
||||
Nanos: int32(m.readTs.Nanosecond()),
|
||||
},
|
||||
}
|
||||
err := s.Send(&sppb.PartialResultSet{
|
||||
Metadata: &meta,
|
||||
Values: []*proto3.Value{
|
||||
{Kind: &proto3.Value_StringValue{StringValue: fmt.Sprintf("foo-%02d", m.next)}},
|
||||
{Kind: &proto3.Value_StringValue{StringValue: fmt.Sprintf("bar-%02d", m.next)}},
|
||||
},
|
||||
ResumeToken: rt,
|
||||
})
|
||||
m.next = m.next + 1
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
return msg.Err
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unsupported SQL: %v", r.Sql)
|
||||
}
|
||||
}
|
||||
|
||||
// Read is a placeholder for SpannerServer.Read.
|
||||
func (m *MockCloudSpanner) Read(c context.Context, r *sppb.ReadRequest) (*sppb.ResultSet, error) {
|
||||
m.t.Fatalf("Read is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// StreamingRead is a placeholder for SpannerServer.StreamingRead.
|
||||
func (m *MockCloudSpanner) StreamingRead(r *sppb.ReadRequest, s sppb.Spanner_StreamingReadServer) error {
|
||||
m.t.Fatalf("StreamingRead is unimplemented")
|
||||
return errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// BeginTransaction is a placeholder for SpannerServer.BeginTransaction.
|
||||
func (m *MockCloudSpanner) BeginTransaction(c context.Context, r *sppb.BeginTransactionRequest) (*sppb.Transaction, error) {
|
||||
m.t.Fatalf("BeginTransaction is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// Commit is a placeholder for SpannerServer.Commit.
|
||||
func (m *MockCloudSpanner) Commit(c context.Context, r *sppb.CommitRequest) (*sppb.CommitResponse, error) {
|
||||
m.t.Fatalf("Commit is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// Rollback is a placeholder for SpannerServer.Rollback.
|
||||
func (m *MockCloudSpanner) Rollback(c context.Context, r *sppb.RollbackRequest) (*empty.Empty, error) {
|
||||
m.t.Fatalf("Rollback is unimplemented")
|
||||
return nil, errors.New("Unimplemented")
|
||||
}
|
||||
|
||||
// Serve runs a MockCloudSpanner listening on a random localhost address.
|
||||
func (m *MockCloudSpanner) Serve() {
|
||||
m.s = grpc.NewServer()
|
||||
if m.addr == "" {
|
||||
m.addr = "localhost:0"
|
||||
}
|
||||
lis, err := net.Listen("tcp", m.addr)
|
||||
if err != nil {
|
||||
m.t.Fatalf("Failed to listen: %v", err)
|
||||
}
|
||||
_, port, err := net.SplitHostPort(lis.Addr().String())
|
||||
if err != nil {
|
||||
m.t.Fatalf("Failed to parse listener address: %v", err)
|
||||
}
|
||||
sppb.RegisterSpannerServer(m.s, m)
|
||||
m.addr = "localhost:" + port
|
||||
go m.s.Serve(lis)
|
||||
}
|
||||
|
||||
// Stop terminates MockCloudSpanner and closes the serving port.
|
||||
func (m *MockCloudSpanner) Stop() {
|
||||
m.s.Stop()
|
||||
}
|
||||
|
||||
// NewMockCloudSpanner creates a new MockCloudSpanner instance.
|
||||
func NewMockCloudSpanner(t *testing.T, ts time.Time) *MockCloudSpanner {
|
||||
mcs := &MockCloudSpanner{
|
||||
t: t,
|
||||
msgs: make(chan MockCtlMsg, 1000),
|
||||
readTs: ts,
|
||||
}
|
||||
return mcs
|
||||
}
|
||||
Reference in New Issue
Block a user