add mockserver
This commit is contained in:
parent
3cc3172974
commit
b88cbe1bef
@ -0,0 +1,21 @@
|
||||
# API 测试工具
|
||||
|
||||
## Go 版本测试服务器 `mockserver`
|
||||
|
||||
### 编译
|
||||
|
||||
1. 准备好 Go 环境
|
||||
2. 下载 [BDChain Go SDK](https://phabricator.internetapi.cn/source/bdchain/repository/master/) 到 `GOPATH`
|
||||
3. 切换工作目录到 `mockserver` 目录
|
||||
4. 使用 `go get -d ./...` 安装此项目依赖
|
||||
5. 使用 `go build` 编译
|
||||
6. `mockserver` 即为编译好的可执行程序
|
||||
|
||||
### 运行
|
||||
|
||||
- 使用 `.\mockserver --help` 查看使用帮助
|
||||
- 目前仅支持使用 `--port N` 设定程序运行的端口为 N
|
||||
|
||||
### 测试连接
|
||||
|
||||
在需要测试连接的位置,设定连接地址和端口为此 `mockserver` 所在地址及端口即可。
|
6
test/bdchain/api/mockserver/.gitignore
vendored
Normal file
6
test/bdchain/api/mockserver/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# Go
|
||||
debug
|
||||
debug.test
|
||||
|
||||
mockserver
|
||||
mockserver.exe
|
52
test/bdchain/api/mockserver/errors.go
Normal file
52
test/bdchain/api/mockserver/errors.go
Normal file
@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
ErrInvalidServer = errors.New("server is invalid")
|
||||
ErrInvalidRequest = errors.New("request is invalid")
|
||||
ErrInvalidParameter = errors.New("parameter is invalid")
|
||||
ErrTestNotImplemented = errors.New("test path not implemented")
|
||||
|
||||
ErrMultiple = errors.New("Multiple errors in transaction")
|
||||
ErrEmptyFrom = errors.New("from must not be empty")
|
||||
ErrInvalidTo = errors.New("to must be a valid 32-byte address")
|
||||
ErrEmptyName = errors.New("name must not be empty")
|
||||
)
|
||||
|
||||
func toStatusError(src error) error {
|
||||
/*__*/ if src == nil {
|
||||
return src
|
||||
} else if _, ok := src.(interface{ GRPCStatus() *status.Status }); ok {
|
||||
return src
|
||||
} else {
|
||||
switch errors.Cause(src) {
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
default:
|
||||
return src
|
||||
case ErrInvalidServer:
|
||||
fallthrough
|
||||
case ErrInvalidRequest:
|
||||
return status.Error(codes.Internal, src.Error())
|
||||
case ErrInvalidParameter:
|
||||
return status.Error(codes.InvalidArgument, src.Error())
|
||||
case ErrTestNotImplemented:
|
||||
return status.Error(codes.Unimplemented, src.Error())
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
case ErrEmptyName:
|
||||
fallthrough
|
||||
case ErrEmptyFrom:
|
||||
fallthrough
|
||||
case ErrInvalidTo:
|
||||
return status.Error(codes.InvalidArgument, src.Error())
|
||||
case ErrMultiple:
|
||||
return status.Error(codes.InvalidArgument, src.Error())
|
||||
}
|
||||
}
|
||||
}
|
39
test/bdchain/api/mockserver/main.go
Normal file
39
test/bdchain/api/mockserver/main.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"bdchain/api/grpc/txledger"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// flag
|
||||
port := flag.Int("port", 10000, "set the port of test server")
|
||||
flag.Parse()
|
||||
|
||||
// server
|
||||
rpc := grpc.NewServer()
|
||||
srv := (*grpcServer)(&server{})
|
||||
txledger.RegisterTransactionLedgerServer(rpc, srv)
|
||||
|
||||
con, err := net.Listen("tcp", ":"+strconv.Itoa(*port))
|
||||
if err == nil {
|
||||
fmt.Println("server is running on", *port)
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// start
|
||||
err = rpc.Serve(con)
|
||||
if err != nil {
|
||||
fmt.Println("server closed with error", err)
|
||||
} else {
|
||||
fmt.Println("server closed")
|
||||
}
|
||||
}
|
191
test/bdchain/api/mockserver/server.go
Normal file
191
test/bdchain/api/mockserver/server.go
Normal file
@ -0,0 +1,191 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"bdchain/api/grpc/common"
|
||||
"bdchain/api/grpc/txledger"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// server
|
||||
type server struct{}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// grpcServer
|
||||
type grpcServer server
|
||||
|
||||
func (s *grpcServer) ClientVersion(
|
||||
c context.Context,
|
||||
r *empty.Empty,
|
||||
) (res *common.ClientVersionResponse, err error) {
|
||||
switch {
|
||||
case s == nil:
|
||||
err = toStatusError(ErrInvalidServer)
|
||||
case r == nil:
|
||||
err = toStatusError(ErrInvalidRequest)
|
||||
default:
|
||||
res = &common.ClientVersionResponse{
|
||||
Version: "TxLedgerGo/v0.0.1alpha/darwin/go1.11",
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *grpcServer) CreateLedger(
|
||||
c context.Context,
|
||||
r *txledger.CreateLedgerRequest,
|
||||
) (res *txledger.CreateLedgerResponse, err error) {
|
||||
switch {
|
||||
case s == nil:
|
||||
err = toStatusError(ErrInvalidServer)
|
||||
case r == nil:
|
||||
err = toStatusError(ErrInvalidRequest)
|
||||
case r.Name == "":
|
||||
err = toStatusError(ErrEmptyName)
|
||||
case r.Name == "test":
|
||||
res = &txledger.CreateLedgerResponse{
|
||||
Ok: true,
|
||||
}
|
||||
default:
|
||||
err = toStatusError(ErrTestNotImplemented)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *grpcServer) GetLedgers(
|
||||
c context.Context,
|
||||
r *empty.Empty,
|
||||
) (res *txledger.GetLedgersResponse, err error) {
|
||||
switch {
|
||||
case s == nil:
|
||||
err = toStatusError(ErrInvalidServer)
|
||||
case r == nil:
|
||||
err = toStatusError(ErrInvalidRequest)
|
||||
default:
|
||||
res = &txledger.GetLedgersResponse{
|
||||
Ledgers: []string{
|
||||
"first",
|
||||
"second",
|
||||
"third",
|
||||
},
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *grpcServer) SendTransaction(
|
||||
c context.Context,
|
||||
r *txledger.SendTransactionRequest,
|
||||
) (res *txledger.SendTransactionResponse, err error) {
|
||||
switch {
|
||||
case s == nil:
|
||||
err = toStatusError(ErrInvalidServer)
|
||||
case r == nil:
|
||||
fallthrough
|
||||
case r.Transaction == nil:
|
||||
err = toStatusError(ErrInvalidRequest)
|
||||
case r.Ledger != "test":
|
||||
err = toStatusError(ErrTestNotImplemented)
|
||||
default:
|
||||
type Input struct {
|
||||
Type common.TransactionType
|
||||
From []byte
|
||||
To []byte
|
||||
Data []byte
|
||||
}
|
||||
type Output struct {
|
||||
Hash []byte
|
||||
Error error
|
||||
}
|
||||
type Case struct {
|
||||
I Input
|
||||
O Output
|
||||
}
|
||||
|
||||
Merge := func(
|
||||
p *status.Status,
|
||||
cs ...*status.Status,
|
||||
) *status.Status {
|
||||
msg := []proto.Message{}
|
||||
for _, c := range cs {
|
||||
msg = append(msg, c.Proto())
|
||||
}
|
||||
r, err := p.WithDetails(msg...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
tx := r.Transaction
|
||||
for _, c := range [...]Case{
|
||||
{
|
||||
I: Input{
|
||||
Type: common.TransactionType_MESSAGE,
|
||||
From: []byte{
|
||||
0xf0, 0x0d, 0xca, 0xfe, 0xf0, 0x0d, 0xca, 0xfe,
|
||||
0xf0, 0x0d, 0xca, 0xfe, 0xf0, 0x0d, 0xca, 0xfe,
|
||||
0xf0, 0x0d, 0xca, 0xfe,
|
||||
},
|
||||
To: []byte{
|
||||
0xfe, 0xed, 0xba, 0xbe, 0xfe, 0xed, 0xba, 0xbe,
|
||||
0xfe, 0xed, 0xba, 0xbe, 0xfe, 0xed, 0xba, 0xbe,
|
||||
0xfe, 0xed, 0xba, 0xbe,
|
||||
},
|
||||
Data: []byte{
|
||||
0xde, 0xad, 0xbe, 0xef,
|
||||
},
|
||||
},
|
||||
O: Output{
|
||||
Hash: []byte{
|
||||
0xd1, 0x5e, 0xa5, 0xed, 0xd1, 0x5e, 0xa5, 0xed,
|
||||
0xd1, 0x5e, 0xa5, 0xed, 0xd1, 0x5e, 0xa5, 0xed,
|
||||
0xd1, 0x5e, 0xa5, 0xed, 0xd1, 0x5e, 0xa5, 0xed,
|
||||
0xd1, 0x5e, 0xa5, 0xed, 0xd1, 0x5e, 0xa5, 0xed,
|
||||
},
|
||||
Error: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
I: Input{
|
||||
Type: common.TransactionType_MESSAGE,
|
||||
From: nil,
|
||||
To: []byte{
|
||||
0x50, 0xba, 0xda, 0x55,
|
||||
},
|
||||
Data: nil,
|
||||
},
|
||||
O: Output{
|
||||
Hash: nil,
|
||||
Error: Merge(
|
||||
status.New(codes.InvalidArgument, ErrMultiple.Error()),
|
||||
status.New(codes.InvalidArgument, ErrEmptyFrom.Error()),
|
||||
status.New(codes.InvalidArgument, ErrInvalidTo.Error()),
|
||||
).Err(),
|
||||
},
|
||||
},
|
||||
} {
|
||||
if c.I.Type == tx.Type &&
|
||||
bytes.Equal(c.I.From, tx.From) &&
|
||||
bytes.Equal(c.I.To, tx.To) &&
|
||||
bytes.Equal(c.I.Data, tx.Data) {
|
||||
if c.O.Error != nil {
|
||||
err = c.O.Error
|
||||
} else {
|
||||
res = &txledger.SendTransactionResponse{Hash: c.O.Hash}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
err = toStatusError(ErrTestNotImplemented)
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue
Block a user