cmd, eth, p2p: introduce pending peer cli arg, add tests
This commit is contained in:
@ -369,6 +369,136 @@ func TestServerTrustedPeers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that a failed dial will temporarily throttle a peer.
|
||||
func TestServerMaxPendingDials(t *testing.T) {
|
||||
defer testlog(t).detach()
|
||||
|
||||
// Start a simple test server
|
||||
server := &Server{
|
||||
ListenAddr: "127.0.0.1:0",
|
||||
PrivateKey: newkey(),
|
||||
MaxPeers: 10,
|
||||
MaxPendingPeers: 1,
|
||||
}
|
||||
if err := server.Start(); err != nil {
|
||||
t.Fatal("failed to start test server: %v", err)
|
||||
}
|
||||
defer server.Stop()
|
||||
|
||||
// Simulate two separate remote peers
|
||||
peers := make(chan *discover.Node, 2)
|
||||
conns := make(chan net.Conn, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("listener %d: failed to setup: %v", i, err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
addr := listener.Addr().(*net.TCPAddr)
|
||||
peers <- &discover.Node{
|
||||
ID: discover.PubkeyID(&newkey().PublicKey),
|
||||
IP: addr.IP,
|
||||
TCP: uint16(addr.Port),
|
||||
}
|
||||
go func() {
|
||||
conn, err := listener.Accept()
|
||||
if err == nil {
|
||||
conns <- conn
|
||||
}
|
||||
}()
|
||||
}
|
||||
// Request a dial for both peers
|
||||
go func() {
|
||||
for i := 0; i < 2; i++ {
|
||||
server.staticDial <- <-peers // hack piggybacking the static implementation
|
||||
}
|
||||
}()
|
||||
|
||||
// Make sure only one outbound connection goes through
|
||||
var conn net.Conn
|
||||
|
||||
select {
|
||||
case conn = <-conns:
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatalf("first dial timeout")
|
||||
}
|
||||
select {
|
||||
case conn = <-conns:
|
||||
t.Fatalf("second dial completed prematurely")
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
}
|
||||
// Finish the first dial, check the second
|
||||
conn.Close()
|
||||
select {
|
||||
case conn = <-conns:
|
||||
conn.Close()
|
||||
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatalf("second dial timeout")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerMaxPendingAccepts(t *testing.T) {
|
||||
defer testlog(t).detach()
|
||||
|
||||
// Start a test server and a peer sink for synchronization
|
||||
started := make(chan *Peer)
|
||||
server := &Server{
|
||||
ListenAddr: "127.0.0.1:0",
|
||||
PrivateKey: newkey(),
|
||||
MaxPeers: 10,
|
||||
MaxPendingPeers: 1,
|
||||
NoDial: true,
|
||||
newPeerHook: func(p *Peer) { started <- p },
|
||||
}
|
||||
if err := server.Start(); err != nil {
|
||||
t.Fatal("failed to start test server: %v", err)
|
||||
}
|
||||
defer server.Stop()
|
||||
|
||||
// Try and connect to the server on multiple threads concurrently
|
||||
conns := make([]net.Conn, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
dialer := &net.Dialer{Deadline: time.Now().Add(3 * time.Second)}
|
||||
|
||||
conn, err := dialer.Dial("tcp", server.ListenAddr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to dial server: %v", err)
|
||||
}
|
||||
conns[i] = conn
|
||||
}
|
||||
// Check that a handshake on the second doesn't pass
|
||||
go func() {
|
||||
key := newkey()
|
||||
shake := &protoHandshake{Version: baseProtocolVersion, ID: discover.PubkeyID(&key.PublicKey)}
|
||||
if _, err := setupConn(conns[1], key, shake, server.Self(), false, server.trustedNodes); err != nil {
|
||||
t.Fatalf("failed to run handshake: %v", err)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-started:
|
||||
t.Fatalf("handshake on second connection accepted")
|
||||
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
}
|
||||
// Shake on first, check that both go through
|
||||
go func() {
|
||||
key := newkey()
|
||||
shake := &protoHandshake{Version: baseProtocolVersion, ID: discover.PubkeyID(&key.PublicKey)}
|
||||
if _, err := setupConn(conns[0], key, shake, server.Self(), false, server.trustedNodes); err != nil {
|
||||
t.Fatalf("failed to run handshake: %v", err)
|
||||
}
|
||||
}()
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case <-started:
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatalf("peer %d: handshake timeout", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newkey() *ecdsa.PrivateKey {
|
||||
key, err := crypto.GenerateKey()
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user