mirror of
https://github.com/redis/go-redis.git
synced 2026-10-24 07:59:20 +03:00
perf(options): perf Fuzz Test Go File (#3692)
Changes: - Eliminated repeated string conversions - Convert byte slice to string once - Functional approach - Used function slice for cleaner operation selection - Better iteration logic - More efficient bounds checking and indexing - Configurable constants - All magic numbers moved to constants - Improved iteration calculation - Uses percentage-based approach for better fuzzing Change-Id: Ie6929037106bd7e648aeb20f422593eb700ecb60
This commit is contained in:
72
fuzz/fuzz.go
72
fuzz/fuzz.go
@@ -10,40 +10,70 @@ import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
const (
|
||||
minDataLength = 4
|
||||
redisAddr = ":6379"
|
||||
dialTimeout = 10 * time.Second
|
||||
readTimeout = 10 * time.Second
|
||||
writeTimeout = 10 * time.Second
|
||||
poolSize = 10
|
||||
poolTimeout = 10 * time.Second
|
||||
scanCount = 10
|
||||
maxIterPercentage = 256 // Use first byte as percentage of data length
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
rdb *redis.Client
|
||||
)
|
||||
|
||||
type redisOperation func(key, value string)
|
||||
|
||||
func init() {
|
||||
rdb = redis.NewClient(&redis.Options{
|
||||
Addr: ":6379",
|
||||
DialTimeout: 10 * time.Second,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
PoolSize: 10,
|
||||
PoolTimeout: 10 * time.Second,
|
||||
Addr: redisAddr,
|
||||
DialTimeout: dialTimeout,
|
||||
ReadTimeout: readTimeout,
|
||||
WriteTimeout: writeTimeout,
|
||||
PoolSize: poolSize,
|
||||
PoolTimeout: poolTimeout,
|
||||
})
|
||||
}
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
arrayLen := len(data)
|
||||
if arrayLen < 4 {
|
||||
if len(data) < minDataLength {
|
||||
return -1
|
||||
}
|
||||
maxIter := int(uint(data[0]))
|
||||
for i := 0; i < maxIter && i < arrayLen; i++ {
|
||||
n := i % arrayLen
|
||||
if n == 0 {
|
||||
_ = rdb.Set(ctx, string(data[i:]), string(data[i:]), 0).Err()
|
||||
} else if n == 1 {
|
||||
_, _ = rdb.Get(ctx, string(data[i:])).Result()
|
||||
} else if n == 2 {
|
||||
_, _ = rdb.Incr(ctx, string(data[i:])).Result()
|
||||
} else if n == 3 {
|
||||
var cursor uint64
|
||||
_, _, _ = rdb.Scan(ctx, cursor, string(data[i:]), 10).Result()
|
||||
}
|
||||
|
||||
maxIter := (int(data[0]) * len(data)) / maxIterPercentage
|
||||
if maxIter == 0 {
|
||||
maxIter = 1 // Ensure at least one iteration
|
||||
}
|
||||
|
||||
operations := []redisOperation{
|
||||
func(key, value string) { rdb.Set(ctx, key, value, 0).Err() },
|
||||
func(key, value string) { rdb.Get(ctx, key).Result() },
|
||||
func(key, value string) { rdb.Incr(ctx, key).Result() },
|
||||
func(key, value string) {
|
||||
var cursor uint64
|
||||
rdb.Scan(ctx, cursor, key, scanCount).Result()
|
||||
},
|
||||
}
|
||||
|
||||
dataStr := string(data)
|
||||
|
||||
for i := 0; i < maxIter && i < len(data); i++ {
|
||||
start := i % len(data)
|
||||
end := (i + 1) % len(data)
|
||||
if end <= start {
|
||||
end = len(data)
|
||||
}
|
||||
|
||||
key := dataStr[start:end]
|
||||
opIndex := i % len(operations)
|
||||
|
||||
operations[opIndex](key, dataStr)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user