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) }