]> Sergey Matveev's repositories - btrtrc.git/blob - dht/dht_test.go
f84ccb68f8a9788518fe07acc6b26ffe9ca3ac8c
[btrtrc.git] / dht / dht_test.go
1 package dht
2
3 import (
4         "encoding/hex"
5         "math/big"
6         "math/rand"
7         "net"
8         "testing"
9
10         "github.com/anacrolix/missinggo"
11         "github.com/stretchr/testify/assert"
12 )
13
14 func TestSetNilBigInt(t *testing.T) {
15         i := new(big.Int)
16         i.SetBytes(make([]byte, 2))
17 }
18
19 func TestMarshalCompactNodeInfo(t *testing.T) {
20         cni := NodeInfo{
21                 ID: [20]byte{'a', 'b', 'c'},
22         }
23         addr, err := net.ResolveUDPAddr("udp4", "1.2.3.4:5")
24         if err != nil {
25                 t.Fatal(err)
26         }
27         cni.Addr = newDHTAddr(addr)
28         var b [CompactNodeInfoLen]byte
29         cni.PutCompact(b[:])
30         if err != nil {
31                 t.Fatal(err)
32         }
33         var bb [26]byte
34         copy(bb[:], []byte("abc"))
35         copy(bb[20:], []byte("\x01\x02\x03\x04\x00\x05"))
36         if b != bb {
37                 t.FailNow()
38         }
39 }
40
41 func recoverPanicOrDie(t *testing.T, f func()) {
42         defer func() {
43                 r := recover()
44                 if r == nil {
45                         t.Fatal("expected panic")
46                 }
47         }()
48         f()
49 }
50
51 const zeroID = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
52
53 var testIDs []nodeID
54
55 func init() {
56         for _, s := range []string{
57                 zeroID,
58                 "\x03" + zeroID[1:],
59                 "\x03" + zeroID[1:18] + "\x55\xf0",
60                 "\x55" + zeroID[1:17] + "\xff\x55\x0f",
61                 "\x54" + zeroID[1:18] + "\x50\x0f",
62                 "",
63         } {
64                 testIDs = append(testIDs, nodeIDFromString(s))
65         }
66 }
67
68 func TestDistances(t *testing.T) {
69         expectBitcount := func(i big.Int, count int) {
70                 if bitCount(i) != count {
71                         t.Fatalf("expected bitcount of %d: got %d", count, bitCount(i))
72                 }
73         }
74         expectBitcount(testIDs[3].Distance(&testIDs[0]), 4+8+4+4)
75         expectBitcount(testIDs[3].Distance(&testIDs[1]), 4+8+4+4)
76         expectBitcount(testIDs[3].Distance(&testIDs[2]), 4+8+8)
77         for i := 0; i < 5; i++ {
78                 dist := testIDs[i].Distance(&testIDs[5])
79                 if dist.Cmp(&maxDistance) != 0 {
80                         t.Fatal("expected max distance for comparison with unset node id")
81                 }
82         }
83 }
84
85 func TestMaxDistanceString(t *testing.T) {
86         if string(maxDistance.Bytes()) != "\x01"+zeroID {
87                 t.FailNow()
88         }
89 }
90
91 func TestClosestNodes(t *testing.T) {
92         cn := newKClosestNodesSelector(2, testIDs[3])
93         for _, i := range rand.Perm(len(testIDs)) {
94                 cn.Push(testIDs[i])
95         }
96         if len(cn.IDs()) != 2 {
97                 t.FailNow()
98         }
99         m := map[string]bool{}
100         for _, id := range cn.IDs() {
101                 m[id.ByteString()] = true
102         }
103         if !m[testIDs[3].ByteString()] || !m[testIDs[4].ByteString()] {
104                 t.FailNow()
105         }
106 }
107
108 func TestUnmarshalGetPeersResponse(t *testing.T) {
109         gpr := Msg{
110                 "r": map[string]interface{}{
111                         "values": []interface{}{"\x01\x02\x03\x04\x05\x06", "\x07\x08\x09\x0a\x0b\x0c"},
112                         "nodes":  "\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x02\x03\x04\x05\x06\x07\x08\x09\x02\x03\x04\x05\x06\x07" + "\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x02\x03\x04\x05\x06\x07\x08\x09\x02\x03\x04\x05\x06\x07",
113                 },
114         }
115         assert.EqualValues(t, 2, len(gpr.Values()))
116         assert.EqualValues(t, 2, len(gpr.Nodes()))
117 }
118
119 func TestDHTDefaultConfig(t *testing.T) {
120         s, err := NewServer(nil)
121         if err != nil {
122                 t.Fatal(err)
123         }
124         s.Close()
125 }
126
127 func TestPing(t *testing.T) {
128         srv, err := NewServer(nil)
129         if err != nil {
130                 t.Fatal(err)
131         }
132         defer srv.Close()
133         srv0, err := NewServer(nil)
134         if err != nil {
135                 t.Fatal(err)
136         }
137         defer srv0.Close()
138         tn, err := srv.Ping(&net.UDPAddr{
139                 IP:   []byte{127, 0, 0, 1},
140                 Port: srv0.Addr().(*net.UDPAddr).Port,
141         })
142         if err != nil {
143                 t.Fatal(err)
144         }
145         defer tn.Close()
146         ok := make(chan bool)
147         tn.SetResponseHandler(func(msg Msg) {
148                 ok <- msg.SenderID() == srv0.ID()
149         })
150         if !<-ok {
151                 t.FailNow()
152         }
153 }
154
155 func TestDHTSec(t *testing.T) {
156         for _, case_ := range []struct {
157                 ipStr     string
158                 nodeIDHex string
159                 valid     bool
160         }{
161                 // These 5 are from the spec example. They are all valid.
162                 {"124.31.75.21", "5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee401", true},
163                 {"21.75.31.124", "5a3ce9c14e7a08645677bbd1cfe7d8f956d53256", true},
164                 {"65.23.51.170", "a5d43220bc8f112a3d426c84764f8c2a1150e616", true},
165                 {"84.124.73.14", "1b0321dd1bb1fe518101ceef99462b947a01ff41", true},
166                 {"43.213.53.83", "e56f6cbf5b7c4be0237986d5243b87aa6d51305a", true},
167                 // spec[0] with one of the rand() bytes changed. Valid.
168                 {"124.31.75.21", "5fbfbff10c5d7a4ec8a88e4c6ab4c28b95eee401", true},
169                 // spec[1] with the 21st leading bit changed. Not Valid.
170                 {"21.75.31.124", "5a3ce1c14e7a08645677bbd1cfe7d8f956d53256", false},
171                 // spec[2] with the 22nd leading bit changed. Valid.
172                 {"65.23.51.170", "a5d43620bc8f112a3d426c84764f8c2a1150e616", true},
173                 // spec[3] with the 4th last bit changed. Valid.
174                 {"84.124.73.14", "1b0321dd1bb1fe518101ceef99462b947a01fe01", true},
175                 // spec[4] with the 3rd last bit changed. Not valid.
176                 {"43.213.53.83", "e56f6cbf5b7c4be0237986d5243b87aa6d51303e", false},
177         } {
178                 ip := net.ParseIP(case_.ipStr)
179                 id, err := hex.DecodeString(case_.nodeIDHex)
180                 if err != nil {
181                         t.Fatal(err)
182                 }
183                 secure := NodeIdSecure(string(id), ip)
184                 if secure != case_.valid {
185                         t.Fatalf("case failed: %v", case_)
186                 }
187                 if !secure {
188                         SecureNodeId(id, ip)
189                         if !NodeIdSecure(string(id), ip) {
190                                 t.Fatal("failed to secure node id")
191                         }
192                 }
193         }
194 }
195
196 func TestServerDefaultNodeIdSecure(t *testing.T) {
197         s, err := NewServer(nil)
198         if err != nil {
199                 t.Fatal(err)
200         }
201         defer s.Close()
202         if !NodeIdSecure(s.ID(), missinggo.AddrIP(s.Addr())) {
203                 t.Fatal("not secure")
204         }
205 }