Skip to content

Commit 6ec40eb

Browse files
committed
expand the RespServer
1 parent a195041 commit 6ec40eb

File tree

1 file changed

+96
-11
lines changed

1 file changed

+96
-11
lines changed

tests/resp.py

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -423,18 +423,103 @@ class RespServer:
423423
Accepts RESP commands and returns RESP responses.
424424
"""
425425

426-
_CLIENT_NAME = "test-suite-client"
427-
_SUCCESS_RESP = b"+OK" + CRNL
428-
_ERROR_RESP = b"-ERR" + CRNL
429-
_SUPPORTED_CMDS = {f"CLIENT SETNAME {_CLIENT_NAME}": _SUCCESS_RESP}
426+
handlers = {}
427+
428+
def __init__(self):
429+
self.protocol = 2
430+
self.server_ver = self.get_server_version()
431+
self.auth = []
432+
self.client_name = ""
433+
434+
# patchable methods for testing
435+
436+
def get_server_version(self):
437+
return 6
438+
439+
def on_auth(self, auth):
440+
pass
441+
442+
def on_setname(self, name):
443+
pass
444+
445+
def on_protocol(self, proto):
446+
pass
430447

431448
def command(self, cmd: Any) -> bytes:
432449
"""Process a single command and return the response"""
433-
if not isinstance(cmd, list):
434-
return f"-ERR unknown command {cmd!r}\r\n".encode()
450+
result = self._command(cmd)
451+
return RespEncoder(self.protocol).encode(result)
435452

436-
# currently supports only a single command
437-
command = " ".join(cmd)
438-
if command in self._SUPPORTED_CMDS:
439-
return self._SUPPORTED_CMDS[command]
440-
return self._ERROR_RESP
453+
def _command(self, cmd: Any) -> Any:
454+
if not isinstance(cmd, list):
455+
return ErrorStr("ERR", "unknown command {cmd!r}")
456+
457+
# handle registered commands
458+
command = cmd[0].upper()
459+
args = cmd[1:]
460+
if command in self.handlers:
461+
return self.handlers[command](self, args)
462+
463+
return ErrorStr("ERR", "unknown command {cmd!r}")
464+
465+
def handle_auth(self, args):
466+
self.auth = args[:]
467+
self.on_auth(self.auth)
468+
expect = 2 if self.server_ver >= 6 else 1
469+
if len(args) != expect:
470+
return ErrorStr("ERR", "wrong number of arguments"
471+
" for 'AUTH' command")
472+
return "OK"
473+
handlers["AUTH"] = handle_auth
474+
475+
def handle_client(self, args):
476+
if args[0] == "SETNAME":
477+
return self.handle_setname(args[1:])
478+
return ErrorStr("ERR", "unknown subcommand or wrong number of arguments")
479+
handlers["CLIENT"] = handle_client
480+
481+
def handle_setname(self, args):
482+
if len(args) != 1:
483+
return ErrorStr("ERR", "wrong number of arguments")
484+
self.client_name = args[0]
485+
self.on_setname(self.client_name)
486+
return "OK"
487+
488+
def handle_hello(self, args):
489+
if self.server_ver < 6:
490+
return ErrorStr("ERR", "unknown command 'HELLO'")
491+
proto = self.protocol
492+
if args:
493+
proto = args.pop(0)
494+
if str(proto) not in ["2", "3"]:
495+
return ErrorStr("NOPROTO",
496+
"sorry this protocol version is not supported")
497+
498+
while args:
499+
cmd = args.pop(0).upper()
500+
if cmd == "AUTH":
501+
auth_args = args[:2]
502+
args = args[2:]
503+
res = self.handle_auth(auth_args)
504+
if res != "OK":
505+
return res
506+
continue
507+
if cmd == "SETNAME":
508+
setname_args = args[:1]
509+
args = args[1:]
510+
res = self.handle_setname(setname_args)
511+
if res != "OK":
512+
return res
513+
continue
514+
return ErrorStr("ERR", "unknown subcommand or wrong number of arguments")
515+
516+
self.protocol = int(proto)
517+
self.on_protocol(self.protocol)
518+
result = {
519+
"server": "redistester",
520+
"version": "0.0.1",
521+
"proto": self.protocol,
522+
}
523+
return result
524+
525+
handlers["HELLO"] = handle_hello

0 commit comments

Comments
 (0)