|
1 | 1 | """Tests for the HTTP server.""" |
2 | 2 |
|
| 3 | +import logging |
3 | 4 | import os |
4 | 5 | import pathlib |
5 | 6 | import queue |
|
20 | 21 | from pypytools.gc.custom import DefaultGc |
21 | 22 |
|
22 | 23 | from .._compat import IS_LINUX, IS_MACOS, IS_WINDOWS, SYS_PLATFORM, bton, ntob |
23 | | -from ..server import IS_UID_GID_RESOLVABLE, Gateway, HTTPServer |
| 24 | +from ..server import ( |
| 25 | + IS_UID_GID_RESOLVABLE, |
| 26 | + Gateway, |
| 27 | + HTTPServer, |
| 28 | + _STOPPING_FOR_INTERRUPT, |
| 29 | +) |
24 | 30 | from ..testing import ( |
25 | 31 | ANY_INTERFACE_IPV4, |
26 | 32 | ANY_INTERFACE_IPV6, |
@@ -127,6 +133,53 @@ def test_stop_interrupts_serve(): |
127 | 133 | assert not serve_thread.is_alive() |
128 | 134 |
|
129 | 135 |
|
| 136 | +def test_serve_unservicable_logs_simple_response_errors(monkeypatch): |
| 137 | + """Check errors while sending 503 responses are logged by the server.""" |
| 138 | + error_log_calls = [] |
| 139 | + |
| 140 | + class BrokenRequest: |
| 141 | + def __init__(self, server, conn): |
| 142 | + self.server = server |
| 143 | + self.conn = conn |
| 144 | + |
| 145 | + def simple_response(self, status): |
| 146 | + assert status == '503 Service Unavailable' |
| 147 | + raise RuntimeError('response failed') |
| 148 | + |
| 149 | + class FakeConnection: |
| 150 | + linger = False |
| 151 | + |
| 152 | + def __init__(self): |
| 153 | + self.closed = False |
| 154 | + |
| 155 | + def close(self): |
| 156 | + self.closed = True |
| 157 | + |
| 158 | + def error_log(msg='', level=20, traceback=False): |
| 159 | + error_log_calls.append((msg, level, traceback)) |
| 160 | + |
| 161 | + httpserver = HTTPServer( |
| 162 | + bind_addr=(ANY_INTERFACE_IPV4, EPHEMERAL_PORT), |
| 163 | + gateway=Gateway, |
| 164 | + ) |
| 165 | + httpserver.ready = True |
| 166 | + httpserver.error_log = error_log |
| 167 | + |
| 168 | + fake_conn = FakeConnection() |
| 169 | + httpserver._unservicable_conns.put(fake_conn) |
| 170 | + httpserver._unservicable_conns.put(_STOPPING_FOR_INTERRUPT) |
| 171 | + |
| 172 | + monkeypatch.setattr('cheroot.server.HTTPRequest', BrokenRequest) |
| 173 | + |
| 174 | + httpserver._serve_unservicable() |
| 175 | + |
| 176 | + assert error_log_calls == [ |
| 177 | + ("RuntimeError('response failed')", logging.ERROR, True), |
| 178 | + ] |
| 179 | + assert fake_conn.linger |
| 180 | + assert fake_conn.closed |
| 181 | + |
| 182 | + |
130 | 183 | @pytest.mark.parametrize( |
131 | 184 | 'exc_cls', |
132 | 185 | ( |
|
0 commit comments