|
|
|
package p2p
|
|
|
|
|
|
|
|
import (
|
|
|
|
// "fmt"
|
|
|
|
"bytes"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/ethutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
func setupMessenger(handlers Handlers) (*TestNetworkConnection, chan *PeerError, *Messenger) {
|
|
|
|
errchan := NewPeerErrorChannel()
|
|
|
|
addr := &TestAddr{"test:30303"}
|
|
|
|
net := NewTestNetworkConnection(addr)
|
|
|
|
conn := NewConnection(net, errchan)
|
|
|
|
mess := NewMessenger(nil, conn, errchan, handlers)
|
|
|
|
mess.Start()
|
|
|
|
return net, errchan, mess
|
|
|
|
}
|
|
|
|
|
|
|
|
type TestProtocol struct {
|
|
|
|
Msgs []*Msg
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *TestProtocol) Start() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *TestProtocol) Stop() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *TestProtocol) Offset() MsgCode {
|
|
|
|
return MsgCode(5)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *TestProtocol) HandleIn(msg *Msg, response chan *Msg) {
|
|
|
|
self.Msgs = append(self.Msgs, msg)
|
|
|
|
close(response)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *TestProtocol) HandleOut(msg *Msg) bool {
|
|
|
|
if msg.Code() > 3 {
|
|
|
|
return false
|
|
|
|
} else {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *TestProtocol) Name() string {
|
|
|
|
return "a"
|
|
|
|
}
|
|
|
|
|
|
|
|
func Packet(offset MsgCode, code MsgCode, params ...interface{}) []byte {
|
|
|
|
msg, _ := NewMsg(code, params...)
|
|
|
|
encoded := msg.Encode(offset)
|
|
|
|
packet := []byte{34, 64, 8, 145}
|
|
|
|
packet = append(packet, ethutil.NumberToBytes(uint32(len(encoded)), 32)...)
|
|
|
|
return append(packet, encoded...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRead(t *testing.T) {
|
|
|
|
handlers := make(Handlers)
|
|
|
|
testProtocol := &TestProtocol{Msgs: []*Msg{}}
|
|
|
|
handlers["a"] = func(p *Peer) Protocol { return testProtocol }
|
|
|
|
net, _, mess := setupMessenger(handlers)
|
|
|
|
mess.AddProtocols([]string{"a"})
|
|
|
|
defer mess.Stop()
|
|
|
|
wait := 1 * time.Millisecond
|
|
|
|
packet := Packet(16, 1, uint32(1), "000")
|
|
|
|
go net.In(0, packet)
|
|
|
|
time.Sleep(wait)
|
|
|
|
if len(testProtocol.Msgs) != 1 {
|
|
|
|
t.Errorf("msg not relayed to correct protocol")
|
|
|
|
} else {
|
|
|
|
if testProtocol.Msgs[0].Code() != 1 {
|
|
|
|
t.Errorf("incorrect msg code relayed to protocol")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestWrite(t *testing.T) {
|
|
|
|
handlers := make(Handlers)
|
|
|
|
testProtocol := &TestProtocol{Msgs: []*Msg{}}
|
|
|
|
handlers["a"] = func(p *Peer) Protocol { return testProtocol }
|
|
|
|
net, _, mess := setupMessenger(handlers)
|
|
|
|
mess.AddProtocols([]string{"a"})
|
|
|
|
defer mess.Stop()
|
|
|
|
wait := 1 * time.Millisecond
|
|
|
|
msg, _ := NewMsg(3, uint32(1), "000")
|
|
|
|
err := mess.Write("b", msg)
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("expect error for unknown protocol")
|
|
|
|
}
|
|
|
|
err = mess.Write("a", msg)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("expect no error for known protocol: %v", err)
|
|
|
|
} else {
|
|
|
|
time.Sleep(wait)
|
|
|
|
if len(net.Out) != 1 {
|
|
|
|
t.Errorf("msg not written")
|
|
|
|
} else {
|
|
|
|
out := net.Out[0]
|
|
|
|
packet := Packet(16, 3, uint32(1), "000")
|
|
|
|
if bytes.Compare(out, packet) != 0 {
|
|
|
|
t.Errorf("incorrect packet %v", out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPulse(t *testing.T) {
|
|
|
|
net, _, mess := setupMessenger(make(Handlers))
|
|
|
|
defer mess.Stop()
|
|
|
|
ping := false
|
|
|
|
timeout := false
|
|
|
|
pingTimeout := 10 * time.Millisecond
|
|
|
|
gracePeriod := 200 * time.Millisecond
|
|
|
|
go mess.PingPong(pingTimeout, gracePeriod, func() { ping = true }, func() { timeout = true })
|
|
|
|
net.In(0, Packet(0, 1))
|
|
|
|
if ping {
|
|
|
|
t.Errorf("ping sent too early")
|
|
|
|
}
|
|
|
|
time.Sleep(pingTimeout + 100*time.Millisecond)
|
|
|
|
if !ping {
|
|
|
|
t.Errorf("no ping sent after timeout")
|
|
|
|
}
|
|
|
|
if timeout {
|
|
|
|
t.Errorf("timeout too early")
|
|
|
|
}
|
|
|
|
ping = false
|
|
|
|
net.In(0, Packet(0, 1))
|
|
|
|
time.Sleep(pingTimeout + 100*time.Millisecond)
|
|
|
|
if !ping {
|
|
|
|
t.Errorf("no ping sent after timeout")
|
|
|
|
}
|
|
|
|
if timeout {
|
|
|
|
t.Errorf("timeout too early")
|
|
|
|
}
|
|
|
|
ping = false
|
|
|
|
time.Sleep(gracePeriod)
|
|
|
|
if ping {
|
|
|
|
t.Errorf("ping called twice")
|
|
|
|
}
|
|
|
|
if !timeout {
|
|
|
|
t.Errorf("no timeout after grace period")
|
|
|
|
}
|
|
|
|
}
|