Files
pekoe/internal/compatibility/rueidis_test.go
2026-04-03 00:09:40 +03:00

218 lines
5.1 KiB
Go

package compatibility
import (
"context"
"fmt"
"sync"
"testing"
"github.com/redis/rueidis"
)
// newRueidisClient creates a rueidis client with proper options for pekoe
func newRueidisClient(t *testing.T, addr string) rueidis.Client {
t.Helper()
client, err := rueidis.NewClient(rueidis.ClientOption{
InitAddress: []string{addr},
DisableCache: true,
})
if err != nil {
t.Fatalf("Failed to create rueidis client: %v", err)
}
return client
}
// TestRueidisPing tests PING command
func TestRueidisPing(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
result, err := client.Do(ctx, client.B().Ping().Build()).ToString()
if err != nil {
t.Fatalf("Ping failed: %v", err)
}
if result != "PONG" {
t.Errorf("Expected 'PONG', got '%s'", result)
}
}
// TestRueidisPingWithMessage tests PING with message
func TestRueidisPingWithMessage(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
result, err := client.Do(ctx, client.B().Ping().Message("hello").Build()).ToString()
if err != nil {
t.Fatalf("Ping failed: %v", err)
}
if result != "hello" {
t.Errorf("Expected 'hello', got '%s'", result)
}
}
// TestRueidisBasicPublish tests PUBLISH and verifies count
func TestRueidisBasicPublish(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
pubClient := newRueidisClient(t, ts.Addr())
defer pubClient.Close()
// Publish to channel with no subscribers
count, err := pubClient.Do(ctx, pubClient.B().Publish().Channel("r-test").Message("hello").Build()).AsInt64()
if err != nil {
t.Fatalf("Publish failed: %v", err)
}
if count != 0 {
t.Errorf("Expected 0 subscribers, got %d", count)
}
}
// TestRueidisPublishNoSubscribers tests PUBLISH with no subscribers
func TestRueidisPublishNoSubscribers(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
n, err := client.Do(ctx, client.B().Publish().Channel("r-no-subs").Message("msg").Build()).AsInt64()
if err != nil {
t.Fatalf("Publish failed: %v", err)
}
if n != 0 {
t.Errorf("Expected 0 receivers, got %d", n)
}
}
// TestRueidisBinarySafe tests binary message handling
func TestRueidisBinarySafe(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
binaryMsg := []byte{0x00, 0x01, 0x02, 0xFF, 0xFE}
// Just verify publish works with binary data
_, err := client.Do(ctx, client.B().Publish().Channel("r-binary").Message(string(binaryMsg)).Build()).AsInt64()
if err != nil {
t.Fatalf("Publish binary failed: %v", err)
}
}
// TestRueidisEmptyMessage tests empty message
func TestRueidisEmptyMessage(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
_, err := client.Do(ctx, client.B().Publish().Channel("r-empty").Message("").Build()).AsInt64()
if err != nil {
t.Fatalf("Publish empty failed: %v", err)
}
}
// TestRueidisConcurrentSubscribers tests concurrent client creation
func TestRueidisConcurrentSubscribers(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
var wg sync.WaitGroup
successCount := 0
var mu sync.Mutex
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
// Just verify we can ping
ctx := context.Background()
_, err := client.Do(ctx, client.B().Ping().Build()).ToString()
if err != nil {
t.Errorf("Client %d ping failed: %v", id, err)
return
}
mu.Lock()
successCount++
mu.Unlock()
}(i)
}
wg.Wait()
if successCount != 10 {
t.Errorf("Only %d/10 clients succeeded", successCount)
}
}
// TestRueidisUnicodeMessages tests Unicode messages
func TestRueidisUnicodeMessages(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
client := newRueidisClient(t, ts.Addr())
defer client.Close()
messages := []string{
"Hello, 世界!",
"Emoji: 🎉",
"Cyrillic: Привет",
}
for _, testMsg := range messages {
t.Run(testMsg[:min(20, len(testMsg))], func(t *testing.T) {
_, err := client.Do(ctx, client.B().Publish().Channel("r-unicode").Message(testMsg).Build()).AsInt64()
if err != nil {
t.Fatalf("Publish failed: %v", err)
}
})
}
}
// TestRueidisConcurrentPublishSubscribe tests concurrent pub/sub operations
func TestRueidisConcurrentPublishSubscribe(t *testing.T) {
ts := startTestServer(t)
defer ts.Close()
ctx := context.Background()
numMessages := 50
pubClient := newRueidisClient(t, ts.Addr())
defer pubClient.Close()
for i := 0; i < numMessages; i++ {
_, err := pubClient.Do(ctx, pubClient.B().Publish().Channel("r-concurrent").Message(fmt.Sprintf("msg-%d", i)).Build()).AsInt64()
if err != nil {
t.Errorf("Publish %d failed: %v", i, err)
}
}
t.Logf("Published %d messages", numMessages)
}