@@ -102,6 +102,27 @@ func overrideTimeAfterFuncWithChannel(t *testing.T) (durChan chan time.Duration,
102
102
return durChan , timeChan
103
103
}
104
104
105
+ // Override the current time used by the DNS resolver.
106
+ func overrideTimeNowFunc (t * testing.T , now time.Time ) {
107
+ origTimeNowFunc := dnsinternal .TimeNowFunc
108
+ dnsinternal .TimeNowFunc = func () time.Time { return now }
109
+ t .Cleanup (func () { dnsinternal .TimeNowFunc = origTimeNowFunc })
110
+ }
111
+
112
+ // Override the remaining wait time to allow re-resolution by DNS resolver.
113
+ // Use the timeChan to read the time until resolver needs to wait for
114
+ // and return 0 wait time.
115
+ func overrideTimeUntilFuncWithChannel (t * testing.T ) (timeChan chan time.Time ) {
116
+ timeCh := make (chan time.Time , 1 )
117
+ origTimeUntil := dnsinternal .TimeUntilFunc
118
+ dnsinternal .TimeUntilFunc = func (t time.Time ) time.Duration {
119
+ timeCh <- t
120
+ return 0
121
+ }
122
+ t .Cleanup (func () { dnsinternal .TimeUntilFunc = origTimeUntil })
123
+ return timeCh
124
+ }
125
+
105
126
func enableSRVLookups (t * testing.T ) {
106
127
origEnableSRVLookups := dns .EnableSRVLookups
107
128
dns .EnableSRVLookups = true
@@ -1290,3 +1311,60 @@ func (s) TestMinResolutionInterval(t *testing.T) {
1290
1311
r .ResolveNow (resolver.ResolveNowOptions {})
1291
1312
}
1292
1313
}
1314
+
1315
+ // TestMinResolutionInterval_NoExtraDelay verifies that there is no extra delay
1316
+ // between two resolution requests apart from [MinResolutionInterval].
1317
+ func (s ) TestMinResolutionInterval_NoExtraDelay (t * testing.T ) {
1318
+ tr := & testNetResolver {
1319
+ hostLookupTable : map [string ][]string {
1320
+ "foo.bar.com" : {"1.2.3.4" , "5.6.7.8" },
1321
+ },
1322
+ txtLookupTable : map [string ][]string {
1323
+ "_grpc_config.foo.bar.com" : txtRecordServiceConfig (txtRecordGood ),
1324
+ },
1325
+ }
1326
+ overrideNetResolver (t , tr )
1327
+ // Override time.Now() to return a zero value for time. This will allow us
1328
+ // to verify that the call to time.Until is made with the exact
1329
+ // [MinResolutionInterval] that we expect.
1330
+ overrideTimeNowFunc (t , time.Time {})
1331
+ // Override time.Until() to read the time passed to it
1332
+ // and return immediately without any delay
1333
+ timeCh := overrideTimeUntilFuncWithChannel (t )
1334
+
1335
+ r , stateCh , errorCh := buildResolverWithTestClientConn (t , "foo.bar.com" )
1336
+
1337
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
1338
+ defer cancel ()
1339
+
1340
+ // Ensure that the first resolution happens.
1341
+ select {
1342
+ case <- ctx .Done ():
1343
+ t .Fatal ("Timeout when waiting for DNS resolver" )
1344
+ case err := <- errorCh :
1345
+ t .Fatalf ("Unexpected error from resolver, %v" , err )
1346
+ case <- stateCh :
1347
+ }
1348
+
1349
+ // Request re-resolution and verify that the resolver waits for
1350
+ // [MinResolutionInterval].
1351
+ r .ResolveNow (resolver.ResolveNowOptions {})
1352
+ select {
1353
+ case <- ctx .Done ():
1354
+ t .Fatal ("Timeout when waiting for DNS resolver" )
1355
+ case gotTime := <- timeCh :
1356
+ wantTime := time.Time {}.Add (dns .MinResolutionInterval )
1357
+ if ! gotTime .Equal (wantTime ) {
1358
+ t .Fatalf ("DNS resolver waits for %v time before re-resolution, want %v" , gotTime , wantTime )
1359
+ }
1360
+ }
1361
+
1362
+ // Ensure that the re-resolution request actually happens.
1363
+ select {
1364
+ case <- ctx .Done ():
1365
+ t .Fatal ("Timeout when waiting for an error from the resolver" )
1366
+ case err := <- errorCh :
1367
+ t .Fatalf ("Unexpected error from resolver, %v" , err )
1368
+ case <- stateCh :
1369
+ }
1370
+ }
0 commit comments