|
|
|
@ -11,14 +11,14 @@ import ( |
|
|
|
|
"testing" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/ethutil" |
|
|
|
|
logpkg "github.com/ethereum/go-ethereum/logger" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func init() { |
|
|
|
|
ethlog.AddLogSystem(ethlog.NewStdLogSystem(os.Stdout, log.LstdFlags, ethlog.DebugLevel)) |
|
|
|
|
logpkg.AddLogSystem(logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.DebugLevel)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func setupMessenger(handlers Handlers) (net.Conn, *Peer, *messenger) { |
|
|
|
|
func testMessenger(handlers Handlers) (net.Conn, *Peer, *messenger) { |
|
|
|
|
conn1, conn2 := net.Pipe() |
|
|
|
|
id := NewSimpleClientIdentity("test", "0", "0", "public key") |
|
|
|
|
server := New(nil, conn1.LocalAddr(), id, handlers, 10, NewBlacklist()) |
|
|
|
@ -33,7 +33,7 @@ func performTestHandshake(r *bufio.Reader, w io.Writer) error { |
|
|
|
|
return fmt.Errorf("read error: %v", err) |
|
|
|
|
} |
|
|
|
|
if msg.Code != handshakeMsg { |
|
|
|
|
return fmt.Errorf("first message should be handshake, got %x", msg.Code) |
|
|
|
|
return fmt.Errorf("first message should be handshake, got %d", msg.Code) |
|
|
|
|
} |
|
|
|
|
if err := msg.Discard(); err != nil { |
|
|
|
|
return err |
|
|
|
@ -44,56 +44,102 @@ func performTestHandshake(r *bufio.Reader, w io.Writer) error { |
|
|
|
|
return writeMsg(w, msg) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type testMsg struct { |
|
|
|
|
code MsgCode |
|
|
|
|
data *ethutil.Value |
|
|
|
|
type testProtocol struct { |
|
|
|
|
offset MsgCode |
|
|
|
|
f func(MsgReadWriter) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type testProto struct { |
|
|
|
|
recv chan testMsg |
|
|
|
|
func (p *testProtocol) Offset() MsgCode { |
|
|
|
|
return p.offset |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (*testProto) Offset() MsgCode { return 5 } |
|
|
|
|
|
|
|
|
|
func (tp *testProto) Start(peer *Peer, rw MsgReadWriter) error { |
|
|
|
|
return MsgLoop(rw, 1024, func(code MsgCode, data *ethutil.Value) error { |
|
|
|
|
logger.Debugf("testprotocol got msg: %d\n", code) |
|
|
|
|
tp.recv <- testMsg{code, data} |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
func (p *testProtocol) Start(peer *Peer, rw MsgReadWriter) error { |
|
|
|
|
p.f(rw) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestRead(t *testing.T) { |
|
|
|
|
testProtocol := &testProto{make(chan testMsg)} |
|
|
|
|
handlers := Handlers{"a": func() Protocol { return testProtocol }} |
|
|
|
|
net, peer, mess := setupMessenger(handlers) |
|
|
|
|
bufr := bufio.NewReader(net) |
|
|
|
|
done := make(chan struct{}) |
|
|
|
|
handlers := Handlers{ |
|
|
|
|
"a": &testProtocol{5, func(rw MsgReadWriter) { |
|
|
|
|
msg, err := rw.ReadMsg() |
|
|
|
|
if err != nil { |
|
|
|
|
t.Errorf("read error: %v", err) |
|
|
|
|
} |
|
|
|
|
if msg.Code != 2 { |
|
|
|
|
t.Errorf("incorrect msg code %d relayed to protocol", msg.Code) |
|
|
|
|
} |
|
|
|
|
data, err := msg.Data() |
|
|
|
|
if err != nil { |
|
|
|
|
t.Errorf("data decoding error: %v", err) |
|
|
|
|
} |
|
|
|
|
expdata := []interface{}{1, []byte{0x30, 0x30, 0x30}} |
|
|
|
|
if !reflect.DeepEqual(data.Slice(), expdata) { |
|
|
|
|
t.Errorf("incorrect msg data %#v", data.Slice()) |
|
|
|
|
} |
|
|
|
|
close(done) |
|
|
|
|
}}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
net, peer, m := testMessenger(handlers) |
|
|
|
|
defer peer.Stop() |
|
|
|
|
bufr := bufio.NewReader(net) |
|
|
|
|
if err := performTestHandshake(bufr, net); err != nil { |
|
|
|
|
t.Fatalf("handshake failed: %v", err) |
|
|
|
|
} |
|
|
|
|
m.setRemoteProtocols([]string{"a"}) |
|
|
|
|
|
|
|
|
|
mess.setRemoteProtocols([]string{"a"}) |
|
|
|
|
writeMsg(net, NewMsg(17, uint32(1), "000")) |
|
|
|
|
writeMsg(net, NewMsg(18, 1, "000")) |
|
|
|
|
select { |
|
|
|
|
case msg := <-testProtocol.recv: |
|
|
|
|
if msg.code != 1 { |
|
|
|
|
t.Errorf("incorrect msg code %d relayed to protocol", msg.code) |
|
|
|
|
} |
|
|
|
|
expdata := []interface{}{1, []byte{0x30, 0x30, 0x30}} |
|
|
|
|
if !reflect.DeepEqual(msg.data.Slice(), expdata) { |
|
|
|
|
t.Errorf("incorrect msg data %#v", msg.data.Slice()) |
|
|
|
|
} |
|
|
|
|
case <-done: |
|
|
|
|
case <-time.After(2 * time.Second): |
|
|
|
|
t.Errorf("receive timeout") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestWriteProtoMsg(t *testing.T) { |
|
|
|
|
handlers := make(Handlers) |
|
|
|
|
testProtocol := &testProto{recv: make(chan testMsg, 1)} |
|
|
|
|
handlers["a"] = func() Protocol { return testProtocol } |
|
|
|
|
net, peer, mess := setupMessenger(handlers) |
|
|
|
|
func TestWriteFromProto(t *testing.T) { |
|
|
|
|
handlers := Handlers{ |
|
|
|
|
"a": &testProtocol{2, func(rw MsgReadWriter) { |
|
|
|
|
if err := rw.WriteMsg(NewMsg(2)); err == nil { |
|
|
|
|
t.Error("expected error for out-of-range msg code, got nil") |
|
|
|
|
} |
|
|
|
|
if err := rw.WriteMsg(NewMsg(1)); err != nil { |
|
|
|
|
t.Errorf("write error: %v", err) |
|
|
|
|
} |
|
|
|
|
}}, |
|
|
|
|
} |
|
|
|
|
net, peer, mess := testMessenger(handlers) |
|
|
|
|
defer peer.Stop() |
|
|
|
|
bufr := bufio.NewReader(net) |
|
|
|
|
if err := performTestHandshake(bufr, net); err != nil { |
|
|
|
|
t.Fatalf("handshake failed: %v", err) |
|
|
|
|
} |
|
|
|
|
mess.setRemoteProtocols([]string{"a"}) |
|
|
|
|
|
|
|
|
|
msg, err := readMsg(bufr) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Errorf("read error: %v") |
|
|
|
|
} |
|
|
|
|
if msg.Code != 17 { |
|
|
|
|
t.Errorf("incorrect message code: got %d, expected %d", msg.Code, 17) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var discardProto = &testProtocol{1, func(rw MsgReadWriter) { |
|
|
|
|
for { |
|
|
|
|
msg, err := rw.ReadMsg() |
|
|
|
|
if err != nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if err = msg.Discard(); err != nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}} |
|
|
|
|
|
|
|
|
|
func TestMessengerWriteProtoMsg(t *testing.T) { |
|
|
|
|
handlers := Handlers{"a": discardProto} |
|
|
|
|
net, peer, mess := testMessenger(handlers) |
|
|
|
|
defer peer.Stop() |
|
|
|
|
bufr := bufio.NewReader(net) |
|
|
|
|
if err := performTestHandshake(bufr, net); err != nil { |
|
|
|
@ -120,13 +166,13 @@ func TestWriteProtoMsg(t *testing.T) { |
|
|
|
|
read <- msg |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
if err := mess.writeProtoMsg("a", NewMsg(3)); err != nil { |
|
|
|
|
if err := mess.writeProtoMsg("a", NewMsg(0)); err != nil { |
|
|
|
|
t.Errorf("expect no error for known protocol: %v", err) |
|
|
|
|
} |
|
|
|
|
select { |
|
|
|
|
case msg := <-read: |
|
|
|
|
if msg.Code != 19 { |
|
|
|
|
t.Errorf("wrong code, got %d, expected %d", msg.Code, 19) |
|
|
|
|
if msg.Code != 16 { |
|
|
|
|
t.Errorf("wrong code, got %d, expected %d", msg.Code, 16) |
|
|
|
|
} |
|
|
|
|
msg.Discard() |
|
|
|
|
case err := <-readerr: |
|
|
|
@ -135,7 +181,7 @@ func TestWriteProtoMsg(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestPulse(t *testing.T) { |
|
|
|
|
net, peer, _ := setupMessenger(nil) |
|
|
|
|
net, peer, _ := testMessenger(nil) |
|
|
|
|
defer peer.Stop() |
|
|
|
|
bufr := bufio.NewReader(net) |
|
|
|
|
if err := performTestHandshake(bufr, net); err != nil { |
|
|
|
@ -149,7 +195,7 @@ func TestPulse(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
after := time.Now() |
|
|
|
|
if msg.Code != pingMsg { |
|
|
|
|
t.Errorf("expected ping message, got %x", msg.Code) |
|
|
|
|
t.Errorf("expected ping message, got %d", msg.Code) |
|
|
|
|
} |
|
|
|
|
if d := after.Sub(before); d < pingTimeout { |
|
|
|
|
t.Errorf("ping sent too early after %v, expected at least %v", d, pingTimeout) |
|
|
|
|