-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathtable_refresh_test.go
194 lines (160 loc) · 5.54 KB
/
table_refresh_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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package kbucket
import (
"testing"
"time"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/test"
pstore "github.com/libp2p/go-libp2p/p2p/host/peerstore"
"github.com/stretchr/testify/require"
)
func TestGenRandPeerID(t *testing.T) {
t.Parallel()
local := test.RandPeerIDFatal(t)
m := pstore.NewMetrics()
rt, err := NewRoutingTable(1, ConvertPeerID(local), time.Hour, m, NoOpThreshold, nil)
require.NoError(t, err)
// generate above maxCplForRefresh fails
p, err := rt.GenRandPeerID(maxCplForRefresh + 1)
require.Error(t, err)
require.Empty(t, p)
// test generate rand peer ID
for cpl := uint(0); cpl <= maxCplForRefresh; cpl++ {
peerID, err := rt.GenRandPeerID(cpl)
require.NoError(t, err)
require.True(t, uint(CommonPrefixLen(ConvertPeerID(peerID), rt.local)) == cpl, "failed for cpl=%d", cpl)
}
}
func TestGenRandomKey(t *testing.T) {
// test can be run in parallel
t.Parallel()
// run multiple occurences to make sure the test wasn't just lucky
for i := 0; i < 100; i++ {
// generate routing table with random local peer ID
local := test.RandPeerIDFatal(t)
m := pstore.NewMetrics()
rt, err := NewRoutingTable(1, ConvertPeerID(local), time.Hour, m, NoOpThreshold, nil)
require.NoError(t, err)
// GenRandomKey fails for cpl >= 256
_, err = rt.GenRandomKey(256)
require.Error(t, err)
_, err = rt.GenRandomKey(300)
require.Error(t, err)
// bitwise comparison legend:
// O for same bit, X for different bit, ? for don't care
// we compare the returned generated key with the local key
// for CPL = X, the first X bits should be the same, bit X+1 should be
// different, and the rest should be random / don't care
// cpl = 0 should return a different first bit
// X??????? ???...
key0, err := rt.GenRandomKey(0)
require.NoError(t, err)
// most significant bit should be different
require.NotEqual(t, key0[0]>>7, rt.local[0]>>7)
// cpl = 1 should return a different second bit
// OX?????? ???...
key1, err := rt.GenRandomKey(1)
require.NoError(t, err)
// MSB should be equal, as cpl = 1
require.Equal(t, key1[0]>>7, rt.local[0]>>7)
// 2nd MSB should be different
require.NotEqual(t, (key1[0]<<1)>>6, (rt.local[0]<<1)>>6)
// cpl = 2 should return a different third bit
// OOX????? ???...
key2, err := rt.GenRandomKey(2)
require.NoError(t, err)
// 2 MSB should be equal, as cpl = 2
require.Equal(t, key2[0]>>6, rt.local[0]>>6)
// 3rd MSB should be different
require.NotEqual(t, (key2[0]<<2)>>5, (rt.local[0]<<2)>>5)
// cpl = 7 should return a different eighth bit
// OOOOOOOX ???...
key7, err := rt.GenRandomKey(7)
require.NoError(t, err)
// 7 MSB should be equal, as cpl = 7
require.Equal(t, key7[0]>>1, rt.local[0]>>1)
// 8th MSB should be different
require.NotEqual(t, key7[0]<<7, rt.local[0]<<7)
// cpl = 8 should return a different ninth bit
// OOOOOOOO X???...
key8, err := rt.GenRandomKey(8)
require.NoError(t, err)
// 8 MSB should be equal, as cpl = 8
require.Equal(t, key8[0], rt.local[0])
// 9th MSB should be different
require.NotEqual(t, key8[1]>>7, rt.local[1]>>7)
// cpl = 53 should return a different 54th bit
// OOOOOOOO OOOOOOOO OOOOOOOO OOOOOOOO OOOOOOOO OOOOOOOO OOOOOX?? ???...
key53, err := rt.GenRandomKey(53)
require.NoError(t, err)
// 53 MSB should be equal, as cpl = 53
require.Equal(t, key53[:6], rt.local[:6])
require.Equal(t, key53[6]>>3, rt.local[6]>>3)
// 54th MSB should be different
require.NotEqual(t, (key53[6]<<5)>>7, (rt.local[6]<<5)>>7)
}
}
func TestRefreshAndGetTrackedCpls(t *testing.T) {
t.Parallel()
const (
minCpl = 8
testCpl = 10
maxCpl = 12
)
local := test.RandPeerIDFatal(t)
m := pstore.NewMetrics()
rt, err := NewRoutingTable(2, ConvertPeerID(local), time.Hour, m, NoOpThreshold, nil)
require.NoError(t, err)
// fetch cpl's
trackedCpls := rt.GetTrackedCplsForRefresh()
// should have nothing.
require.Len(t, trackedCpls, 1)
var peerIDs []peer.ID
for i := minCpl; i <= maxCpl; i++ {
id, err := rt.GenRandPeerID(uint(i))
require.NoError(t, err)
peerIDs = append(peerIDs, id)
}
// add peer IDs.
for i, id := range peerIDs {
added, err := rt.TryAddPeer(id, true, false)
require.NoError(t, err)
require.True(t, added)
require.Len(t, rt.GetTrackedCplsForRefresh(), minCpl+i+1)
}
// and remove down to the test CPL
for i := maxCpl; i > testCpl; i-- {
rt.RemovePeer(peerIDs[i-minCpl])
require.Len(t, rt.GetTrackedCplsForRefresh(), i)
}
// should be tracking testCpl
trackedCpls = rt.GetTrackedCplsForRefresh()
require.Len(t, trackedCpls, testCpl+1)
// they should all be zero
for _, refresh := range trackedCpls {
require.True(t, refresh.IsZero(), "tracked cpl's should be zero")
}
// add our peer ID to max out the table
added, err := rt.TryAddPeer(local, true, false)
require.NoError(t, err)
require.True(t, added)
// should be tracking the max
trackedCpls = rt.GetTrackedCplsForRefresh()
require.Len(t, trackedCpls, int(maxCplForRefresh)+1)
// and not refreshed
for _, refresh := range trackedCpls {
require.True(t, refresh.IsZero(), "tracked cpl's should be zero")
}
now := time.Now()
// reset the test peer ID.
rt.ResetCplRefreshedAtForID(ConvertPeerID(peerIDs[testCpl-minCpl]), now)
// should still be tracking all buckets
trackedCpls = rt.GetTrackedCplsForRefresh()
require.Len(t, trackedCpls, int(maxCplForRefresh)+1)
for i, refresh := range trackedCpls {
if i == testCpl {
require.True(t, now.Equal(refresh), "test cpl should have the correct refresh time")
} else {
require.True(t, refresh.IsZero(), "other cpl's should be 0")
}
}
}