|
| 1 | +from contextlib import ExitStack |
1 | 2 | from contextlib import contextmanager |
2 | 3 | from http.server import BaseHTTPRequestHandler |
3 | 4 | from http.server import ThreadingHTTPServer |
4 | 5 | import json |
5 | 6 | from queue import Queue |
| 7 | +import socket |
6 | 8 | from threading import Thread |
7 | 9 | from unittest.mock import MagicMock |
8 | 10 | from unittest.mock import patch |
|
25 | 27 | # so we use a large enough integer as an approximation instead. |
26 | 28 | LONG_INTERVAL = 2147483647.0 |
27 | 29 |
|
| 30 | +# httpretty -- reached through tests.internal.remoteconfig.rcm_endpoint, which |
| 31 | +# test_debugger.py uses earlier in this suite -- intermittently leaves the socket |
| 32 | +# module holding its fakes after being disabled. A server built on a fake socket binds |
| 33 | +# a port that never accepts, so the native sender only reports a timeout. These are |
| 34 | +# captured at import time, before any test can patch them, and reinstalled for the |
| 35 | +# lifetime of the intake server below. |
| 36 | +_REAL_SOCKET_ATTRS = { |
| 37 | + name: getattr(socket, name) for name in ("socket", "create_connection", "getaddrinfo", "socketpair") |
| 38 | +} |
| 39 | + |
28 | 40 |
|
29 | 41 | class MockSignalUploader(SignalUploader): |
30 | 42 | def __init__(self, *args, **kwargs): |
@@ -212,11 +224,18 @@ def close(self) -> None: |
212 | 224 |
|
213 | 225 | @contextmanager |
214 | 226 | def _intake_server(): |
215 | | - server = _IntakeServer() |
216 | | - try: |
217 | | - yield server |
218 | | - finally: |
219 | | - server.close() |
| 227 | + # socket.socket is consulted again on every accept(), so the real |
| 228 | + # implementations have to stay installed for as long as the server serves, not |
| 229 | + # just while it is constructed. |
| 230 | + with ExitStack() as stack: |
| 231 | + for name, real in _REAL_SOCKET_ATTRS.items(): |
| 232 | + stack.enter_context(patch.object(socket, name, real)) |
| 233 | + |
| 234 | + server = _IntakeServer() |
| 235 | + try: |
| 236 | + yield server |
| 237 | + finally: |
| 238 | + server.close() |
220 | 239 |
|
221 | 240 |
|
222 | 241 | def _uploader_to(url): |
|
0 commit comments