forked from nictuku/dht
-
Notifications
You must be signed in to change notification settings - Fork 0
/
neighborhood_test.go
115 lines (98 loc) · 2.57 KB
/
neighborhood_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package dht
import (
"crypto/rand"
"net"
"testing"
)
const (
id = "01abcdefghij01234567"
)
type test struct {
id string
proximity int
}
var table = []test{
{id, 160},
{"01abcdefghij01234566", 159},
{"01abcdefghij01234568", 156},
{"01abcdefghij01234569", 156},
{"01abcdefghij0123456a", 153},
{"01abcdefghij0123456b", 153},
{"01abcdefghij0123456c", 153},
{"01abcdefghij0123456d", 153},
}
func TestCommonBits(t *testing.T) {
for _, v := range table {
c := commonBits(id, v.id)
if c != v.proximity {
t.Errorf("test failed for %v, wanted %d got %d", v.id, v.proximity, c)
}
}
}
func TestUpkeep(t *testing.T) {
r := newRoutingTable()
r.nodeId = id
// Current state: 0 neighbors.
for i := 0; i < kNodes; i++ {
// Add a few random nodes. They become neighbors and get added to the
// routing table, but when they are displaced by closer nodes, they
// are killed from the neighbors list and from the routing table, so
// there should be no sign of them later on.
n := randNodeId()
n[0] = byte(0x3d) // Ensure long distance.
r.neighborhoodUpkeep(genremoteNode(string(n)))
}
// Current state: 8 neighbors with low proximity.
// Adds 7 neighbors from the static table. They should replace the
// random ones, except for one.
for _, v := range table[1:8] {
r.neighborhoodUpkeep(genremoteNode(v.id))
}
// Current state: 7 close neighbors, one distant dude.
// The proximity should be from the one remaining random node, thus very low.
p := table[len(table)-1].proximity
if r.proximity >= p {
t.Errorf("proximity: %d >= %d: false", r.proximity, p)
t.Logf("Neighbors:")
for _, v := range r.lookup(id) {
t.Logf("... %q", v.id)
}
}
// Now let's kill the boundary nodes. Killing one makes the next
// "random" node to become the next boundary node (they were kept in
// the routing table). Repeat until all of them are removed.
if r.boundaryNode == nil {
t.Fatalf("tried to kill nil boundary node")
}
r.kill(r.boundaryNode)
// The resulting boundary neighbor should now be one from the static
// table, with high proximity.
p = table[len(table)-1].proximity
if r.proximity != p {
t.Errorf("proximity wanted >= %d, got %d", p, r.proximity)
t.Logf("Later Neighbors:")
for _, v := range r.lookup(id) {
t.Logf("... %x", v.id)
}
}
}
func genremoteNode(id string) *remoteNode {
return &remoteNode{
id: id,
address: randUDPAddr(),
}
}
func randUDPAddr() *net.UDPAddr {
b := make([]byte, 4)
for {
n, err := rand.Read(b)
if n != len(b) || err != nil {
continue
}
break
}
return &net.UDPAddr{
IP: b,
Port: 1111,
}
}