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

Skip to content

Commit ca25769

Browse files
committed
Remove fifo regression (microsoft#24685) (microsoft#24687)
fixes regression in microsoft#24656 by reverting problem
1 parent ceab82c commit ca25769

File tree

19 files changed

+434
-528
lines changed

19 files changed

+434
-528
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,
@@ -480,7 +485,7 @@ def pytest_sessionfinish(session, exitstatus):
480485
result=file_coverage_map,
481486
error=None,
482487
)
483-
send_message(payload)
488+
send_post_request(payload)
484489

485490

486491
def build_test_tree(session: pytest.Session) -> TestNode:
@@ -848,10 +853,8 @@ def get_node_path(node: Any) -> pathlib.Path:
848853
atexit.register(lambda: __writer.close() if __writer else None)
849854

850855

851-
def send_execution_message(
852-
cwd: str, status: Literal["success", "error"], tests: TestRunResultDict | None
853-
):
854-
"""Sends message execution payload details.
856+
def execution_post(cwd: str, status: Literal["success", "error"], tests: TestRunResultDict | None):
857+
"""Sends a POST request with execution payload details.
855858
856859
Args:
857860
cwd (str): Current working directory.
@@ -863,10 +866,10 @@ def send_execution_message(
863866
)
864867
if ERRORS:
865868
payload["error"] = ERRORS
866-
send_message(payload)
869+
send_post_request(payload)
867870

868871

869-
def send_discovery_message(cwd: str, session_node: TestNode) -> None:
872+
def post_response(cwd: str, session_node: TestNode) -> None:
870873
"""
871874
Sends a POST request with test session details in payload.
872875
@@ -882,7 +885,7 @@ def send_discovery_message(cwd: str, session_node: TestNode) -> None:
882885
}
883886
if ERRORS is not None:
884887
payload["error"] = ERRORS
885-
send_message(payload, cls_encoder=PathEncoder)
888+
send_post_request(payload, cls_encoder=PathEncoder)
886889

887890

888891
class PathEncoder(json.JSONEncoder):
@@ -894,7 +897,7 @@ def default(self, o):
894897
return super().default(o)
895898

896899

897-
def send_message(
900+
def send_post_request(
898901
payload: ExecutionPayloadDict | DiscoveryPayloadDict | CoveragePayloadDict,
899902
cls_encoder=None,
900903
):
@@ -919,7 +922,8 @@ def send_message(
919922

920923
if __writer is None:
921924
try:
922-
__writer = open(TEST_RUN_PIPE, "w", encoding="utf-8", newline="\r\n") # noqa: SIM115, PTH123
925+
__writer = socket_manager.PipeManager(TEST_RUN_PIPE)
926+
__writer.connect()
923927
except Exception as error:
924928
error_msg = f"Error attempting to connect to extension named pipe {TEST_RUN_PIPE}[vscode-pytest]: {error}"
925929
print(error_msg, file=sys.stderr)
@@ -937,11 +941,10 @@ def send_message(
937941
"params": payload,
938942
}
939943
data = json.dumps(rpc, cls=cls_encoder)
944+
940945
try:
941946
if __writer:
942-
request = f"""content-length: {len(data)}\ncontent-type: application/json\n\n{data}"""
943-
__writer.write(request)
944-
__writer.flush()
947+
__writer.write(data)
945948
else:
946949
print(
947950
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