147 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package p2p
 | 
						|
 | 
						|
import (
 | 
						|
	// "fmt"
 | 
						|
	"bytes"
 | 
						|
	"github.com/ethereum/eth-go/ethutil"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
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")
 | 
						|
	}
 | 
						|
}
 |