8000 Remove fifo regression (#24685) · microsoft/vscode-python@3ccf984 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3ccf984

Browse files
authored
Remove fifo regression (#24685)
fixes regression in #24656 by reverting problem
1 parent de988ff commit 3ccf984

File tree

19 files changed

+376
-364
lines changed

19 files changed

+376
-364
lines changed

noxfile.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ def install_python_libs(session: nox.Session):
5353
)
5454

5555
session.install("packaging")
56-
session.install("debugpy")
5756

5857
# Download get-pip script
5958
session.run(

python_files/testing_tools/socket_manager.py

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,39 @@ def __exit__(self, *_):
2020
self.close()
2121

2222
def connect(self):
23-
self._writer = open(self.name, "w", encoding="utf-8") # noqa: SIM115, PTH123
24-
# reader created in read method
23+
if sys.platform == "win32":
24+
self._writer = open(self.name, "w", encoding="utf-8") # noqa: SIM115, PTH123
25+
# reader created in read method
26+
else:
27+
self._socket = _SOCKET(socket.AF_UNIX, socket.SOCK_STREAM)
28+
self._socket.connect(self.name)
2529
return self
2630

2731
def close(self):
28-
self._writer.close()
29-
if hasattr(self, "_reader"):
30-
self._reader.close()
32+
if sys.platform == "win32":
33+
self._writer.close()
34+
else:
35+
# add exception catch
36+
self._socket.close()
3137

3238
def write(self, data: str):
33-
try:
34-
# for windows, is should only use \n\n
35-
request = f"""content-length: {len(data)}\ncontent-type: application/json\n\n{data}"""
36-
self._writer.write(request)
37-
self._writer.flush()
38-
except Exception as e:
39-
print("error attempting to write to pipe", e)
40-
raise (e)
39+
if sys.platform == "win32":
40+
try:
41+
# for windows, is should only use \n\n
42+
request = (
43+
f"""content-length: {len(data)}\ncontent-type: application/json\n\n{data}"""
44+
)
45+
self._writer.write(request)
46+
self._writer.flush()
47+
except Exception as e:
48+
print("error attempting to write to pipe", e)
49+
raise (e)
50+
else:
51+
# must include the carriage-return defined (as \r\n) for unix systems
52+
request = (
53+
f"""content-length: {len(data)}\r\ncontent-type: application/json\r\n\r\n{data}"""
54+
)
55+
self._socket.send(request.encode("utf-8"))
4156

4257
def read(self, bufsize=1024) -> str:
4358
"""Read data from the socket.
@@ -48,10 +63,17 @@ def read(self, bufsize=1024) -> str:
4863
Returns:
4964
data (str): Data received from the socket.
5065
"""
51-
# returns a string automatically from read
52-
if not hasattr(self, "_reader"):
53-
self._reader = open(self.name, encoding="utf-8") # noqa: SIM115, PTH123
54-
return self._reader.read(bufsize)
66+
if sys.platform == "win32":
67+
# returns a string automatically from read
68+
if not hasattr(self, "_reader"):
69+
self._reader = open(self.name, encoding="utf-8") # noqa: SIM115, PTH123
70+
return self._reader.read(bufsize)
71+
else:
72+
# receive bytes and convert to string
73+
while True:
74+
part: bytes = self._socket.recv(bufsize)
75+
data: str = part.decode("utf-8")
76+
return data
5577

5678

5779
class SocketManager:

python_files/tests/pytestadapter/helpers.py

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,6 @@ def parse_rpc_message(data: str) -> Tuple[Dict[str, str], str]:
128128
print("json decode error")
129129

130130

131-
def _listen_on_fifo(pipe_name: str, result: List[str], completed: threading.Event):
132-
# Open the FIFO for reading
133-
fifo_path = pathlib.Path(pipe_name)
134-
with fifo_path.open() as fifo:
135-
print("Waiting for data...")
136-
while True:
137-
if completed.is_set():
138-
break # Exit loop if completed event is set
139-
data = fifo.read() # This will block until data is available
140-
if len(data) == 0:
141-
# If data is empty, assume EOF
142-
break
143-
print(f"Received: {data}")
144-
result.append(data)
145-
146-
147131
def _listen_on_pipe_new(listener, result: List[str], completed: threading.Event):
148132
"""Listen on the named pipe or Unix domain socket for JSON data from the server.
149133
@@ -323,19 +307,14 @@ def runner_with_cwd_env(
323307
# if additional environment variables are passed, add them to the environment
324308
if env_add:
325309
env.update(env_add)
326-
# server = UnixPipeServer(pipe_name)
327-
# server.start()
328-
#################
329-
# Create the FIFO (named pipe) if it doesn't exist
330-
# if not pathlib.Path.exists(pipe_name):
331-
os.mkfifo(pipe_name)
332-
#################
310+
server = UnixPipeServer(pipe_name)
311+
server.start()
333312

334313
completed = threading.Event()
335314

336315
result = [] # result is a string array to store the data during threading
337316
t1: threading.Thread = threading.Thread(
338-
target=_listen_on_fifo, args=(pipe_name, result, completed)
317+
target=_listen_on_pipe_new, args=(server, result, completed)
339318
)
340319
t1.start()
341320

@@ -385,14 +364,14 @@ def generate_random_pipe_name(prefix=""):
385364

386365
# For Windows, named pipes have a specific naming convention.
387366
if sys.platform == "win32":
388-
return f"\\\\.\\pipe\\{prefix}-{random_suffix}"
367+
return f"\\\\.\\pipe\\{prefix}-{random_suffix}-sock"
389368

390369
# For Unix-like systems, use either the XDG_RUNTIME_DIR or a temporary directory.
391370
xdg_runtime_dir = os.getenv("XDG_RUNTIME_DIR")
392371
if xdg_runtime_dir:
393-
return os.path.join(xdg_runtime_dir, f"{prefix}-{random_suffix}") # noqa: PTH118
372+
return os.path.join(xdg_runtime_dir, f"{prefix}-{random_suffix}.sock") # noqa: PTH118
394373
else:
395-
return os.path.join(tempfile.gettempdir(), f"{prefix}-{random_suffix}") # noqa: PTH118
374+
return os.path.join(tempfile.gettempdir(), f"{prefix}-{random_suffix}.sock") # noqa: PTH118
396375

397376

398377
class UnixPipeServer:

python_files/unittestadapter/pvsc_utils.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
from typing_extensions import NotRequired # noqa: E402
2020

21+
from testing_tools import socket_manager # noqa: E402
22+
2123
# Types
2224

2325

@@ -329,10 +331,10 @@ def send_post_request(
329331

330332
if __writer is None:
331333
try:
332-
__writer = open(test_run_pipe, "w", encoding="utf-8", newline="\r\n") # noqa: SIM115, PTH123
334+
__writer = socket_manager.PipeManager(test_run_pipe)
335+
__writer.connect()
333336
except Exception as error:
334337
error_msg = f"Error attempting to connect to extension named pipe {test_run_pipe}[vscode-unittest]: {error}"
335-
print(error_msg, file=sys.stderr)
336338
__writer = None
337339
raise VSCodeUnittestError(error_msg) from error
338340

@@ -341,11 +343,10 @@ def send_post_request(
341343
"params": payload,
342344
}
343345
data = json.dumps(rpc)
346+
344347
try:
345348
if __writer:
346-
request = f"""content-length: {len(data)}\ncontent-type: application/json\n\n{data}"""
347-
__writer.write(request)
348-
__writer.flush()
349+
__writer.write(data)
349350
else:
350351
print(
351352
f"Connection error[vscode-unittest], writer is None \n[vscode-unittest] data: \n{data} \n",

python_files/vscode_pytest/__init__.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121

2222
import pytest
2323

24+
script_dir = pathlib.Path(__file__).parent.parent
25+
sys.path.append(os.fspath(script_dir))
26+
sys.path.append(os.fspath(script_dir / "lib" / "python"))
27+
from testing_tools import socket_manager # noqa: E402
28+
2429
if TYPE_CHECKING:
2530
from pluggy import Result
2631

@@ -166,7 +171,7 @@ def pytest_exception_interact(node, call, report):
166171
collected_test = TestRunResultDict()
167172
collected_test[node_id] = item_result
168173
cwd = pathlib.Path.cwd()
169-
send_execution_message(
174+
execution_post(
170175
os.fsdecode(cwd),
171176
"success",
172177
collected_test if collected_test else None,
@@ -290,7 +295,7 @@ def pytest_report_teststatus(report, config): # noqa: ARG001
290295
)
291296
collected_test = TestRunResultDict()
292297
collected_test[absolute_node_id] = item_result
293-
send_execution_message(
298+
execution_post(
294299
os.fsdecode(cwd),
295300
"success",
296301
collected_test if collected_test else None,
@@ -324,7 +329,7 @@ def pytest_runtest_protocol(item, nextitem): # noqa: ARG001
324329
)
325330
collected_test = TestRunResultDict()
326331
collected_test[absolute_node_id] = item_result
327-
send_execution_message(
332+
execution_post(
328333
os.fsdecode(cwd),
329334
"success",
330335
collected_test if collected_test else None,
@@ -400,15 +405,15 @@ def pytest_sessionfinish(session, exitstatus):
400405
"children": [],
401406
"id_": "",
402407
}
403-
send_discovery_message(os.fsdecode(cwd), error_node)
408+
post_response(os.fsdecode(cwd), error_node)
404409
try:
405410
session_node: TestNode | None = build_test_tree(session)
406411
if not session_node:
407412
raise VSCodePytestError(
408413
"Something went wrong following pytest finish, \
409414
no session node was created"
410415
)
411-
send_discovery_message(os.fsdecode(cwd), session_node)
416+
post_response(os.fsdecode(cwd), session_node)
412417
except Exception as e:
413418
ERRORS.append(
414419
f"Error Occurred, traceback: {(traceback.format_exc() if e.__traceback__ else '')}"
@@ -420,7 +425,7 @@ def pytest_sessionfinish(session, exitstatus):
420425
"children": [],
421426
"id_": "",
422427
}
423-
send_discovery_message(os.fsdecode(cwd), error_node)
428+
post_response(os.fsdecode(cwd), error_node)
424429
else:
425430
if exitstatus == 0 or exitstatus == 1:
426431
exitstatus_bool = "success"
@@ -430,7 +435,7 @@ def pytest_sessionfinish(session, exitstatus):
430435
)
431436
exitstatus_bool = "error"
432437

433-
send_execution_message(
438+
execution_post(
434439
os.fsdecode(cwd),
435440
exitstatus_bool,
436441
None,
@@ -484,7 +489,7 @@ def pytest_sessionfinish(session, exitstatus):
484489
result=file_coverage_map,
485490
error=None,
486491
)
487-
send_message(payload)
492+
send_post_request(payload)
488493

489494

490495
def build_test_tree(session: pytest.Session) -> TestNode:
@@ -852,10 +857,8 @@ def get_node_path(node: Any) -> pathlib.Path:
852857
atexit.register(lambda: __writer.close() if __writer else None)
853858

854859

855-
def send_execution_message(
856-
cwd: str, status: Literal["success", "error"], tests: TestRunResultDict | None
857-
):
858-
"""Sends message execution payload details.
860+
def execution_post(cwd: str, status: Literal["success", "error"], tests: TestRunResultDict | None):
861+
"""Sends a POST request with execution payload details.
859862
860863
Args:
861864
cwd (str): Current working directory.
@@ -867,10 +870,10 @@ def send_execution_message(
867870
)
868871
if ERRORS:
869872
payload["error"] = ERRORS
870-
send_message(payload)
873+
send_post_request(payload)
871874

872875

873-
def send_discovery_message(cwd: str, session_node: TestNode) -> None:
876+
def post_response(cwd: str, session_node: TestNode) -> None:
874877
"""
875878
Sends a POST request with test session details in payload.
876879
@@ -886,7 +889,7 @@ def send_discovery_message(cwd: str, session_node: TestNode) -> None:
886889
}
887890
if ERRORS is not None:
888891
payload["error"] = ERRORS
889-
send_message(payload, cls_encoder=PathEncoder)
892+
send_post_request(payload, cls_encoder=PathEncoder)
890893

891894

892895
class PathEncoder(json.JSONEncoder):
@@ -898,7 +901,7 @@ def default(self, o):
898901
return super().default(o)
899902

900903

901-
def send_message(
904+
def send_post_request(
902905
payload: ExecutionPayloadDict | DiscoveryPayloadDict | CoveragePayloadDict,
903906
cls_encoder=None,
904907
):
@@ -923,7 +926,8 @@ def send_message(
923926

924927
if __writer is None:
925928
try:
926-
__writer = open(TEST_RUN_PIPE, "w", encoding="utf-8", newline="\r\n") # noqa: SIM115, PTH123
929+
__writer = socket_manager.PipeManager(TEST_RUN_PIPE)
930+
__writer.connect()
927931
except Exception as error:
928932
error_msg = f"Error attempting to connect to extension named pipe {TEST_RUN_PIPE}[vscode-pytest]: {error}"
929933
print(error_msg, file=sys.stderr)
@@ -941,11 +945,10 @@ def send_message(
941945
"params": payload,
942946
}
943947
data = json.dumps(rpc, cls=cls_encoder)
948+
944949
try:
945950
if __writer:
946-
request = f"""content-length: {len(data)}\ncontent-type: application/json\n\n{data}"""
947-
__writer.write(request)
948-
__writer.flush()
951+
__writer.write(data)
949952
else:
950953
print(
951954
f"Plugin error connection error[vscode-pytest], writer is None \n[vscode-pytest] data: \n{data} \n",

python_files/vscode_pytest/_common.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0