@@ -1457,21 +1457,25 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1457
1457
select {
1458
1458
case tokenCh <- t :
1459
1459
default :
1460
+ // Channel full, ignore
1460
1461
}
1461
1462
},
1462
1463
onErrorFunc : func (err error ) {
1463
1464
select {
1464
1465
case errorCh <- err :
1465
1466
default :
1467
+ // Channel full, ignore
1466
1468
}
1467
1469
},
1468
1470
}
1469
1471
1470
1472
// Choose operation based on a pattern
1473
+ // Using modulo for a deterministic pattern that exercises all operations
1471
1474
opType := j % 3
1472
1475
1473
1476
switch opType {
1474
1477
case 0 :
1478
+ // Start the token manager with a new listener
1475
1479
closeFunc , err := tm .Start (listener )
1476
1480
1477
1481
if err != nil {
@@ -1485,12 +1489,15 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1485
1489
continue
1486
1490
}
1487
1491
1492
+ // Store the closer for later cleanup
1488
1493
closerKey := fmt .Sprintf ("closer-%d-%d" , routineID , j )
1489
1494
closers .Store (closerKey , closeFunc )
1490
1495
1496
+ // Simulate some work
1491
1497
time .Sleep (time .Duration (500 - rand .Intn (400 )) * time .Millisecond )
1492
1498
1493
1499
case 1 :
1500
+ // Get current token
1494
1501
token , err := tm .GetToken (false )
1495
1502
if err != nil {
1496
1503
select {
@@ -1502,12 +1509,15 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1502
1509
select {
1503
1510
case tokenCh <- token :
1504
1511
default :
1512
+ // Channel full, ignore
1505
1513
}
1506
1514
}
1507
1515
1508
1516
case 2 :
1517
+ // Close a previously created token manager listener
1518
+ // This simulates multiple subscriptions being created and destroyed
1509
1519
closers .Range (func (key , value interface {}) bool {
1510
- if j % 10 > 7 {
1520
+ if j % 10 > 7 { // Only close some of the time based on a pattern
1511
1521
closeFunc := value .(StopFunc )
1512
1522
if err := closeFunc (); err != nil {
1513
1523
if err != ErrTokenManagerAlreadyStopped {
@@ -1520,7 +1530,7 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1520
1530
}
1521
1531
1522
1532
closers .Delete (key )
1523
- return false
1533
+ return false // stop after finding one to close
1524
1534
}
1525
1535
return true
1526
1536
})
@@ -1538,6 +1548,8 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1538
1548
// Use a timeout to detect deadlocks
1539
1549
select {
1540
1550
case <- doneCh :
1551
+ // All operations completed successfully
1552
+ t .Log ("All concurrent operations completed successfully" )
1541
1553
case <- time .After (30 * time .Second ):
1542
1554
t .Fatal ("test timed out, possible deadlock detected" )
1543
1555
}
@@ -1596,6 +1608,14 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1596
1608
totalOps := startCount + getTokenCount + closeCount
1597
1609
expectedOps := int32 (numGoroutines * numConcurrentOps )
1598
1610
1611
+ // Report operation counts
1612
+ t .Logf ("Concurrent test summary:" )
1613
+ t .Logf ("- Total operations executed: %d (expected: %d)" , totalOps , expectedOps )
1614
+ t .Logf ("- Start operations: %d (with %d errors)" , startCount , len (startErrors ))
1615
+ t .Logf ("- GetToken operations: %d (with %d errors, %d successful)" ,
1616
+ getTokenCount , len (getTokenErrors ), len (tokens ))
1617
+ t .Logf ("- Close operations: %d (with %d errors)" , closeCount , len (closeErrors ))
1618
+
1599
1619
// Some errors are expected due to concurrent operations
1600
1620
// but we should have received tokens successfully
1601
1621
assert .Equal (t , expectedOps , totalOps , "All operations should be accounted for" )
@@ -1604,6 +1624,7 @@ func TestConcurrentTokenManagerOperations(t *testing.T) {
1604
1624
// Verify the token manager still works after all the concurrent operations
1605
1625
finalListener := & concurrentTestTokenListener {
1606
1626
onNextFunc : func (t * token.Token ) {
1627
+ // Just verify we get a token - don't use assert within this callback
1607
1628
if t == nil {
1608
1629
panic ("Final token should not be nil" )
1609
1630
}
0 commit comments