@@ -102,6 +102,27 @@ func overrideTimeAfterFuncWithChannel(t *testing.T) (durChan chan time.Duration,
102102 return durChan , timeChan
103103}
104104
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+
105126func enableSRVLookups (t * testing.T ) {
106127 origEnableSRVLookups := dns .EnableSRVLookups
107128 dns .EnableSRVLookups = true
@@ -1290,3 +1311,60 @@ func (s) TestMinResolutionInterval(t *testing.T) {
12901311 r .ResolveNow (resolver.ResolveNowOptions {})
12911312 }
12921313}
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