From 796cd5b8e4e41f4dfb409098eb60537175b9d980 Mon Sep 17 00:00:00 2001 From: Antonin Roullet Date: Mon, 29 Sep 2025 10:57:12 +0200 Subject: [PATCH 1/2] feat: implement WAIT command as no-op --- README.md | 2 +- cmd_generic.go | 20 ++++++++++++++++++++ cmd_generic_test.go | 24 ++++++++++++++++++++++++ cmd_scripting_test.go | 5 +++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 710d1642..8216d0cd 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Implemented commands: - TTL - TYPE - UNLINK + - WAIT -- no-op - Transactions (complete) - DISCARD - EXEC @@ -305,7 +306,6 @@ Commands which will probably not be implemented: - Key - ~~MIGRATE~~ - ~~OBJECT~~ - - ~~WAIT~~ - Scripting - ~~FCALL / FCALL_RO *~~ - ~~FUNCTION *~~ diff --git a/cmd_generic.go b/cmd_generic.go index 2f55d5f0..e27d009c 100644 --- a/cmd_generic.go +++ b/cmd_generic.go @@ -56,6 +56,7 @@ func commandsGeneric(m *Miniredis) { m.srv.Register("SCAN", m.cmdScan, server.ReadOnlyOption()) // SORT m.srv.Register("UNLINK", m.cmdDel) + m.srv.Register("WAIT", m.cmdWait) } type expireOpts struct { @@ -773,3 +774,22 @@ func (m *Miniredis) cmdCopy(c *server.Peer, cmd string, args []string) { c.WriteInt(1) }) } + +// WAIT +func (m *Miniredis) cmdWait(c *server.Peer, cmd string, args []string) { + if !m.isValidCMD(c, cmd, args, exactly(2)) { + return + } + nReplicas, err := strconv.Atoi(args[0]) + if err != nil || nReplicas < 0 { + c.WriteError(msgInvalidInt) + return + } + timeout, err := strconv.Atoi(args[1]) + if err != nil || timeout < 0 { + c.WriteError(msgInvalidInt) + return + } + // WAIT always returns 0 when called on a standalone instance + c.WriteInt(0) +} diff --git a/cmd_generic_test.go b/cmd_generic_test.go index 3994bac0..ef3f0257 100644 --- a/cmd_generic_test.go +++ b/cmd_generic_test.go @@ -990,3 +990,27 @@ func TestCopy(t *testing.T) { ) }) } + +func TestWait(t *testing.T) { + _, c := runWithClient(t) + + t.Run("success", func(t *testing.T) { + must0(t, c, "WAIT", "2", "100") + must0(t, c, "WAIT", "1", "0") + }) + + t.Run("errors", func(t *testing.T) { + mustDo(t, c, "WAIT", + proto.Error(errWrongNumber("wait")), + ) + mustDo(t, c, "WAIT", "2", + proto.Error(errWrongNumber("wait")), + ) + mustDo(t, c, "WAIT", "2", "bar", + proto.Error(msgInvalidInt), + ) + mustDo(t, c, "WAIT", "foo", "100", + proto.Error(msgInvalidInt), + ) + }) +} diff --git a/cmd_scripting_test.go b/cmd_scripting_test.go index b8fcd69f..144f0f48 100644 --- a/cmd_scripting_test.go +++ b/cmd_scripting_test.go @@ -469,6 +469,11 @@ func TestCmdEvalResponse(t *testing.T) { "EVAL", "return redis.call('HMGET','mkey', 'bad', 'key')", "0", proto.Array(proto.Nil, proto.Nil), ) + + mustDo(t, c, + "EVAL", "return redis.call('WAIT', '2', '100')", "0", + proto.Int(0), + ) } func TestCmdEvalAuth(t *testing.T) { From d672a87d730d5b4b1f72a7ec60522a6339fa1a63 Mon Sep 17 00:00:00 2001 From: Harmen Date: Wed, 15 Oct 2025 09:39:35 +0200 Subject: [PATCH 2/2] add small int test --- cmd_generic.go | 6 +++++- integration/server_test.go | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cmd_generic.go b/cmd_generic.go index e27d009c..6d4bb557 100644 --- a/cmd_generic.go +++ b/cmd_generic.go @@ -786,10 +786,14 @@ func (m *Miniredis) cmdWait(c *server.Peer, cmd string, args []string) { return } timeout, err := strconv.Atoi(args[1]) - if err != nil || timeout < 0 { + if err != nil { c.WriteError(msgInvalidInt) return } + if timeout < 0 { + c.WriteError(msgTimeoutNegative) + return + } // WAIT always returns 0 when called on a standalone instance c.WriteInt(0) } diff --git a/integration/server_test.go b/integration/server_test.go index 491079bd..d3612f50 100644 --- a/integration/server_test.go +++ b/integration/server_test.go @@ -55,6 +55,19 @@ func TestServer(t *testing.T) { c.Error("wrong number of arguments", "MEMORY", "USAGE") c.Error("syntax error", "MEMORY", "USAGE", "too", "many") }) + + testRaw(t, func(c *client) { + c.DoLoosely("WAIT", "1", "1") + + // Failure cases + c.Error("wrong number", "WAIT", "1") + c.Error("wrong number", "WAIT", "1", "2", "3") + c.Error("wrong number", "WAIT") + c.Error("not an integer", "WAIT", "foo", "0") + c.Error("not an integer", "WAIT", "1", "foo") + // c.Error("out of range", "WAIT", "-1", "0") // something weird going on + c.Error("timeout is negative", "WAIT", "11", "-12") + }) } func TestServerTLS(t *testing.T) {