-
Notifications
You must be signed in to change notification settings - Fork 559
Open
Labels
bugtype bugtype bug
Description
Search before asking
- I had searched in the issues and found no similar issues.
Version
2.12.1
Minimal reproduce step
1.Run a kvrocks in cluster mode
2.Add test code with new folder like scan_bug
under test/gocase/unit
and run test
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package scan_bug
import (
"context"
"fmt"
"strings"
"sync"
"testing"
"github.com/apache/kvrocks/tests/gocase/util"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
)
func TestScanBugWithNumberCursor(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
ctx := context.Background()
// rdb := srv.NewClient()
rdb := redis.NewUniversalClient(&redis.UniversalOptions{
Addrs: []string{
yourhostport,
yourhostport
},
})
defer func() { require.NoError(t, rdb.Close()) }()
require.NoError(t, rdb.ConfigSet(ctx, "redis-cursor-compatible", "yes").Err())
ScanTest(t, rdb, ctx)
}
func ScanTest(t *testing.T, rdb redis.UniversalClient, ctx context.Context) {
t.Run("SCAN MATCH BUG", func(t *testing.T) {
require.NoError(t, rdb.FlushAll(ctx).Err())
universalPopulate(t, rdb, "test:B:{1}:info", 3, 10)
universalPopulate(t, rdb, "test:A:{1}:info", 3, 10)
keys, _ := scanAllNodes(ctx, rdb, "test:B:*")
keys2, _ := scanAllNodes(ctx, rdb, "test:*")
require.Len(t, keys2, 6)
require.Len(t, keys, 3)
})
}
func scanAllNodes(ctx context.Context, rdb redis.UniversalClient, pattern string) ([]string, error) {
if clusterClient, ok := rdb.(*redis.ClusterClient); ok {
var keys []string
var mu sync.Mutex
var count int64 = 100
// Scan keys in the cluster using ForEachMaster
err := clusterClient.ForEachMaster(ctx, func(ctx context.Context, client *redis.Client) error {
var cursor uint64
for {
var tempKeys []string
var err error
tempKeys, cursor, err = client.Scan(ctx, cursor, pattern, count).Result()
if err != nil {
return err
}
mu.Lock()
for _, key := range tempKeys {
fmt.Println("Key:", key)
keys = append(keys, key)
}
mu.Unlock()
if cursor == 0 {
break
}
}
return nil
})
if err != nil {
panic(err)
}
return keys, nil
}
singleNodeClient, ok := rdb.(*redis.Client)
if !ok {
return nil, fmt.Errorf("NOT SUPPORT CLIENT TYPE")
}
return scanNodeSingle(ctx, singleNodeClient, pattern)
}
func scanNodeSingle(ctx context.Context, node *redis.Client, pattern string) ([]string, error) {
var keys []string
var cursor uint64
var count int64 = 100
for {
var scanResult []string
var err error
scanResult, cursor, err = node.Scan(ctx, cursor, pattern, count).Result()
if err != nil {
return nil, fmt.Errorf("EXEC SCAN FAIL: %v", err)
}
keys = append(keys, scanResult...)
if cursor == 0 {
break
}
}
return keys, nil
}
func universalPopulate(t testing.TB, rdb redis.UniversalClient, prefix string, n, size int) {
ctx := context.Background()
p := rdb.Pipeline()
for i := 0; i < n; i++ {
p.Do(ctx, "SET", fmt.Sprintf("%s%d", prefix, i), strings.Repeat("A", size))
}
_, err := p.Exec(ctx)
require.NoError(t, err)
}
What did you expect to see?
the test pass
What did you see instead?
the test fail
Anything Else?
may be get a error cursor when the test running but pass in single mode
if (!cursor.empty()) {
iter->Seek(ns_cursor);
if (iter->Valid()) {
iter->Next();
}
} else if (ns_prefix.empty()) {
iter->SeekToFirst();
} else {
iter->Seek(ns_prefix);
}
Are you willing to submit a PR?
- I'm willing to submit a PR!
Metadata
Metadata
Assignees
Labels
bugtype bugtype bug