chore: fix TestCheckInactiveUsers flake (#19469)

THIS CODE WAS NOT WRITTEN BY A HUMAN.
Use a fixed time interval to avoid timing flakes.
This commit is contained in:
Cian Johnston
2025-08-21 16:35:31 +01:00
committed by GitHub
parent fe289e8824
commit 86f9bed608
2 changed files with 20 additions and 11 deletions
@@ -37,12 +37,13 @@ func CheckInactiveUsersWithOptions(ctx context.Context, logger slog.Logger, clk
ctx, cancelFunc := context.WithCancel(ctx)
tf := clk.TickerFunc(ctx, checkInterval, func() error {
startTime := time.Now()
lastSeenAfter := dbtime.Now().Add(-dormancyPeriod)
now := dbtime.Time(clk.Now()).UTC()
lastSeenAfter := now.Add(-dormancyPeriod)
logger.Debug(ctx, "check inactive user accounts", slog.F("dormancy_period", dormancyPeriod), slog.F("last_seen_after", lastSeenAfter))
updatedUsers, err := db.UpdateInactiveUsersToDormant(ctx, database.UpdateInactiveUsersToDormantParams{
LastSeenAfter: lastSeenAfter,
UpdatedAt: dbtime.Now(),
UpdatedAt: now,
})
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
logger.Error(ctx, "can't mark inactive users as dormant", slog.Error(err))
@@ -31,20 +31,28 @@ func TestCheckInactiveUsers(t *testing.T) {
ctx, cancelFunc := context.WithCancel(context.Background())
t.Cleanup(cancelFunc)
inactiveUser1 := setupUser(ctx, t, db, "dormant-user-1@coder.com", database.UserStatusActive, time.Now().Add(-dormancyPeriod).Add(-time.Minute))
inactiveUser2 := setupUser(ctx, t, db, "dormant-user-2@coder.com", database.UserStatusActive, time.Now().Add(-dormancyPeriod).Add(-time.Hour))
inactiveUser3 := setupUser(ctx, t, db, "dormant-user-3@coder.com", database.UserStatusActive, time.Now().Add(-dormancyPeriod).Add(-6*time.Hour))
// Use a fixed base time to avoid timing races
baseTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
dormancyThreshold := baseTime.Add(-dormancyPeriod)
activeUser1 := setupUser(ctx, t, db, "active-user-1@coder.com", database.UserStatusActive, time.Now().Add(-dormancyPeriod).Add(time.Minute))
activeUser2 := setupUser(ctx, t, db, "active-user-2@coder.com", database.UserStatusActive, time.Now().Add(-dormancyPeriod).Add(time.Hour))
activeUser3 := setupUser(ctx, t, db, "active-user-3@coder.com", database.UserStatusActive, time.Now().Add(-dormancyPeriod).Add(6*time.Hour))
// Create inactive users (last seen BEFORE dormancy threshold)
inactiveUser1 := setupUser(ctx, t, db, "dormant-user-1@coder.com", database.UserStatusActive, dormancyThreshold.Add(-time.Minute))
inactiveUser2 := setupUser(ctx, t, db, "dormant-user-2@coder.com", database.UserStatusActive, dormancyThreshold.Add(-time.Hour))
inactiveUser3 := setupUser(ctx, t, db, "dormant-user-3@coder.com", database.UserStatusActive, dormancyThreshold.Add(-6*time.Hour))
suspendedUser1 := setupUser(ctx, t, db, "suspended-user-1@coder.com", database.UserStatusSuspended, time.Now().Add(-dormancyPeriod).Add(-time.Minute))
suspendedUser2 := setupUser(ctx, t, db, "suspended-user-2@coder.com", database.UserStatusSuspended, time.Now().Add(-dormancyPeriod).Add(-time.Hour))
suspendedUser3 := setupUser(ctx, t, db, "suspended-user-3@coder.com", database.UserStatusSuspended, time.Now().Add(-dormancyPeriod).Add(-6*time.Hour))
// Create active users (last seen AFTER dormancy threshold)
activeUser1 := setupUser(ctx, t, db, "active-user-1@coder.com", database.UserStatusActive, baseTime.Add(-time.Minute))
activeUser2 := setupUser(ctx, t, db, "active-user-2@coder.com", database.UserStatusActive, baseTime.Add(-time.Hour))
activeUser3 := setupUser(ctx, t, db, "active-user-3@coder.com", database.UserStatusActive, baseTime.Add(-6*time.Hour))
suspendedUser1 := setupUser(ctx, t, db, "suspended-user-1@coder.com", database.UserStatusSuspended, dormancyThreshold.Add(-time.Minute))
suspendedUser2 := setupUser(ctx, t, db, "suspended-user-2@coder.com", database.UserStatusSuspended, dormancyThreshold.Add(-time.Hour))
suspendedUser3 := setupUser(ctx, t, db, "suspended-user-3@coder.com", database.UserStatusSuspended, dormancyThreshold.Add(-6*time.Hour))
mAudit := audit.NewMock()
mClock := quartz.NewMock(t)
// Set the mock clock to the base time to ensure consistent behavior
mClock.Set(baseTime)
// Run the periodic job
closeFunc := dormancy.CheckInactiveUsersWithOptions(ctx, logger, mClock, db, mAudit, interval, dormancyPeriod)
t.Cleanup(closeFunc)