@@ -501,5 +501,173 @@ def bar():
501501 self .assertIn ("Function returned: 42" , stdout )
502502 self .assertEqual (process .returncode , 0 )
503503
504+ def test_handle_eof (self ):
505+ """Test that EOF signal properly exits the debugger."""
506+ self ._create_script ()
507+ process , client_file = self ._connect_and_get_client_file ()
508+
509+ with process :
510+ # Skip initial messages until we get to the prompt
511+ self ._read_until_prompt (client_file )
512+
513+ # Send EOF signal to exit the debugger
514+ client_file .write (json .dumps ({"signal" : "EOF" }).encode () + b"\n " )
515+ client_file .flush ()
516+
517+ # The process should complete normally after receiving EOF
518+ stdout , stderr = process .communicate (timeout = 5 )
519+
520+ # Verify process completed correctly
521+ self .assertIn ("Function returned: 42" , stdout )
522+ self .assertEqual (process .returncode , 0 )
523+ self .assertEqual (stderr , "" )
524+
525+ def test_protocol_version (self ):
526+ """Test that incompatible protocol versions are properly detected."""
527+ # Create a script using an incompatible protocol version
528+ script = f"""
529+ import sys
530+ import pdb
531+
532+ def run_test():
533+ frame = sys._getframe()
534+
535+ # Use a fake version number that's definitely incompatible
536+ fake_version = 0x01010101 # A fake version that doesn't match any real Python version
537+
538+ # Connect with the wrong version
539+ pdb._connect(
540+ host='127.0.0.1',
541+ port={ self .port } ,
542+ frame=frame,
543+ commands="",
544+ version=fake_version,
545+ )
546+
547+ # This should print if the debugger detaches correctly
548+ print("Debugger properly detected version mismatch")
549+ return True
550+
551+ if __name__ == "__main__":
552+ print("Test result:", run_test())
553+ """
554+ self ._create_script (script = script )
555+ process , client_file = self ._connect_and_get_client_file ()
556+
557+ with process :
558+ # First message should be an error about protocol version mismatch
559+ data = client_file .readline ()
560+ message = json .loads (data .decode ())
561+
562+ self .assertIn ('message' , message )
563+ self .assertEqual (message ['type' ], 'error' )
564+ self .assertIn ('incompatible' , message ['message' ])
565+ self .assertIn ('protocol version' , message ['message' ])
566+
567+ # The process should complete normally
568+ stdout , stderr = process .communicate (timeout = 5 )
569+
570+ # Verify the process completed successfully
571+ self .assertIn ("Test result: True" , stdout )
572+ self .assertIn ("Debugger properly detected version mismatch" , stdout )
573+ self .assertEqual (process .returncode , 0 )
574+
575+ def test_help_system (self ):
576+ """Test that the help system properly sends help text to the client."""
577+ self ._create_script ()
578+ process , client_file = self ._connect_and_get_client_file ()
579+
580+ with process :
581+ # Skip initial messages until we get to the prompt
582+ self ._read_until_prompt (client_file )
583+
584+ # Request help for different commands
585+ help_commands = ["help" , "help break" , "help continue" , "help pdb" ]
586+
587+ for cmd in help_commands :
588+ self ._send_command (client_file , cmd )
589+
590+ # Look for help message
591+ data = client_file .readline ()
592+ message = json .loads (data .decode ())
593+
594+ self .assertIn ('help' , message )
595+
596+ if cmd == "help" :
597+ # Should just contain the command itself
598+ self .assertEqual (message ['help' ], "" )
599+ else :
600+ # Should contain the specific command we asked for help with
601+ command = cmd .split ()[1 ]
602+ self .assertEqual (message ['help' ], command )
603+
604+ # Skip to the next prompt
605+ self ._read_until_prompt (client_file )
606+
607+ # Continue execution to finish the program
608+ self ._send_command (client_file , "c" )
609+
610+ stdout , stderr = process .communicate (timeout = 5 )
611+ self .assertIn ("Function returned: 42" , stdout )
612+ self .assertEqual (process .returncode , 0 )
613+
614+ def test_multi_line_commands (self ):
615+ """Test that multi-line commands work properly over remote connection."""
616+ self ._create_script ()
617+ process , client_file = self ._connect_and_get_client_file ()
618+
619+ with process :
620+ # Skip initial messages until we get to the prompt
621+ self ._read_until_prompt (client_file )
622+
623+ # Send a multi-line command
624+ multi_line_commands = [
625+ # Define a function
626+ "def test_func():\n return 42" ,
627+
628+ # For loop
629+ "for i in range(3):\n print(i)" ,
630+
631+ # If statement
632+ "if True:\n x = 42\n else:\n x = 0" ,
633+
634+ # Try/except
635+ "try:\n result = 10/2\n print(result)\n except ZeroDivisionError:\n print('Error')" ,
636+
637+ # Class definition
638+ "class TestClass:\n def __init__(self):\n self.value = 100\n def get_value(self):\n return self.value"
639+ ]
640+
641+ for cmd in multi_line_commands :
642+ self ._send_command (client_file , cmd )
643+ self ._read_until_prompt (client_file )
644+
645+ # Test executing the defined function
646+ self ._send_command (client_file , "test_func()" )
647+ messages = self ._read_until_prompt (client_file )
648+
649+ # Find the result message
650+ result_msg = next (msg ['message' ] for msg in messages if 'message' in msg )
651+ self .assertIn ("42" , result_msg )
652+
653+ # Test creating an instance of the defined class
654+ self ._send_command (client_file , "obj = TestClass()" )
655+ self ._read_until_prompt (client_file )
656+
657+ # Test calling a method on the instance
658+ self ._send_command (client_file , "obj.get_value()" )
659+ messages = self ._read_until_prompt (client_file )
660+
661+ # Find the result message
662+ result_msg = next (msg ['message' ] for msg in messages if 'message' in msg )
663+ self .assertIn ("100" , result_msg )
664+
665+ # Continue execution to finish
666+ self ._send_command (client_file , "c" )
667+
668+ stdout , stderr = process .communicate (timeout = 5 )
669+ self .assertIn ("Function returned: 42" , stdout )
670+ self .assertEqual (process .returncode , 0 )
671+
504672if __name__ == "__main__" :
505673 unittest .main ()
0 commit comments