Skip to content

Commit e37c780

Browse files
committed
mutex;
1 parent cd3888e commit e37c780

File tree

1 file changed

+29
-42
lines changed

1 file changed

+29
-42
lines changed

cmd/lakectl/cmd/token_cacing_test.go

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,16 @@ func TestTokenExpiredWrite(t *testing.T) {
195195
require.Nil(t, token)
196196
})
197197
}
198+
199+
var testMutex sync.Mutex
200+
198201
func resetGlobalState() {
202+
testMutex.Lock()
203+
defer testMutex.Unlock()
204+
205+
// Wait longer to ensure all callback goroutines complete
206+
time.Sleep(500 * time.Millisecond)
207+
199208
tokenLoadOnce = sync.Once{}
200209
tokenCacheOnce = sync.Once{}
201210
tokenSaveOnce = sync.Once{}
@@ -208,7 +217,6 @@ func resetGlobalState() {
208217
os.RemoveAll(cacheDir)
209218
}
210219
}
211-
212220
func setupTestHomeDir(t *testing.T) (cleanup func()) {
213221
tempDir := t.TempDir()
214222
originalHome := os.Getenv("HOME")
@@ -310,12 +318,8 @@ func createSecurityProvider(mockClient *mockExternalLoginClient, initialToken *a
310318
)
311319
}
312320

313-
var testMutex sync.Mutex
314-
315321
func TestLoginOnlyOnce(t *testing.T) {
316322
t.Run("login called only once across multiple requests", func(t *testing.T) {
317-
testMutex.Lock()
318-
defer testMutex.Unlock()
319323
resetGlobalState()
320324
cleanup := setupTestHomeDir(t)
321325
defer cleanup()
@@ -329,26 +333,18 @@ func TestLoginOnlyOnce(t *testing.T) {
329333
provider := createSecurityProvider(mockClient, nil, &callbackCount)
330334
require.Nil(t, provider.AuthenticationToken)
331335

332-
// Add debug logging
333-
t.Logf("Before Intercept - Token: %v", provider.AuthenticationToken)
334-
t.Logf("Before Intercept - Login count: %d", mockClient.getLoginCount())
335-
336336
req1 := httptest.NewRequest("GET", "http://example.com/api/v1/repositories", nil)
337337
err := provider.Intercept(context.Background(), req1)
338338

339-
t.Logf("After Intercept - Token: %v", provider.AuthenticationToken)
340-
t.Logf("After Intercept - Login count: %d", mockClient.getLoginCount())
341-
t.Logf("Authorization header: %s", req1.Header.Get("Authorization"))
342-
343339
require.NoError(t, err)
344340
require.Equal(t, "Bearer cached-token", req1.Header.Get("Authorization"))
345341
require.Equal(t, int64(1), mockClient.getLoginCount())
342+
343+
// Wait for callback goroutine to complete
344+
time.Sleep(200 * time.Millisecond)
346345
})
347-
// }
348-
// func TestNoLoginWhenTokenIsGiven(t *testing.T) {
346+
349347
t.Run("no login performed when valid token provided initially", func(t *testing.T) {
350-
testMutex.Lock()
351-
defer testMutex.Unlock()
352348
resetGlobalState()
353349
cleanup := setupTestHomeDir(t)
354350
defer cleanup()
@@ -367,20 +363,17 @@ func TestLoginOnlyOnce(t *testing.T) {
367363
var callbackCount int64
368364
provider := createSecurityProvider(mockClient, existingToken, &callbackCount)
369365

370-
// Request should use existing token, no login
371366
req := httptest.NewRequest("GET", "http://example.com/api/v1/repositories", nil)
372367
err := provider.Intercept(context.Background(), req)
373368
require.NoError(t, err)
374369
require.Equal(t, "Bearer pre-existing-token", req.Header.Get("Authorization"))
375-
require.Equal(t, int64(0), mockClient.getLoginCount()) // No login called
376-
time.Sleep(time.Second)
377-
require.Equal(t, int64(0), atomic.LoadInt64(&callbackCount)) // No callback called
370+
require.Equal(t, int64(0), mockClient.getLoginCount())
371+
372+
time.Sleep(200 * time.Millisecond)
373+
require.Equal(t, int64(0), atomic.LoadInt64(&callbackCount))
378374
})
379-
// }
380-
// func TestRealInterceptWithGlobalCache2(t *testing.T) {
375+
381376
t.Run("handles login failure gracefully", func(t *testing.T) {
382-
testMutex.Lock()
383-
defer testMutex.Unlock()
384377
resetGlobalState()
385378
cleanup := setupTestHomeDir(t)
386379
defer cleanup()
@@ -393,20 +386,17 @@ func TestLoginOnlyOnce(t *testing.T) {
393386
var callbackCount int64
394387
provider := createSecurityProvider(mockClient, nil, &callbackCount)
395388

396-
// Request should fail due to login failure
397389
req := httptest.NewRequest("GET", "http://example.com/api/v1/repositories", nil)
398390
err := provider.Intercept(context.Background(), req)
399391
require.ErrorIs(t, err, errMockLoginFailed)
400392
require.Empty(t, req.Header.Get("Authorization"))
401-
require.Equal(t, int64(1), mockClient.getLoginCount()) // Login attempted once
402-
time.Sleep(time.Second)
403-
require.Equal(t, int64(0), atomic.LoadInt64(&callbackCount)) // No callback on failure
393+
require.Equal(t, int64(1), mockClient.getLoginCount())
394+
395+
time.Sleep(200 * time.Millisecond)
396+
require.Equal(t, int64(0), atomic.LoadInt64(&callbackCount))
404397
})
405-
// }
406-
// func TestRealInterceptWithGlobalCache5(t *testing.T) {
398+
407399
t.Run("token cached via callback and reused after provider recreation", func(t *testing.T) {
408-
testMutex.Lock()
409-
defer testMutex.Unlock()
410400
resetGlobalState()
411401
cleanup := setupTestHomeDir(t)
412402
defer cleanup()
@@ -419,34 +409,31 @@ func TestLoginOnlyOnce(t *testing.T) {
419409
var callbackCount int64
420410
provider1 := createSecurityProvider(mockClient, nil, &callbackCount)
421411

422-
// First request - should trigger login and cache via callback
423412
req1 := httptest.NewRequest("GET", "http://example.com/api/v1/repositories", nil)
424413
err := provider1.Intercept(context.Background(), req1)
425414
require.NoError(t, err)
426415
require.Equal(t, "Bearer callback-cached-token", req1.Header.Get("Authorization"))
427416
require.Equal(t, int64(1), mockClient.getLoginCount())
428-
time.Sleep(time.Second)
417+
418+
time.Sleep(200 * time.Millisecond)
429419
require.Equal(t, int64(1), atomic.LoadInt64(&callbackCount))
430420

431-
// Verify token was saved to global cache
432421
require.NotNil(t, cachedToken)
433422
require.Equal(t, "callback-cached-token", cachedToken.Token)
434423

435-
// Create new provider instance (simulating new command execution)
436424
mockClient.resetLoginCount()
437425
callbackCount = 0
438426

439-
// Get token from cache using global function
440427
cachedTokenFromFile := getTokenOnce()
441428
provider2 := createSecurityProvider(mockClient, cachedTokenFromFile, &callbackCount)
442429

443-
// Second request with new provider should use cached token from file
444430
req2 := httptest.NewRequest("GET", "http://example.com/api/v1/repositories", nil)
445431
err = provider2.Intercept(context.Background(), req2)
446432
require.NoError(t, err)
447433
require.Equal(t, "Bearer callback-cached-token", req2.Header.Get("Authorization"))
448-
require.Equal(t, int64(0), mockClient.getLoginCount()) // No new login, used cache
449-
time.Sleep(time.Second)
450-
require.Equal(t, int64(0), atomic.LoadInt64(&callbackCount)) // No new callback
434+
require.Equal(t, int64(0), mockClient.getLoginCount())
435+
436+
time.Sleep(200 * time.Millisecond)
437+
require.Equal(t, int64(0), atomic.LoadInt64(&callbackCount))
451438
})
452439
}

0 commit comments

Comments
 (0)