44 "context"
55 "errors"
66 "strconv"
7+ "sync/atomic"
78 "testing"
89 "time"
910
@@ -15,11 +16,11 @@ import (
1516// mockDNSResolver implements DNSResolver for testing
1617type mockDNSResolver struct {
1718 lookupFunc func (ctx context.Context , addr string ) ([]string , error )
18- lookupCount int
19+ lookupCount atomic. Int64
1920}
2021
2122func (m * mockDNSResolver ) LookupAddr (ctx context.Context , addr string ) ([]string , error ) {
22- m .lookupCount ++
23+ m .lookupCount . Add ( 1 )
2324 if m .lookupFunc != nil {
2425 return m .lookupFunc (ctx , addr )
2526 }
@@ -84,7 +85,7 @@ func TestDNSEnrichment_CacheHit(t *testing.T) {
8485 assert .False (t , needsAsync , "Should not need async on cache hit" )
8586
8687 // Verify no DNS lookup was performed (cache hit)
87- assert .Equal (t , 0 , mockResolver .lookupCount , "DNS lookup should not be called on cache hit" )
88+ assert .Equal (t , int64 ( 0 ) , mockResolver .lookupCount . Load () , "DNS lookup should not be called on cache hit" )
8889}
8990
9091// TestDNSEnrichment_CacheMiss_Success tests cache miss with successful lookup
@@ -122,19 +123,19 @@ func TestDNSEnrichment_CacheMiss_Success(t *testing.T) {
122123 assert .Equal (t , "resolved.example.com" , result , "Should return resolved hostname" )
123124
124125 // Verify DNS lookup was performed
125- assert .Equal (t , 1 , mockResolver .lookupCount , "DNS lookup should be called on cache miss" )
126+ assert .Equal (t , int64 ( 1 ) , mockResolver .lookupCount . Load () , "DNS lookup should be called on cache miss" )
126127
127128 // Verify result was cached
128129 val , exists := c .dnsCache .Get ("192.0.2.2" )
129130 assert .True (t , exists , "Result should be cached" )
130131 assert .Equal (t , "resolved.example.com" , val .(string ), "Cached value should match resolved hostname" )
131132
132133 // Second call should hit cache (no additional lookup)
133- mockResolver .lookupCount = 0
134+ mockResolver .lookupCount . Store ( 0 )
134135 hostname2 , needsAsync2 := c .enrichWithDNSSync ("192.0.2.2" )
135136 assert .Equal (t , "resolved.example.com" , hostname2 , "Should return cached hostname" )
136137 assert .False (t , needsAsync2 , "Should not need async on cache hit" )
137- assert .Equal (t , 0 , mockResolver .lookupCount , "Second call should hit cache" )
138+ assert .Equal (t , int64 ( 0 ) , mockResolver .lookupCount . Load () , "Second call should hit cache" )
138139}
139140
140141// TestDNSEnrichment_CacheMiss_Timeout tests cache miss with timeout
@@ -173,7 +174,7 @@ func TestDNSEnrichment_CacheMiss_Timeout(t *testing.T) {
173174 assert .Equal (t , "" , result , "Should return empty on timeout" )
174175
175176 // Verify DNS lookup was attempted
176- assert .Equal (t , 1 , mockResolver .lookupCount , "DNS lookup should be attempted" )
177+ assert .Equal (t , int64 ( 1 ) , mockResolver .lookupCount . Load () , "DNS lookup should be attempted" )
177178}
178179
179180// TestDNSEnrichment_CacheMiss_Failure tests cache miss with DNS failure
@@ -206,7 +207,7 @@ func TestDNSEnrichment_CacheMiss_Failure(t *testing.T) {
206207 assert .Equal (t , "" , result , "Should return empty on DNS failure" )
207208
208209 // Verify DNS lookup was attempted
209- assert .Equal (t , 1 , mockResolver .lookupCount , "DNS lookup should be attempted" )
210+ assert .Equal (t , int64 ( 1 ) , mockResolver .lookupCount . Load () , "DNS lookup should be attempted" )
210211}
211212
212213// TestDNSEnrichment_CacheTTL tests that cache entries expire after TTL
@@ -239,22 +240,27 @@ func TestDNSEnrichment_CacheTTL(t *testing.T) {
239240 // First lookup - cache miss (blocking)
240241 result1 := c .enrichWithDNSBlocking ("192.0.2.5" )
241242 assert .Equal (t , "ttl-test.example.com" , result1 )
242- assert .Equal (t , 1 , mockResolver .lookupCount )
243+ assert .Equal (t , int64 ( 1 ) , mockResolver .lookupCount . Load () )
243244
244245 // Immediate second lookup - cache hit
245- mockResolver .lookupCount = 0
246+ mockResolver .lookupCount . Store ( 0 )
246247 hostname2 , needsAsync2 := c .enrichWithDNSSync ("192.0.2.5" )
247248 assert .Equal (t , "ttl-test.example.com" , hostname2 )
248249 assert .False (t , needsAsync2 , "Should hit cache" )
249- assert .Equal (t , 0 , mockResolver .lookupCount , "Should hit cache" )
250+ assert .Equal (t , int64 ( 0 ) , mockResolver .lookupCount . Load () , "Should hit cache" )
250251
251- // Wait for cache entry to expire
252- time .Sleep (600 * time .Millisecond )
252+ // Wait for cache entry to expire and verify a new lookup occurs
253+ assert .Eventually (t , func () bool {
254+ mockResolver .lookupCount .Store (0 )
255+ _ , needsAsync := c .enrichWithDNSSync ("192.0.2.5" )
256+ return needsAsync
257+ }, 5 * time .Second , 100 * time .Millisecond , "Cache entry should eventually expire" )
253258
254- // Third lookup after expiry - cache miss again
259+ // Now do a blocking lookup to get fresh result
260+ mockResolver .lookupCount .Store (0 )
255261 result3 := c .enrichWithDNSBlocking ("192.0.2.5" )
256262 assert .Equal (t , "ttl-test.example.com" , result3 )
257- assert .Equal (t , 1 , mockResolver .lookupCount , "Should do new lookup after TTL expiry" )
263+ assert .Equal (t , int64 ( 1 ) , mockResolver .lookupCount . Load () , "Should do new lookup after TTL expiry" )
258264}
259265
260266// TestDNSEnrichment_Concurrency tests multiple concurrent DNS lookups
@@ -306,7 +312,7 @@ func TestDNSEnrichment_Concurrency(t *testing.T) {
306312
307313 // All requests should succeed (workers handle them concurrently)
308314 assert .Equal (t , numRequests , successCount , "All concurrent lookups should succeed" )
309- assert .GreaterOrEqual (t , mockResolver .lookupCount , numRequests , "All lookups should be performed" )
315+ assert .GreaterOrEqual (t , mockResolver .lookupCount . Load (), int64 ( numRequests ) , "All lookups should be performed" )
310316}
311317
312318// TestDNSEnrichment_Integration tests full integration with record creation
@@ -426,7 +432,7 @@ func TestDNSEnrichment_Integration(t *testing.T) {
426432 assert .Equal (t , "university.edu" , record .UserDomain , "User domain should be extracted from enriched hostname" )
427433
428434 // Verify DNS lookup was performed (once for user IP, once for server IP)
429- assert .Equal (t , 2 , mockResolver .lookupCount , "DNS lookup should be performed for user and server IPs" )
435+ assert .Equal (t , int64 ( 2 ) , mockResolver .lookupCount . Load () , "DNS lookup should be performed for user and server IPs" )
430436
431437 // Verify result was cached for user IP
432438 val , exists := c .dnsCache .Get ("192.0.2.10" )
0 commit comments