зеркало из https://github.com/github/vitess-gh.git
Adding unit test framework for tabletconn, and one test.
This commit is contained in:
Родитель
7c539a0712
Коммит
ba8c172a30
|
@ -60,13 +60,13 @@ func (sq *SqlQuery) SplitQuery(ctx context.Context, req *proto.SplitQueryRequest
|
|||
return sq.server.SplitQuery(ctx, req, reply)
|
||||
}
|
||||
|
||||
// NewSqlQuery returns a new SqlQuery based on the QueryService implementation
|
||||
func NewSqlQuery(server queryservice.QueryService) *SqlQuery {
|
||||
// New returns a new SqlQuery based on the QueryService implementation
|
||||
func New(server queryservice.QueryService) *SqlQuery {
|
||||
return &SqlQuery{server}
|
||||
}
|
||||
|
||||
func init() {
|
||||
tabletserver.QueryServiceControlRegisterFunctions = append(tabletserver.QueryServiceControlRegisterFunctions, func(qsc tabletserver.QueryServiceControl) {
|
||||
servenv.Register("queryservice", NewSqlQuery(qsc.QueryService()))
|
||||
servenv.Register("queryservice", New(qsc.QueryService()))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2015, Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gorpctabletconn
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/youtube/vitess/go/rpcplus"
|
||||
"github.com/youtube/vitess/go/rpcwrap/bsonrpc"
|
||||
"github.com/youtube/vitess/go/vt/tabletserver/gorpcqueryservice"
|
||||
"github.com/youtube/vitess/go/vt/tabletserver/tabletconntest"
|
||||
"github.com/youtube/vitess/go/vt/topo"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// This test makes sure the go rpc service works
|
||||
func TestGoRPCTabletConn(t *testing.T) {
|
||||
// fake service
|
||||
service := tabletconntest.CreateFakeServer(t)
|
||||
|
||||
// listen on a random port
|
||||
listener, err := net.Listen("tcp", ":0")
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot listen: %v", err)
|
||||
}
|
||||
port := listener.Addr().(*net.TCPAddr).Port
|
||||
|
||||
// Create a Go Rpc server and listen on the port
|
||||
server := rpcplus.NewServer()
|
||||
server.Register(gorpcqueryservice.New(service))
|
||||
|
||||
// create the HTTP server, serve the server from it
|
||||
handler := http.NewServeMux()
|
||||
bsonrpc.ServeCustomRPC(handler, server, false)
|
||||
httpServer := http.Server{
|
||||
Handler: handler,
|
||||
}
|
||||
go httpServer.Serve(listener)
|
||||
|
||||
// Create a Go RPC client connecting to the server
|
||||
ctx := context.Background()
|
||||
client, err := DialTablet(ctx, topo.EndPoint{
|
||||
Host: "localhost",
|
||||
NamedPortMap: map[string]int{
|
||||
"vt": port,
|
||||
},
|
||||
}, tabletconntest.TestKeyspace, tabletconntest.TestShard, 30*time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("dial failed: %v", err)
|
||||
}
|
||||
|
||||
// run the test suite
|
||||
tabletconntest.TestSuite(t, client)
|
||||
|
||||
// and clean up
|
||||
client.Close()
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
// Copyright 2015, Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package tabletconntest provides the test methods to make sure a
|
||||
// tabletconn/queryservice pair over RPC works correctly.
|
||||
package tabletconntest
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
mproto "github.com/youtube/vitess/go/mysql/proto"
|
||||
"github.com/youtube/vitess/go/sqltypes"
|
||||
"github.com/youtube/vitess/go/vt/tabletserver/proto"
|
||||
"github.com/youtube/vitess/go/vt/tabletserver/queryservice"
|
||||
"github.com/youtube/vitess/go/vt/tabletserver/tabletconn"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// fakeQueryService has the server side of this fake
|
||||
type fakeQueryService struct {
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
// TestKeyspace is the Keyspace we use for this test
|
||||
const TestKeyspace = "test_keyspace"
|
||||
|
||||
// TestShard is the Shard we use for this test
|
||||
const TestShard = "test_shard"
|
||||
|
||||
const testSessionId int64 = 5678
|
||||
|
||||
// GetSessionId is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) GetSessionId(sessionParams *proto.SessionParams, sessionInfo *proto.SessionInfo) error {
|
||||
if sessionParams.Keyspace != TestKeyspace {
|
||||
f.t.Fatalf("invalid keyspace: got %v expected %v", sessionParams.Keyspace, TestKeyspace)
|
||||
}
|
||||
if sessionParams.Shard != TestShard {
|
||||
f.t.Fatalf("invalid shard: got %v expected %v", sessionParams.Shard, TestShard)
|
||||
}
|
||||
sessionInfo.SessionId = testSessionId
|
||||
return nil
|
||||
}
|
||||
|
||||
// Begin is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) Begin(ctx context.Context, session *proto.Session, txInfo *proto.TransactionInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Commit is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) Commit(ctx context.Context, session *proto.Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rollback is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) Rollback(ctx context.Context, session *proto.Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Execute is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) Execute(ctx context.Context, query *proto.Query, reply *mproto.QueryResult) error {
|
||||
if query.Sql != executeQuery {
|
||||
f.t.Fatalf("invalid Execute.Query.Sql: got %v expected %v", query.Sql, executeQuery)
|
||||
}
|
||||
if !reflect.DeepEqual(query.BindVariables, executeBindVars) {
|
||||
f.t.Fatalf("invalid Execute.Query.BindVariables: got %v expected %v", query.BindVariables, executeBindVars)
|
||||
}
|
||||
if query.SessionId != testSessionId {
|
||||
f.t.Fatalf("invalid Execute.Query.SessionId: got %v expected %v", query.SessionId, testSessionId)
|
||||
}
|
||||
if query.TransactionId != executeTransactionId {
|
||||
f.t.Fatalf("invalid Execute.Query.TransactionId: got %v expected %v", query.TransactionId, executeTransactionId)
|
||||
}
|
||||
*reply = executeQueryResult
|
||||
return nil
|
||||
}
|
||||
|
||||
const executeQuery = "executeQuery"
|
||||
|
||||
var executeBindVars = map[string]interface{}{
|
||||
"bind1": int64(0),
|
||||
}
|
||||
|
||||
const executeTransactionId int64 = 678
|
||||
|
||||
var executeQueryResult = mproto.QueryResult{
|
||||
Fields: []mproto.Field{
|
||||
mproto.Field{
|
||||
Name: "field1",
|
||||
Type: 42,
|
||||
},
|
||||
mproto.Field{
|
||||
Name: "field2",
|
||||
Type: 73,
|
||||
},
|
||||
},
|
||||
RowsAffected: 123,
|
||||
InsertId: 72,
|
||||
Rows: [][]sqltypes.Value{
|
||||
[]sqltypes.Value{
|
||||
sqltypes.MakeString([]byte("row1 value1")),
|
||||
sqltypes.MakeString([]byte("row1 value2")),
|
||||
},
|
||||
[]sqltypes.Value{
|
||||
sqltypes.MakeString([]byte("row2 value1")),
|
||||
sqltypes.MakeString([]byte("row2 value2")),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func testExecute(t *testing.T, conn tabletconn.TabletConn) {
|
||||
ctx := context.Background()
|
||||
qr, err := conn.Execute(ctx, executeQuery, executeBindVars, executeTransactionId)
|
||||
if err != nil {
|
||||
t.Fatalf("Execute failed: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(*qr, executeQueryResult) {
|
||||
t.Errorf("Unexpected result from Execute: got %v wanted %v", qr, executeQueryResult)
|
||||
}
|
||||
}
|
||||
|
||||
// StreamExecute is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) StreamExecute(ctx context.Context, query *proto.Query, sendReply func(*mproto.QueryResult) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecuteBatch is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) ExecuteBatch(ctx context.Context, queryList *proto.QueryList, reply *proto.QueryResultList) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SplitQuery is part of the queryservice.QueryService interface
|
||||
func (f *fakeQueryService) SplitQuery(ctx context.Context, req *proto.SplitQueryRequest, reply *proto.SplitQueryResult) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateFakeServer returns the fake server for the tests
|
||||
func CreateFakeServer(t *testing.T) queryservice.QueryService {
|
||||
return &fakeQueryService{t}
|
||||
}
|
||||
|
||||
// TestSuite runs all the tests
|
||||
func TestSuite(t *testing.T, conn tabletconn.TabletConn) {
|
||||
testExecute(t, conn)
|
||||
}
|
Загрузка…
Ссылка в новой задаче