mirror of
https://github.com/sourcegraph/jsonrpc2.git
synced 2026-06-18 05:00:03 +02:00
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)
|
|
}
|
|
}
|