|
|
@@ -18,6 +18,7 @@ package p2p
|
|
|
|
|
|
import (
|
|
|
"encoding/binary"
|
|
|
+ "net"
|
|
|
"reflect"
|
|
|
"testing"
|
|
|
"time"
|
|
|
@@ -79,6 +80,7 @@ type fakeTable []*discover.Node
|
|
|
func (t fakeTable) Self() *discover.Node { return new(discover.Node) }
|
|
|
func (t fakeTable) Close() {}
|
|
|
func (t fakeTable) Lookup(discover.NodeID) []*discover.Node { return nil }
|
|
|
+func (t fakeTable) Resolve(discover.NodeID) *discover.Node { return nil }
|
|
|
func (t fakeTable) ReadRandomNodes(buf []*discover.Node) int { return copy(buf, t) }
|
|
|
|
|
|
// This test checks that dynamic dials are launched from discovery results.
|
|
|
@@ -113,9 +115,9 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(5)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
|
|
},
|
|
|
},
|
|
|
// Some of the dials complete but no new ones are launched yet because
|
|
|
@@ -129,8 +131,8 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(4)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
},
|
|
|
},
|
|
|
// No new dial tasks are launched in the this round because
|
|
|
@@ -145,7 +147,7 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(5)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(5)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
&waitExpireTask{Duration: 14 * time.Second},
|
|
|
@@ -162,7 +164,7 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(5)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(6)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(6)}},
|
|
|
},
|
|
|
},
|
|
|
// More peers (3,4) drop off and dial for ID 6 completes.
|
|
|
@@ -175,10 +177,10 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(5)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(6)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(6)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(7)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(7)}},
|
|
|
&discoverTask{},
|
|
|
},
|
|
|
},
|
|
|
@@ -193,7 +195,7 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(7)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(7)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(7)}},
|
|
|
},
|
|
|
},
|
|
|
// Finish the running node discovery with an empty set. A new lookup
|
|
|
@@ -236,11 +238,11 @@ func TestDialStateDynDialFromTable(t *testing.T) {
|
|
|
// 5 out of 8 of the nodes returned by ReadRandomNodes are dialed.
|
|
|
{
|
|
|
new: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(1)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(2)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(5)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(2)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
|
|
&discoverTask{},
|
|
|
},
|
|
|
},
|
|
|
@@ -251,8 +253,8 @@ func TestDialStateDynDialFromTable(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(2)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(1)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(2)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(2)}},
|
|
|
&discoverTask{results: []*discover.Node{
|
|
|
{ID: uintID(10)},
|
|
|
{ID: uintID(11)},
|
|
|
@@ -260,9 +262,9 @@ func TestDialStateDynDialFromTable(t *testing.T) {
|
|
|
}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(10)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(11)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(12)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(10)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(11)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(12)}},
|
|
|
&discoverTask{},
|
|
|
},
|
|
|
},
|
|
|
@@ -276,12 +278,12 @@ func TestDialStateDynDialFromTable(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(12)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(5)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(10)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(11)}},
|
|
|
- &dialTask{dynDialedConn, &discover.Node{ID: uintID(12)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(10)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(11)}},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(12)}},
|
|
|
},
|
|
|
},
|
|
|
// Waiting for expiry. No waitExpireTask is launched because the
|
|
|
@@ -332,9 +334,9 @@ func TestDialStateStaticDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(2)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(5)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
|
|
},
|
|
|
},
|
|
|
// No new tasks are launched in this round because all static
|
|
|
@@ -346,7 +348,7 @@ func TestDialStateStaticDial(t *testing.T) {
|
|
|
{rw: &conn{flags: staticDialedConn, id: uintID(3)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
},
|
|
|
},
|
|
|
// No new dial tasks are launched because all static
|
|
|
@@ -360,8 +362,8 @@ func TestDialStateStaticDial(t *testing.T) {
|
|
|
{rw: &conn{flags: staticDialedConn, id: uintID(5)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(5)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
&waitExpireTask{Duration: 14 * time.Second},
|
|
|
@@ -386,8 +388,8 @@ func TestDialStateStaticDial(t *testing.T) {
|
|
|
{rw: &conn{flags: staticDialedConn, id: uintID(5)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(2)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(4)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -410,9 +412,9 @@ func TestDialStateCache(t *testing.T) {
|
|
|
{
|
|
|
peers: nil,
|
|
|
new: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(1)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(2)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(1)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
},
|
|
|
},
|
|
|
// No new tasks are launched in this round because all static
|
|
|
@@ -423,8 +425,8 @@ func TestDialStateCache(t *testing.T) {
|
|
|
{rw: &conn{flags: staticDialedConn, id: uintID(2)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(1)}},
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(2)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(1)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}},
|
|
|
},
|
|
|
},
|
|
|
// A salvage task is launched to wait for node 3's history
|
|
|
@@ -435,7 +437,7 @@ func TestDialStateCache(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(2)}},
|
|
|
},
|
|
|
done: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
&waitExpireTask{Duration: 14 * time.Second},
|
|
|
@@ -455,13 +457,40 @@ func TestDialStateCache(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, id: uintID(2)}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{staticDialedConn, &discover.Node{ID: uintID(3)}},
|
|
|
+ &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}},
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+func TestDialResolve(t *testing.T) {
|
|
|
+ resolved := discover.NewNode(uintID(1), net.IP{127, 0, 55, 234}, 3333, 4444)
|
|
|
+ table := &resolveMock{answer: resolved}
|
|
|
+ state := newDialState(nil, table, 0)
|
|
|
+
|
|
|
+ // Check that the task is generated with an incomplete ID.
|
|
|
+ dest := discover.NewNode(uintID(1), nil, 0, 0)
|
|
|
+ state.addStatic(dest)
|
|
|
+ tasks := state.newTasks(0, nil, time.Time{})
|
|
|
+ if !reflect.DeepEqual(tasks, []task{&dialTask{flags: staticDialedConn, dest: dest}}) {
|
|
|
+ t.Fatalf("expected dial task, got %#v", tasks)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Now run the task, it should resolve the ID once.
|
|
|
+ srv := &Server{ntab: table, Dialer: &net.Dialer{Deadline: time.Now().Add(-5 * time.Minute)}}
|
|
|
+ tasks[0].Do(srv)
|
|
|
+ if !reflect.DeepEqual(table.resolveCalls, []discover.NodeID{dest.ID}) {
|
|
|
+ t.Fatalf("wrong resolve calls, got %v", table.resolveCalls)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Report it as done to the dialer, which should update the static node record.
|
|
|
+ state.taskDone(tasks[0], time.Now())
|
|
|
+ if state.static[uintID(1)].dest != resolved {
|
|
|
+ t.Fatalf("state.dest not updated")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// compares task lists but doesn't care about the order.
|
|
|
func sametasks(a, b []task) bool {
|
|
|
if len(a) != len(b) {
|
|
|
@@ -484,3 +513,20 @@ func uintID(i uint32) discover.NodeID {
|
|
|
binary.BigEndian.PutUint32(id[:], i)
|
|
|
return id
|
|
|
}
|
|
|
+
|
|
|
+// implements discoverTable for TestDialResolve
|
|
|
+type resolveMock struct {
|
|
|
+ resolveCalls []discover.NodeID
|
|
|
+ answer *discover.Node
|
|
|
+}
|
|
|
+
|
|
|
+func (t *resolveMock) Resolve(id discover.NodeID) *discover.Node {
|
|
|
+ t.resolveCalls = append(t.resolveCalls, id)
|
|
|
+ return t.answer
|
|
|
+}
|
|
|
+
|
|
|
+func (t *resolveMock) Self() *discover.Node { return new(discover.Node) }
|
|
|
+func (t *resolveMock) Close() {}
|
|
|
+func (t *resolveMock) Bootstrap([]*discover.Node) {}
|
|
|
+func (t *resolveMock) Lookup(discover.NodeID) []*discover.Node { return nil }
|
|
|
+func (t *resolveMock) ReadRandomNodes(buf []*discover.Node) int { return 0 }
|