From 25d2816ab4c18cc0606cc2723468f923e8e80c17 Mon Sep 17 00:00:00 2001 From: Harmen Date: Wed, 21 Jan 2026 20:55:58 +0100 Subject: [PATCH 1/4] CLUSTER SHARDS --- cmd_cluster.go | 31 +++++++++++++++++++++++++++++++ cmd_cluster_test.go | 29 +++++++++++++++++++++++++++++ integration/cluster_test.go | 1 + 3 files changed, 61 insertions(+) diff --git a/cmd_cluster.go b/cmd_cluster.go index efb53496..82826ef4 100644 --- a/cmd_cluster.go +++ b/cmd_cluster.go @@ -31,6 +31,8 @@ func (m *Miniredis) cmdCluster(c *server.Peer, cmd string, args []string) { m.cmdClusterKeySlot(c, cmd, args) case "NODES": m.cmdClusterNodes(c, cmd, args) + case "SHARDS": + m.cmdClusterShards(c, cmd, args) default: setDirty(c) c.WriteError(fmt.Sprintf("ERR 'CLUSTER %s' not supported", strings.Join(args, " "))) @@ -68,3 +70,32 @@ func (m *Miniredis) cmdClusterNodes(c *server.Peer, cmd string, args []string) { c.WriteBulk(fmt.Sprintf("e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca %s@%d myself,master - 0 0 1 connected 0-16383", addr, port)) }) } + +// CLUSTER SHARDS +func (m *Miniredis) cmdClusterShards(c *server.Peer, cmd string, args []string) { + withTx(m, c, func(c *server.Peer, ctx *connCtx) { + // addr := m.srv.Addr() + port := m.srv.Addr().Port + c.WriteLen(1) + c.WriteMapLen(2) + c.WriteBulk("slots") + c.WriteLen(0) + c.WriteBulk("nodes") + c.WriteLen(1) + c.WriteMapLen(7) + c.WriteBulk("id") + c.WriteBulk("13f84e686106847b76671957dd348fde540a77bb") + c.WriteBulk("port") + c.WriteInt(port) + c.WriteBulk("ip") + c.WriteBulk("") + c.WriteBulk("endpoint") + c.WriteBulk("") + c.WriteBulk("role") + c.WriteBulk("master") + c.WriteBulk("replication-offset") + c.WriteInt(0) + c.WriteBulk("health") + c.WriteBulk("online") + }) +} diff --git a/cmd_cluster_test.go b/cmd_cluster_test.go index 9a0a5c6a..d48c8d24 100644 --- a/cmd_cluster_test.go +++ b/cmd_cluster_test.go @@ -38,6 +38,35 @@ func TestCluster(t *testing.T) { ) }) + t.Run("shards", func(t *testing.T) { + mustDo(t, c, + "CLUSTER", "SHARDS", + proto.Array( + proto.Array( + proto.String("slots"), proto.Array(), + proto.String("nodes"), proto.Array( + proto.Array( + proto.String("id"), + proto.String("13f84e686106847b76671957dd348fde540a77bb"), + proto.String("port"), + proto.Int(s.srv.Addr().Port), + proto.String("ip"), + proto.String(""), + proto.String("endpoint"), + proto.String(""), + proto.String("role"), + proto.String("master"), + proto.String("replication-offset"), + proto.Int(0), + proto.String("health"), + proto.String("online"), + ), + ), + ), + ), + ) + }) + t.Run("keyslot", func(t *testing.T) { mustDo(t, c, "CLUSTER", "keyslot", "{test_key}", diff --git a/integration/cluster_test.go b/integration/cluster_test.go index 80beb033..b5b837aa 100644 --- a/integration/cluster_test.go +++ b/integration/cluster_test.go @@ -10,6 +10,7 @@ func TestCluster(t *testing.T) { c.DoLoosely("CLUSTER", "KEYSLOT", "{test}") c.DoLoosely("CLUSTER", "NODES") c.Error("wrong number", "CLUSTER") + c.DoLoosely("CLUSTER", "SHARDS") }, ) } From 9da9cc55b1024bdc438d8cf6d96e06c5547d1bcc Mon Sep 17 00:00:00 2001 From: Dimitrij Drus Date: Wed, 21 Jan 2026 22:00:25 +0100 Subject: [PATCH 2/4] update to the cmdClusterShards command which works --- cmd_cluster.go | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/cmd_cluster.go b/cmd_cluster.go index 82826ef4..4f7c77f4 100644 --- a/cmd_cluster.go +++ b/cmd_cluster.go @@ -74,27 +74,48 @@ func (m *Miniredis) cmdClusterNodes(c *server.Peer, cmd string, args []string) { // CLUSTER SHARDS func (m *Miniredis) cmdClusterShards(c *server.Peer, cmd string, args []string) { withTx(m, c, func(c *server.Peer, ctx *connCtx) { - // addr := m.srv.Addr() - port := m.srv.Addr().Port + addr := m.srv.Addr() + host := addr.IP.String() + port := addr.Port + + // Array of shards (we return 1 shard) c.WriteLen(1) + + // Shard is a map with 2 keys: "slots" and "nodes" c.WriteMapLen(2) + + // "slots": flat list of start/end pairs (inclusive ranges) c.WriteBulk("slots") - c.WriteLen(0) + c.WriteLen(2) + c.WriteInt(0) + c.WriteInt(16383) + + // "nodes": array of node maps c.WriteBulk("nodes") c.WriteLen(1) - c.WriteMapLen(7) + + // Node map. + // (id, endpoint, ip, port, role, replication-offset, health) + c.WriteMapLen(6) + c.WriteBulk("id") c.WriteBulk("13f84e686106847b76671957dd348fde540a77bb") + + //c.WriteBulk("endpoint") + //c.WriteBulk(host) // or host:port if your client expects that + + c.WriteBulk("ip") + c.WriteBulk(host) + c.WriteBulk("port") c.WriteInt(port) - c.WriteBulk("ip") - c.WriteBulk("") - c.WriteBulk("endpoint") - c.WriteBulk("") + c.WriteBulk("role") c.WriteBulk("master") + c.WriteBulk("replication-offset") c.WriteInt(0) + c.WriteBulk("health") c.WriteBulk("online") }) From 5d0c7f253d6594ae66a038247d8c00971f803476 Mon Sep 17 00:00:00 2001 From: Dimitrij Drus Date: Wed, 21 Jan 2026 22:10:23 +0100 Subject: [PATCH 3/4] tests updated --- cmd_cluster_test.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/cmd_cluster_test.go b/cmd_cluster_test.go index d48c8d24..00e3ce40 100644 --- a/cmd_cluster_test.go +++ b/cmd_cluster_test.go @@ -43,21 +43,27 @@ func TestCluster(t *testing.T) { "CLUSTER", "SHARDS", proto.Array( proto.Array( - proto.String("slots"), proto.Array(), + proto.String("slots"), proto.Array( + proto.Int(0), + proto.Int(16383), + ), proto.String("nodes"), proto.Array( proto.Array( proto.String("id"), proto.String("13f84e686106847b76671957dd348fde540a77bb"), + + proto.String("ip"), + proto.String(s.srv.Addr().IP.String()), + proto.String("port"), proto.Int(s.srv.Addr().Port), - proto.String("ip"), - proto.String(""), - proto.String("endpoint"), - proto.String(""), + proto.String("role"), proto.String("master"), + proto.String("replication-offset"), proto.Int(0), + proto.String("health"), proto.String("online"), ), From cf8dc3b8a69c7d581645f97e002b128243225c61 Mon Sep 17 00:00:00 2001 From: Harmen Date: Thu, 22 Jan 2026 08:55:38 +0100 Subject: [PATCH 4/4] disable test --- integration/cluster_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/cluster_test.go b/integration/cluster_test.go index b5b837aa..b3a3409a 100644 --- a/integration/cluster_test.go +++ b/integration/cluster_test.go @@ -10,7 +10,7 @@ func TestCluster(t *testing.T) { c.DoLoosely("CLUSTER", "KEYSLOT", "{test}") c.DoLoosely("CLUSTER", "NODES") c.Error("wrong number", "CLUSTER") - c.DoLoosely("CLUSTER", "SHARDS") + // c.DoLoosely("CLUSTER", "SHARDS") }, ) }