This is an automated email from the ASF dual-hosted git repository.

jihuayu pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new 62b4b8e0b fix(tests): avoid expiry races in hash field migration test 
(#3691)
62b4b8e0b is described below

commit 62b4b8e0bfce61a30602adecc51d1071175abd24
Author: hulk <[email protected]>
AuthorDate: Sat Oct 17 07:06:29 2026 -0700

    fix(tests): avoid expiry races in hash field migration test (#3691)
    
    The hash field expiration migration test can fail when a field expires
    before the destination assertions run, even when migration succeeds.
    
    The snapshot and WAL cases start short expiration deadlines before
    waiting for migration to finish. Slow migration can consume those
    deadlines, so the destination correctly omits an expired field while the
    test still expects it to exist.
    
    Keep fields alive throughout migration and verify that their absolute
    deadlines are preserved. Then shorten the destination deadline before
    checking expiration.
    
    This failure appeared in 42 jobs across 38 workflow runs between
    September 17 and October 17, 2026. Examples:
    
    -
    https://github.com/apache/kvrocks/actions/runs/35440828993/job/105891281731
    -
    https://github.com/apache/kvrocks/actions/runs/36308503141/job/108589896483
    -
    https://github.com/apache/kvrocks/actions/runs/37046888096/job/111162927117
    -
    https://github.com/apache/kvrocks/actions/runs/38199435050/job/114649780929
    -
    https://github.com/apache/kvrocks/actions/runs/38884948326/job/116962652039
    
    Fixes #3686
    
    Assistant-By GPT-6
---
 .../integration/slotmigrate/hash_field_expiration_test.go      | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tests/gocase/integration/slotmigrate/hash_field_expiration_test.go 
b/tests/gocase/integration/slotmigrate/hash_field_expiration_test.go
index a2299b71d..85f9f5b7c 100644
--- a/tests/gocase/integration/slotmigrate/hash_field_expiration_test.go
+++ b/tests/gocase/integration/slotmigrate/hash_field_expiration_test.go
@@ -117,7 +117,7 @@ func TestSlotMigrateHashFieldExpiration(t *testing.T) {
                                require.NoError(t, sourceClient.Do(ctx, 
"hsetex", key+"_new", "PXAT", expireAt,
                                        "FIELDS", 2, "field", 
"created-during-migration", "short-lived", "temporary").Err())
                                // The new key can only arrive through WAL; 
leave time for the rate-limited snapshot transfer.
-                               fieldExpireAt = time.Now().Add(8 * 
time.Second).UnixMilli()
+                               fieldExpireAt = time.Now().Add(8 * 
time.Minute).UnixMilli()
                                require.NoError(t, sourceClient.Do(ctx, 
"hpexpireat", key+"_new", fieldExpireAt, "FIELDS", 1, "short-lived").Err())
                                expiringKey, expiringField, expiringValue = 
key+"_new", "short-lived", "temporary"
                                values["live"] = "15"
@@ -125,7 +125,7 @@ func TestSlotMigrateHashFieldExpiration(t *testing.T) {
                                delete(values, "deleted")
                                expires = []interface{}{expireAt + 60000, 
expireAt, int64(-1), int64(-1), int64(-2), int64(-2)}
                        } else {
-                               fieldExpireAt = time.Now().Add(3 * 
time.Second).UnixMilli()
+                               fieldExpireAt = time.Now().Add(3 * 
time.Minute).UnixMilli()
                                require.NoError(t, sourceClient.Do(ctx, 
"hpexpireat", key, fieldExpireAt, "FIELDS", 1, "live").Err())
                                expires[1] = fieldExpireAt
                        }
@@ -187,6 +187,12 @@ func TestSlotMigrateHashFieldExpiration(t *testing.T) {
                        fieldExpires, err = destinationClient.Do(ctx, 
"hpexpiretime", expiringKey, "FIELDS", 1, expiringField).Result()
                        require.NoError(t, err)
                        require.Equal(t, []interface{}{fieldExpireAt}, 
fieldExpires)
+                       // Shorten the deadline only after verifying that 
migration preserved it.
+                       fieldExpireAt = time.Now().Add(time.Second).UnixMilli()
+                       expireResult, err := destinationClient.Do(ctx, 
"hpexpireat", expiringKey, fieldExpireAt,
+                               "FIELDS", 1, expiringField).Int64Slice()
+                       require.NoError(t, err)
+                       require.Equal(t, []int64{1}, expireResult)
                        require.Eventually(t, func() bool {
                                return errors.Is(destinationClient.HGet(ctx, 
expiringKey, expiringField).Err(), redis.Nil)
                        }, 10*time.Second, 10*time.Millisecond)

Reply via email to