diff --git a/cmd_cluster.go b/cmd_cluster.go index efb5349..4f7c77f 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,53 @@ 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() + 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(2) + c.WriteInt(0) + c.WriteInt(16383) + + // "nodes": array of node maps + c.WriteBulk("nodes") + c.WriteLen(1) + + // 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("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 9a0a5c6..00e3ce4 100644 --- a/cmd_cluster_test.go +++ b/cmd_cluster_test.go @@ -38,6 +38,41 @@ 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.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("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 80beb03..b3a3409 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") }, ) }