mirror of
https://github.com/sourcegraph/jsonrpc2.git
synced 2026-06-16 04:04:56 +02:00
This merge request moves some of the contents from the jsonrpc2.go file into their own designated file. The new files being introduced (excluding test files) are as follows: * conn.go * request.go * response.go The motive of this change is to make it easier to navigate the code. Without this change, the jsonrpc2.go file is 813 lines of code.
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
package jsonrpc2_test
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/sourcegraph/jsonrpc2"
|
|
)
|
|
|
|
func TestConn_DisconnectNotify(t *testing.T) {
|
|
|
|
t.Run("EOF", func(t *testing.T) {
|
|
connA, connB := net.Pipe()
|
|
c := jsonrpc2.NewConn(context.Background(), jsonrpc2.NewPlainObjectStream(connB), nil)
|
|
// By closing connA, connB receives io.EOF
|
|
if err := connA.Close(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
assertDisconnect(t, c, connB)
|
|
})
|
|
|
|
t.Run("Close", func(t *testing.T) {
|
|
_, connB := net.Pipe()
|
|
c := jsonrpc2.NewConn(context.Background(), jsonrpc2.NewPlainObjectStream(connB), nil)
|
|
if err := c.Close(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
assertDisconnect(t, c, connB)
|
|
})
|
|
|
|
t.Run("Close async", func(t *testing.T) {
|
|
done := make(chan struct{})
|
|
_, connB := net.Pipe()
|
|
c := jsonrpc2.NewConn(context.Background(), jsonrpc2.NewPlainObjectStream(connB), nil)
|
|
go func() {
|
|
if err := c.Close(); err != nil && err != jsonrpc2.ErrClosed {
|
|
t.Error(err)
|
|
}
|
|
close(done)
|
|
}()
|
|
assertDisconnect(t, c, connB)
|
|
<-done
|
|
})
|
|
|
|
t.Run("protocol error", func(t *testing.T) {
|
|
connA, connB := net.Pipe()
|
|
c := jsonrpc2.NewConn(context.Background(), jsonrpc2.NewPlainObjectStream(connB), nil)
|
|
connA.Write([]byte("invalid json"))
|
|
assertDisconnect(t, c, connB)
|
|
})
|
|
}
|
|
|
|
func TestConn_Close(t *testing.T) {
|
|
t.Run("waiting for response", func(t *testing.T) {
|
|
connA, connB := net.Pipe()
|
|
nodeA := jsonrpc2.NewConn(
|
|
context.Background(),
|
|
jsonrpc2.NewPlainObjectStream(connA), noopHandler{},
|
|
)
|
|
defer nodeA.Close()
|
|
nodeB := jsonrpc2.NewConn(
|
|
context.Background(),
|
|
jsonrpc2.NewPlainObjectStream(connB),
|
|
noopHandler{},
|
|
)
|
|
defer nodeB.Close()
|
|
|
|
ready := make(chan struct{})
|
|
done := make(chan struct{})
|
|
go func() {
|
|
close(ready)
|
|
err := nodeB.Call(context.Background(), "m", nil, nil)
|
|
if err != jsonrpc2.ErrClosed {
|
|
t.Errorf("got error %v, want %v", err, jsonrpc2.ErrClosed)
|
|
}
|
|
close(done)
|
|
}()
|
|
// Wait for the request to be sent before we close the connection.
|
|
<-ready
|
|
if err := nodeB.Close(); err != nil && err != jsonrpc2.ErrClosed {
|
|
t.Error(err)
|
|
}
|
|
assertDisconnect(t, nodeB, connB)
|
|
<-done
|
|
})
|
|
}
|
|
|
|
func assertDisconnect(t *testing.T, c *jsonrpc2.Conn, conn io.Writer) {
|
|
select {
|
|
case <-c.DisconnectNotify():
|
|
case <-time.After(200 * time.Millisecond):
|
|
t.Fatal("no disconnect notification")
|
|
}
|
|
// Assert that conn is closed by trying to write to it.
|
|
_, got := conn.Write(nil)
|
|
want := io.ErrClosedPipe
|
|
if got != want {
|
|
t.Fatalf("got %q, want %q", got, want)
|
|
}
|
|
}
|