jsonrpc: basic channel test

This commit is contained in:
Łukasz Magiera 2019-07-23 00:47:02 +02:00
parent dda1dfdc80
commit 527ab7100a
2 changed files with 86 additions and 24 deletions

View File

@ -10,7 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"
) )
type SimpleServerHandler struct { type SimpleServerHandler struct {
@ -73,37 +73,37 @@ func TestRPC(t *testing.T) {
StringMatch func(t TestType, i2 int64) (out TestOut, err error) StringMatch func(t TestType, i2 int64) (out TestOut, err error)
} }
closer, err := NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &client) closer, err := NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &client)
assert.NoError(t, err) require.NoError(t, err)
defer closer() defer closer()
// Add(int) error // Add(int) error
assert.NoError(t, client.Add(2)) require.NoError(t, client.Add(2))
assert.Equal(t, 2, serverHandler.n) require.Equal(t, 2, serverHandler.n)
err = client.Add(-3546) err = client.Add(-3546)
assert.EqualError(t, err, "test") require.EqualError(t, err, "test")
// AddGet(int) int // AddGet(int) int
n := client.AddGet(3) n := client.AddGet(3)
assert.Equal(t, 5, n) require.Equal(t, 5, n)
assert.Equal(t, 5, serverHandler.n) require.Equal(t, 5, serverHandler.n)
// StringMatch // StringMatch
o, err := client.StringMatch(TestType{S: "0"}, 0) o, err := client.StringMatch(TestType{S: "0"}, 0)
assert.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "0", o.S) require.Equal(t, "0", o.S)
assert.Equal(t, 0, o.I) require.Equal(t, 0, o.I)
_, err = client.StringMatch(TestType{S: "5"}, 5) _, err = client.StringMatch(TestType{S: "5"}, 5)
assert.EqualError(t, err, ":(") require.EqualError(t, err, ":(")
o, err = client.StringMatch(TestType{S: "8", I: 8}, 8) o, err = client.StringMatch(TestType{S: "8", I: 8}, 8)
assert.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "8", o.S) require.Equal(t, "8", o.S)
assert.Equal(t, 8, o.I) require.Equal(t, 8, o.I)
// Invalid client handlers // Invalid client handlers
@ -111,18 +111,18 @@ func TestRPC(t *testing.T) {
Add func(int) Add func(int)
} }
closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &noret) closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &noret)
assert.NoError(t, err) require.NoError(t, err)
// this one should actually work // this one should actually work
noret.Add(4) noret.Add(4)
assert.Equal(t, 9, serverHandler.n) require.Equal(t, 9, serverHandler.n)
closer() closer()
var noparam struct { var noparam struct {
Add func() Add func()
} }
closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &noparam) closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &noparam)
assert.NoError(t, err) require.NoError(t, err)
// shouldn't panic // shouldn't panic
noparam.Add() noparam.Add()
@ -132,7 +132,7 @@ func TestRPC(t *testing.T) {
AddGet func() (int, error) AddGet func() (int, error)
} }
closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &erronly) closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &erronly)
assert.NoError(t, err) require.NoError(t, err)
_, err = erronly.AddGet() _, err = erronly.AddGet()
if err == nil || err.Error() != "RPC error (-32602): wrong param count" { if err == nil || err.Error() != "RPC error (-32602): wrong param count" {
@ -144,7 +144,7 @@ func TestRPC(t *testing.T) {
Add func(string) error Add func(string) error
} }
closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &wrongtype) closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &wrongtype)
assert.NoError(t, err) require.NoError(t, err)
err = wrongtype.Add("not an int") err = wrongtype.Add("not an int")
if err == nil || !strings.Contains(err.Error(), "RPC error (-32700):") || !strings.Contains(err.Error(), "json: cannot unmarshal string into Go value of type int") { if err == nil || !strings.Contains(err.Error(), "RPC error (-32700):") || !strings.Contains(err.Error(), "json: cannot unmarshal string into Go value of type int") {
@ -156,7 +156,7 @@ func TestRPC(t *testing.T) {
NotThere func(string) error NotThere func(string) error
} }
closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &notfound) closer, err = NewClient("ws://"+testServ.Listener.Addr().String(), "SimpleServerHandler", &notfound)
assert.NoError(t, err) require.NoError(t, err)
err = notfound.NotThere("hello?") err = notfound.NotThere("hello?")
if err == nil || err.Error() != "RPC error (-32601): method 'SimpleServerHandler.NotThere' not found" { if err == nil || err.Error() != "RPC error (-32601): method 'SimpleServerHandler.NotThere' not found" {
@ -203,7 +203,7 @@ func TestCtx(t *testing.T) {
Test func(ctx context.Context) Test func(ctx context.Context)
} }
closer, err := NewClient("ws://"+testServ.Listener.Addr().String(), "CtxHandler", &client) closer, err := NewClient("ws://"+testServ.Listener.Addr().String(), "CtxHandler", &client)
assert.NoError(t, err) require.NoError(t, err)
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel() defer cancel()
@ -239,3 +239,62 @@ func TestCtx(t *testing.T) {
serverHandler.lk.Unlock() serverHandler.lk.Unlock()
closer() closer()
} }
type ChanHandler struct {
wait chan struct{}
}
func (h *ChanHandler) Sub(ctx context.Context, i int) (<-chan int, error) {
out := make(chan int)
go func() {
defer close(out)
var n int
for {
<-h.wait
n += i
select {
case <-ctx.Done():
return
case out <- n:
}
}
}()
return out, nil
}
func TestChan(t *testing.T) {
var client struct {
Sub func(context.Context, int) (<-chan int, error)
}
serverHandler := &ChanHandler{
wait: make(chan struct{}, 5),
}
rpcServer := NewServer()
rpcServer.Register("ChanHandler", serverHandler)
testServ := httptest.NewServer(rpcServer)
defer testServ.Close()
closer, err := NewClient("ws://"+testServ.Listener.Addr().String(), "ChanHandler", &client)
require.NoError(t, err)
defer closer()
serverHandler.wait <- struct{}{}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
sub, err := client.Sub(ctx, 2)
require.NoError(t, err)
require.Equal(t, 2, <-sub)
}

View File

@ -230,6 +230,9 @@ func handleWsConn(ctx context.Context, conn *websocket.Conn, handler handlers, r
return // remote closed return // remote closed
} }
// debug util - dump all messages to stderr
// r = io.TeeReader(r, os.Stderr)
var frame frame var frame frame
if err := json.NewDecoder(r).Decode(&frame); err != nil { if err := json.NewDecoder(r).Decode(&frame); err != nil {
log.Error("handle me:", err) log.Error("handle me:", err)
@ -248,11 +251,11 @@ func handleWsConn(ctx context.Context, conn *websocket.Conn, handler handlers, r
continue continue
} }
if req.retCh != nil { if req.retCh != nil && frame.Result != nil {
// output is channel // output is channel
var chid uint64 var chid uint64
if err := json.Unmarshal(frame.Result, &chid); err != nil { if err := json.Unmarshal(frame.Result, &chid); err != nil {
log.Error("failed to unmarshal channel id response: %s", err) log.Errorf("failed to unmarshal channel id response: %s, data '%s'", err, string(frame.Result))
continue continue
} }
@ -277,7 +280,7 @@ func handleWsConn(ctx context.Context, conn *websocket.Conn, handler handlers, r
hnd, ok := chanHandlers[chid] hnd, ok := chanHandlers[chid]
if !ok { if !ok {
log.Error("xrpc.ch.val: handler %d not found", chid) log.Errorf("xrpc.ch.val: handler %d not found", chid)
continue continue
} }