mirror of
https://github.com/hanzokv/go.git
synced 2026-09-24 00:31:51 +00:00
We do not use Redis. The client was a go-redis fork and still said so
everywhere: `package redis`, `redis.NewClient`, `redis://`, `extra/redisotel`.
Consumers wrote `redis.Client` against a Valkey-backed store called KV.
package redis -> package kv (93 decls)
redis.X -> kv.X (2,794 call sites)
"redis: …" errors -> "kv: …" (206)
extra/redis{otel,cmd,prometheus,census} -> extra/kv{otel,cmd,prometheus,census}
redis:// , rediss:// -> kv:// , kvs:// (ParseURL)
Redis*/*Redis* idents -> KV*/*KV*
REDIS_VERSION, REDIS_ENDPOINTS_CONFIG_PATH -> KV_*
I previously argued this rename was unsafe because much of it was "wire
contract". That was wrong, and the categorisation shows why: RESP command names
are GET/SET/HSET — they never contain the word. Of 5,771 occurrences only two
kinds were server-visible at all: the ParseURL scheme (we choose what we pass;
our configs already use kv://) and the CLIENT SETINFO lib-name label, which the
server merely records. Nothing here changes a byte of protocol.
Two things deliberately keep the old spelling:
RediSearch — names a specific external module the FT.* commands map to.
StoreDist — contains the letters by accident (sto-reDis-t), not the word.
Breaking for consumers by design: every import site must move redis.X -> kv.X.
Minor bump, never a major — this module stays v9 forever.
110 lines
2.9 KiB
Go
110 lines
2.9 KiB
Go
package kv_test
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
. "github.com/bsm/ginkgo/v2"
|
|
. "github.com/bsm/gomega"
|
|
|
|
"github.com/hanzokv/go/v9"
|
|
)
|
|
|
|
// This test is for manual use and is not part of the CI of Go-KV.
|
|
var _ = Describe("Monitor command", Label("monitor"), func() {
|
|
ctx := context.TODO()
|
|
var client *kv.Client
|
|
|
|
BeforeEach(func() {
|
|
if os.Getenv("RUN_MONITOR_TEST") != "true" {
|
|
Skip("Skipping Monitor command test. Set RUN_MONITOR_TEST=true to run it.")
|
|
}
|
|
client = kv.NewClient(&kv.Options{Addr: kvPort})
|
|
Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
|
|
|
|
})
|
|
|
|
AfterEach(func() {
|
|
Expect(client.Close()).NotTo(HaveOccurred())
|
|
})
|
|
|
|
It("should monitor", Label("monitor"), func() {
|
|
ress := make(chan string)
|
|
client1 := kv.NewClient(&kv.Options{Addr: kvPort})
|
|
mn := client1.Monitor(ctx, ress)
|
|
mn.Start()
|
|
// Wait for the KV server to be in monitoring mode.
|
|
time.Sleep(100 * time.Millisecond)
|
|
client.Set(ctx, "foo", "bar", 0)
|
|
client.Set(ctx, "bar", "baz", 0)
|
|
client.Set(ctx, "bap", 8, 0)
|
|
client.Get(ctx, "bap")
|
|
lst := []string{}
|
|
for i := 0; i < 5; i++ {
|
|
s := <-ress
|
|
lst = append(lst, s)
|
|
}
|
|
mn.Stop()
|
|
Expect(lst[0]).To(ContainSubstring("OK"))
|
|
Expect(lst[1]).To(ContainSubstring(`"set" "foo" "bar"`))
|
|
Expect(lst[2]).To(ContainSubstring(`"set" "bar" "baz"`))
|
|
Expect(lst[3]).To(ContainSubstring(`"set" "bap" "8"`))
|
|
})
|
|
})
|
|
|
|
func TestMonitorCommand(t *testing.T) {
|
|
if os.Getenv("RUN_MONITOR_TEST") != "true" {
|
|
t.Skip("Skipping Monitor command test. Set RUN_MONITOR_TEST=true to run it.")
|
|
}
|
|
|
|
ctx := context.TODO()
|
|
client := kv.NewClient(&kv.Options{Addr: kvPort})
|
|
if err := client.FlushDB(ctx).Err(); err != nil {
|
|
t.Fatalf("FlushDB failed: %v", err)
|
|
}
|
|
|
|
defer func() {
|
|
if err := client.Close(); err != nil {
|
|
t.Fatalf("Close failed: %v", err)
|
|
}
|
|
}()
|
|
|
|
ress := make(chan string, 10) // Buffer to prevent blocking
|
|
client1 := kv.NewClient(&kv.Options{Addr: kvPort}) // Adjust the Addr field as necessary
|
|
mn := client1.Monitor(ctx, ress)
|
|
mn.Start()
|
|
// Wait for the KV server to be in monitoring mode.
|
|
time.Sleep(100 * time.Millisecond)
|
|
client.Set(ctx, "foo", "bar", 0)
|
|
client.Set(ctx, "bar", "baz", 0)
|
|
client.Set(ctx, "bap", 8, 0)
|
|
client.Get(ctx, "bap")
|
|
mn.Stop()
|
|
var lst []string
|
|
for i := 0; i < 5; i++ {
|
|
s := <-ress
|
|
lst = append(lst, s)
|
|
}
|
|
|
|
// Assertions
|
|
if !containsSubstring(lst[0], "OK") {
|
|
t.Errorf("Expected lst[0] to contain 'OK', got %s", lst[0])
|
|
}
|
|
if !containsSubstring(lst[1], `"set" "foo" "bar"`) {
|
|
t.Errorf(`Expected lst[1] to contain '"set" "foo" "bar"', got %s`, lst[1])
|
|
}
|
|
if !containsSubstring(lst[2], `"set" "bar" "baz"`) {
|
|
t.Errorf(`Expected lst[2] to contain '"set" "bar" "baz"', got %s`, lst[2])
|
|
}
|
|
if !containsSubstring(lst[3], `"set" "bap" "8"`) {
|
|
t.Errorf(`Expected lst[3] to contain '"set" "bap" "8"', got %s`, lst[3])
|
|
}
|
|
}
|
|
|
|
func containsSubstring(s, substr string) bool {
|
|
return strings.Contains(s, substr)
|
|
}
|