@@ -102,6 +102,15 @@ func overrideTimeAfterFuncWithChannel(t *testing.T) (durChan chan time.Duration,
102102return durChan , timeChan
103103}
104104
105+ // Override the remaining time used by the DNS resolver to allow resolution
106+ func overrideTimeUntilFunc (t * testing.T , now time.Time ) {
107+ origTimeUntil := dnsinternal .TimeUntilFunc
108+ dnsinternal .TimeUntilFunc = func (tm time.Time ) time.Duration {
109+ return now .Sub (tm )
110+ }
111+ t .Cleanup (func () { dnsinternal .TimeUntilFunc = origTimeUntil })
112+ }
113+
105114func enableSRVLookups (t * testing.T ) {
106115origEnableSRVLookups := dns .EnableSRVLookups
107116dns .EnableSRVLookups = true
@@ -1292,16 +1301,12 @@ func (s) TestMinResolutionInterval(t *testing.T) {
12921301}
12931302
12941303// TestMinResolutionInterval_NoExtraDelay verifies that there is no extra delay
1295- // between two resolution requests apart from [MinResolutionInterval]
1296- // i.e. if a request is made after [MinResolutionInterval], it should resolve
1297- // immediately. Test sets [MinResolutionInterval] to 1 second and calls
1298- // ResolveNow() 4 times with a wait of 1 second between each request.
1299- // A correct implementation should resolve all requests without timing out in
1300- // test duration of 5 seconds.
1304+ // between two resolution requests apart from [minResolutionInterval].
1305+ // It sets the minResolutionInterval 1s and overrides timeUntilFunc to
1306+ // calculate remaining time to allow resolution after 1s and verifies that
1307+ // remaining time to allow resolution is very small
13011308func (s ) TestMinResolutionInterval_NoExtraDelay (t * testing.T ) {
1302- const target = "foo.bar.com"
1303-
1304- overrideResolutionInterval (t , 1 * time .Second )
1309+ durChan , timeChan := overrideTimeAfterFuncWithChannel (t )
13051310tr := & testNetResolver {
13061311hostLookupTable : map [string ][]string {
13071312"foo.bar.com" : {"1.2.3.4" , "5.6.7.8" },
@@ -1311,34 +1316,44 @@ func (s) TestMinResolutionInterval_NoExtraDelay(t *testing.T) {
13111316},
13121317}
13131318overrideNetResolver (t , tr )
1319+ var minResolutionInterval = 1 * time .Second
1320+ overrideResolutionInterval (t , minResolutionInterval )
13141321
1315- r , stateCh , _ := buildResolverWithTestClientConn (t , target )
1322+ r , stateCh , errorCh := buildResolverWithTestClientConn (t , "foo.bar.com" )
13161323
1317- wantAddrs := []resolver.Address {{Addr : "1.2.3.4" + colonDefaultPort }, {Addr : "5.6.7.8" + colonDefaultPort }}
1318- wantSC := scJSON
1319-
1320- // set context timeout to test duration of 5 seconds
1321- // to make sure all 4 resolutions happen successfully
1322- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
1323- defer cancel ()
1324+ ctx , ctxCancel := context .WithTimeout (context .Background (), defaultTestTimeout )
1325+ defer ctxCancel ()
1326+ select {
1327+ case <- ctx .Done ():
1328+ t .Fatal ("Timeout when waiting for an error from the resolver" )
1329+ case <- stateCh :
1330+ case err := <- errorCh :
1331+ t .Fatalf ("Unexpected error from resolver, %v" , err )
1332+ }
13241333
1325- // We chose to make 4 requests to strike a balance between coverage and
1326- // test duration. This number is sufficiently large to validate the
1327- // behavior across multiple resolution attempts, while also reducing
1328- // the likelihood of flakiness due to timing issues.
1329- for i := 1 ; i <= 4 ; i ++ {
1330- verifyUpdateFromResolver (ctx , t , stateCh , wantAddrs , nil , wantSC )
1334+ // Make next resolution request after 1s.
1335+ var now = time .Now ().Add (minResolutionInterval )
1336+ overrideTimeUntilFunc (t , now )
1337+ r .ResolveNow (resolver.ResolveNowOptions {})
13311338
1332- // Wait for 1 second to respect [MinResolutionInterval]
1333- // before sending another resolution request
1334- select {
1335- case <- dnsinternal . TimeAfterFunc ( 1 * time . Second ):
1336- // Waited for 1 second
1337- case <- ctx . Done () :
1338- // If the context is done, exit the loop
1339- t .Fatal ( "Timeout when waiting for a state update from the resolver " )
1339+ ctx , cancel := context . WithTimeout ( context . Background (), defaultTestTimeout )
1340+ defer cancel ()
1341+ select {
1342+ case <- ctx . Done ( ):
1343+ t . Fatal ( "Timeout when waiting for an error from the resolver" )
1344+ case dur := <- durChan :
1345+ if dur > 1 * time . Millisecond {
1346+ t .Fatalf ( "Remaining time duration to allow next resolution is higher than expected " )
13401347}
1348+ }
13411349
1342- r .ResolveNow (resolver.ResolveNowOptions {})
1350+ // Unblock the DNS resolver's backoff by pushing the current time.
1351+ timeChan <- time .Now ()
1352+
1353+ select {
1354+ case <- ctx .Done ():
1355+ t .Fatal ("Timeout when waiting for an error from the resolver" )
1356+ case err := <- errorCh :
1357+ t .Fatalf ("Unexpected error from resolver, %v" , err )
13431358}
13441359}
0 commit comments