@@ -19,6 +19,7 @@ package dnsdisc
19
19
import (
20
20
"context"
21
21
"crypto/ecdsa"
22
+ "errors"
22
23
"math/rand"
23
24
"reflect"
24
25
"testing"
@@ -176,11 +177,62 @@ func TestIteratorNodeUpdates(t *testing.T) {
176
177
t .Fatal (err )
177
178
}
178
179
179
- // sync the original tree.
180
+ // Sync the original tree.
180
181
resolver .add (tree1 .ToTXT ("n" ))
181
182
checkIterator (t , it , nodes [:25 ])
182
183
183
- // Update some nodes and ensure RandomNode returns the new nodes as well.
184
+ // Ensure RandomNode returns the new nodes after the tree is updated.
185
+ updateSomeNodes (nodesSeed1 , nodes )
186
+ tree2 , _ := makeTestTree ("n" , nodes , nil )
187
+ resolver .clear ()
188
+ resolver .add (tree2 .ToTXT ("n" ))
189
+ t .Log ("tree updated" )
190
+
191
+ clock .Run (c .cfg .RecheckInterval + 1 * time .Second )
192
+ checkIterator (t , it , nodes )
193
+ }
194
+
195
+ // This test checks that the tree root is rechecked when a couple of leaf
196
+ // requests have failed. The test is just like TestIteratorNodeUpdates, but
197
+ // without advancing the clock by recheckInterval after the tree update.
198
+ func TestIteratorRootRecheckOnFail (t * testing.T ) {
199
+ var (
200
+ clock = new (mclock.Simulated )
201
+ nodes = testNodes (nodesSeed1 , 30 )
202
+ resolver = newMapResolver ()
203
+ c = NewClient (Config {
204
+ Resolver : resolver ,
205
+ Logger : testlog .Logger (t , log .LvlTrace ),
206
+ RecheckInterval : 20 * time .Minute ,
207
+ RateLimit : 500 ,
208
+ // Disabling the cache is required for this test because the client doesn't
209
+ // notice leaf failures if all records are cached.
210
+ CacheLimit : 1 ,
211
+ })
212
+ )
213
+ c .clock = clock
214
+ tree1 , url := makeTestTree ("n" , nodes [:25 ], nil )
215
+ it , err := c .NewIterator (url )
216
+ if err != nil {
217
+ t .Fatal (err )
218
+ }
219
+
220
+ // Sync the original tree.
221
+ resolver .add (tree1 .ToTXT ("n" ))
222
+ checkIterator (t , it , nodes [:25 ])
223
+
224
+ // Ensure RandomNode returns the new nodes after the tree is updated.
225
+ updateSomeNodes (nodesSeed1 , nodes )
226
+ tree2 , _ := makeTestTree ("n" , nodes , nil )
227
+ resolver .clear ()
228
+ resolver .add (tree2 .ToTXT ("n" ))
229
+ t .Log ("tree updated" )
230
+
231
+ checkIterator (t , it , nodes )
232
+ }
233
+
234
+ // updateSomeNodes applies ENR updates to some of the given nodes.
235
+ func updateSomeNodes (keySeed int64 , nodes []* enode.Node ) {
184
236
keys := testKeys (nodesSeed1 , len (nodes ))
185
237
for i , n := range nodes [:len (nodes )/ 2 ] {
186
238
r := n .Record ()
@@ -190,11 +242,6 @@ func TestIteratorNodeUpdates(t *testing.T) {
190
242
n2 , _ := enode .New (enode .ValidSchemes , r )
191
243
nodes [i ] = n2
192
244
}
193
- tree2 , _ := makeTestTree ("n" , nodes , nil )
194
- clock .Run (c .cfg .RecheckInterval + 1 * time .Second )
195
- resolver .clear ()
196
- resolver .add (tree2 .ToTXT ("n" ))
197
- checkIterator (t , it , nodes )
198
245
}
199
246
200
247
// This test verifies that randomIterator re-checks the root of the tree to catch
@@ -230,9 +277,10 @@ func TestIteratorLinkUpdates(t *testing.T) {
230
277
// Add link to tree3, remove link to tree2.
231
278
tree1 , _ = makeTestTree ("t1" , nodes [:10 ], []string {url3 })
232
279
resolver .add (tree1 .ToTXT ("t1" ))
233
- clock .Run (c .cfg .RecheckInterval + 1 * time .Second )
234
280
t .Log ("tree1 updated" )
235
281
282
+ clock .Run (c .cfg .RecheckInterval + 1 * time .Second )
283
+
236
284
var wantNodes []* enode.Node
237
285
wantNodes = append (wantNodes , tree1 .Nodes ()... )
238
286
wantNodes = append (wantNodes , tree3 .Nodes ()... )
@@ -345,5 +393,5 @@ func (mr mapResolver) LookupTXT(ctx context.Context, name string) ([]string, err
345
393
if record , ok := mr [name ]; ok {
346
394
return []string {record }, nil
347
395
}
348
- return nil , nil
396
+ return nil , errors . New ( "not found" )
349
397
}
0 commit comments