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)