@@ -395,18 +395,103 @@ class RespServer:
395
395
Accepts RESP commands and returns RESP responses.
396
396
"""
397
397
398
- _CLIENT_NAME = "test-suite-client"
399
- _SUCCESS_RESP = b"+OK" + CRNL
400
- _ERROR_RESP = b"-ERR" + CRNL
401
- _SUPPORTED_CMDS = {f"CLIENT SETNAME { _CLIENT_NAME } " : _SUCCESS_RESP }
398
+ handlers = {}
399
+
400
+ def __init__ (self ):
401
+ self .protocol = 2
402
+ self .server_ver = self .get_server_version ()
403
+ self .auth = []
404
+ self .client_name = ""
405
+
406
+ # patchable methods for testing
407
+
408
+ def get_server_version (self ):
409
+ return 6
410
+
411
+ def on_auth (self , auth ):
412
+ pass
413
+
414
+ def on_setname (self , name ):
415
+ pass
416
+
417
+ def on_protocol (self , proto ):
418
+ pass
402
419
403
420
def command (self , cmd : Any ) -> bytes :
404
421
"""Process a single command and return the response"""
405
- if not isinstance (cmd , list ):
406
- return f"-ERR unknown command { cmd !r } \r \n " . encode ()
422
+ result = self . _command (cmd )
423
+ return RespEncoder ( self . protocol ). encode (result )
407
424
408
- # currently supports only a single command
409
- command = " " .join (cmd )
410
- if command in self ._SUPPORTED_CMDS :
411
- return self ._SUPPORTED_CMDS [command ]
412
- return self ._ERROR_RESP
425
+ def _command (self , cmd : Any ) -> Any :
426
+ if not isinstance (cmd , list ):
427
+ return ErrorStr ("ERR" , "unknown command {cmd!r}" )
428
+
429
+ # handle registered commands
430
+ command = cmd [0 ].upper ()
431
+ args = cmd [1 :]
432
+ if command in self .handlers :
433
+ return self .handlers [command ](self , args )
434
+
435
+ return ErrorStr ("ERR" , "unknown command {cmd!r}" )
436
+
437
+ def handle_auth (self , args ):
438
+ self .auth = args [:]
439
+ self .on_auth (self .auth )
440
+ expect = 2 if self .server_ver >= 6 else 1
441
+ if len (args ) != expect :
442
+ return ErrorStr ("ERR" , "wrong number of arguments"
443
+ " for 'AUTH' command" )
444
+ return "OK"
445
+ handlers ["AUTH" ] = handle_auth
446
+
447
+ def handle_client (self , args ):
448
+ if args [0 ] == "SETNAME" :
449
+ return self .handle_setname (args [1 :])
450
+ return ErrorStr ("ERR" , "unknown subcommand or wrong number of arguments" )
451
+ handlers ["CLIENT" ] = handle_client
452
+
453
+ def handle_setname (self , args ):
454
+ if len (args ) != 1 :
455
+ return ErrorStr ("ERR" , "wrong number of arguments" )
456
+ self .client_name = args [0 ]
457
+ self .on_setname (self .client_name )
458
+ return "OK"
459
+
460
+ def handle_hello (self , args ):
461
+ if self .server_ver < 6 :
462
+ return ErrorStr ("ERR" , "unknown command 'HELLO'" )
463
+ proto = self .protocol
464
+ if args :
465
+ proto = args .pop (0 )
466
+ if str (proto ) not in ["2" , "3" ]:
467
+ return ErrorStr ("NOPROTO" ,
468
+ "sorry this protocol version is not supported" )
469
+
470
+ while args :
471
+ cmd = args .pop (0 ).upper ()
472
+ if cmd == "AUTH" :
473
+ auth_args = args [:2 ]
474
+ args = args [2 :]
475
+ res = self .handle_auth (auth_args )
476
+ if res != "OK" :
477
+ return res
478
+ continue
479
+ if cmd == "SETNAME" :
480
+ setname_args = args [:1 ]
481
+ args = args [1 :]
482
+ res = self .handle_setname (setname_args )
483
+ if res != "OK" :
484
+ return res
485
+ continue
486
+ return ErrorStr ("ERR" , "unknown subcommand or wrong number of arguments" )
487
+
488
+ self .protocol = int (proto )
489
+ self .on_protocol (self .protocol )
490
+ result = {
491
+ "server" : "redistester" ,
492
+ "version" : "0.0.1" ,
493
+ "proto" : self .protocol ,
494
+ }
495
+ return result
496
+
497
+ handlers ["HELLO" ] = handle_hello
0 commit comments