GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — vscode-python/python_files/tests/test_python_server.py at main · microsoft/vscode-python Expand file tree/ Copy pathtest_python_server.pyMore file actions 162 lines (123 loc) · 5.78 KB / Copy pathtest_python_server.pyFile metadata and controls162 lines (123 loc) · 5.78 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. """Tests for python_server.py, specifically EOF handling to prevent infinite loops.""" import io from unittest import mock import pytest class TestGetHeaders: """Tests for the get_headers function.""" def test_get_headers_normal(self): """Test get_headers with valid headers.""" # Arrange: Import the module import python_server # Create a mock stdin with valid headers mock_input = b"Content-Length: 100\r\nContent-Type: application/json\r\n\r\n" mock_stdin = io.BytesIO(mock_input) # Act with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)): headers = python_server.get_headers() # Assert assert headers == {"Content-Length": "100", "Content-Type": "application/json"} def test_get_headers_eof_raises_error(self): """Test that get_headers raises EOFError when stdin is closed (EOF).""" # Arrange: Import the module import python_server # Create a mock stdin that returns empty bytes (EOF) mock_stdin = io.BytesIO(b"") # Act & Assert with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)), pytest.raises( EOFError, match="EOF reached while reading headers" ): python_server.get_headers() def test_get_headers_eof_mid_headers_raises_error(self): """Test that get_headers raises EOFError when EOF occurs mid-headers.""" # Arrange: Import the module import python_server # Create a mock stdin with partial headers then EOF mock_input = b"Content-Length: 100\r\n" # No terminating empty line mock_stdin = io.BytesIO(mock_input) # Act & Assert with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)), pytest.raises( EOFError, match="EOF reached while reading headers" ): python_server.get_headers() def test_get_headers_empty_line_terminates(self): """Test that an empty line (not EOF) properly terminates header reading.""" # Arrange: Import the module import python_server # Create a mock stdin with headers followed by empty line mock_input = b"Content-Length: 50\r\n\r\nsome body content" mock_stdin = io.BytesIO(mock_input) # Act with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)): headers = python_server.get_headers() # Assert assert headers == {"Content-Length": "50"} class TestEOFHandling: """Tests for EOF handling in various functions that use get_headers.""" def test_custom_input_exits_on_eof(self): """Test that custom_input exits gracefully on EOF.""" # Arrange: Import the module import python_server # Create a mock stdin that returns empty bytes (EOF) mock_stdin = io.BytesIO(b"") mock_stdout = io.BytesIO() # Act & Assert with mock.patch.object( python_server, "STDIN", mock.Mock(buffer=mock_stdin) ), mock.patch.object(python_server, "STDOUT", mock.Mock(buffer=mock_stdout)), pytest.raises( SystemExit ) as exc_info: python_server.custom_input("prompt> ") # Should exit with code 0 (graceful exit) assert exc_info.value.code == 0 def test_handle_response_exits_on_eof(self): """Test that handle_response exits gracefully on EOF.""" # Arrange: Import the module import python_server # Create a mock stdin that returns empty bytes (EOF) mock_stdin = io.BytesIO(b"") # Act & Assert with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)), pytest.raises( SystemExit ) as exc_info: python_server.handle_response("test-request-id") # Should exit with code 0 (graceful exit) assert exc_info.value.code == 0 class TestMainLoopEOFHandling: """Tests that simulate the main loop EOF scenario.""" def test_main_loop_exits_on_eof(self): """Test that the main loop pattern exits gracefully on EOF. This test verifies the fix for GitHub issue #25620 where the server would spin at 100% CPU instead of exiting when VS Code closes. """ # Arrange: Import the module import python_server # Create a mock stdin that returns empty bytes (EOF) mock_stdin = io.BytesIO(b"") # Simulate what happens in the main loop with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)): try: python_server.get_headers() # If we get here without raising EOFError, the fix isn't working pytest.fail("Expected EOFError to be raised on EOF") except EOFError: # This is the expected behavior - the fix is working pass def test_readline_eof_vs_empty_line(self): """Test that we correctly distinguish between EOF and empty line. EOF: readline() returns b'' (empty bytes) Empty line: readline() returns b'\\r\\n' or b'\\n' (newline bytes) """ # Test EOF case eof_stream = io.BytesIO(b"") result = eof_stream.readline() assert result == b"", "EOF should return empty bytes" # Test empty line case empty_line_stream = io.BytesIO(b"\r\n") result = empty_line_stream.readline() assert result == b"\r\n", "Empty line should return newline bytes" # Test empty line with just newline empty_line_stream2 = io.BytesIO(b"\n") result = empty_line_stream2.readline() assert result == b"\n", "Empty line should return newline bytes" |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |