package service import ( "context" "testing" "time" "github.com/Tencent/WeKnora/internal/common/redislock" "github.com/alicebob/miniredis/v2" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/require" ) func TestWikiSlugLockRefusesUnlockedWritesWhenRedisFails(t *testing.T) { mini := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: mini.Addr(), MaxRetries: -1, DialTimeout: 50 * time.Millisecond}) t.Cleanup(func() { _ = client.Close() }) mini.Close() called := false acquired, err := (&wikiIngestService{redisClient: client}).withSlugLock(context.Background(), "kb", "concept/a", func(context.Context) error { called = true return nil }) require.Error(t, err) require.False(t, acquired) require.False(t, called) } func TestWikiSlugLockPassesOwnershipContextToReducer(t *testing.T) { mini := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: mini.Addr()}) t.Cleanup(func() { _ = client.Close() }) acquired, err := (&wikiIngestService{redisClient: client}).withSlugLock(context.Background(), "kb", "concept/a", func(ctx context.Context) error { key := wikiSlugLockPrefix + "kb:concept/a" require.NotEqual(t, "1", client.Get(ctx, key).Val()) require.NoError(t, client.Set(ctx, key, "successor", time.Minute).Err()) return verifyWikiSlugOwnership(ctx) }) require.True(t, acquired) require.ErrorIs(t, err, redislock.ErrLockOwnershipLost) require.Equal(t, "successor", client.Get(context.Background(), wikiSlugLockPrefix+"kb:concept/a").Val()) }