@@ -501,5 +501,173 @@ def bar():
501
501
self .assertIn ("Function returned: 42" , stdout )
502
502
self .assertEqual (process .returncode , 0 )
503
503
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
+
504
672
if __name__ == "__main__" :
505
673
unittest .main ()
0 commit comments