@@ -423,18 +423,103 @@ class RespServer:
423
423
Accepts RESP commands and returns RESP responses.
424
424
"""
425
425
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
430
447
431
448
def command (self , cmd : Any ) -> bytes :
432
449
"""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 )
435
452
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