Skip to content

Commit be9662f

Browse files
authored
revert testing to using socket (#21242)
switch back to using a socket instead of an output file for use in the plugin communication during testing. This should work now that we resolved the issue with python path for windows.
1 parent b4a47bb commit be9662f

File tree

2 files changed

+59
-64
lines changed

2 files changed

+59
-64
lines changed

pythonFiles/tests/pytestadapter/helpers.py

+45-38
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,14 @@
1010
import socket
1111
import subprocess
1212
import sys
13+
import threading
1314
import uuid
1415
from typing import Any, Dict, List, Optional, Union
1516

1617
TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
1718
from typing_extensions import TypedDict
1819

1920

20-
@contextlib.contextmanager
21-
def test_output_file(root: pathlib.Path, ext: str = ".txt"):
22-
"""Creates a temporary python file with a random name."""
23-
basename = (
24-
"".join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(9)) + ext
25-
)
26-
fullpath = root / basename
27-
try:
28-
fullpath.write_text("", encoding="utf-8")
29-
yield fullpath
30-
finally:
31-
os.unlink(str(fullpath))
32-
33-
3421
def create_server(
3522
host: str = "127.0.0.1",
3623
port: int = 0,
@@ -116,31 +103,51 @@ def runner(args: List[str]) -> Optional[Dict[str, Any]]:
116103
"-p",
117104
"vscode_pytest",
118105
] + args
106+
listener: socket.socket = create_server()
107+
_, port = listener.getsockname()
108+
listener.listen()
109+
110+
env = os.environ.copy()
111+
env.update(
112+
{
113+
"TEST_UUID": str(uuid.uuid4()),
114+
"TEST_PORT": str(port),
115+
"PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
116+
}
117+
)
118+
119+
result: list = []
120+
t1: threading.Thread = threading.Thread(
121+
target=_listen_on_socket, args=(listener, result)
122+
)
123+
t1.start()
124+
125+
t2 = threading.Thread(
126+
target=lambda proc_args, proc_env, proc_cwd: subprocess.run(
127+
proc_args, env=proc_env, cwd=proc_cwd
128+
),
129+
args=(process_args, env, TEST_DATA_PATH),
130+
)
131+
t2.start()
132+
133+
t1.join()
134+
t2.join()
135+
136+
return process_rpc_json(result[0]) if result else None
137+
119138

120-
with test_output_file(TEST_DATA_PATH) as output_path:
121-
env = os.environ.copy()
122-
env.update(
123-
{
124-
"TEST_UUID": str(uuid.uuid4()),
125-
"TEST_PORT": str(12345), # port is not used for tests
126-
"PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
127-
"TEST_OUTPUT_FILE": os.fspath(output_path),
128-
}
129-
)
130-
131-
result = subprocess.run(
132-
process_args,
133-
env=env,
134-
cwd=os.fspath(TEST_DATA_PATH),
135-
stdout=subprocess.PIPE,
136-
stderr=subprocess.PIPE,
137-
)
138-
if result.returncode != 0:
139-
print("Subprocess Run failed with:")
140-
print(result.stdout.decode(encoding="utf-8"))
141-
print(result.stderr.decode(encoding="utf-8"))
142-
143-
return process_rpc_json(output_path.read_text(encoding="utf-8"))
139+
def _listen_on_socket(listener: socket.socket, result: List[str]):
140+
"""Listen on the socket for the JSON data from the server.
141+
Created as a seperate function for clarity in threading.
142+
"""
143+
sock, (other_host, other_port) = listener.accept()
144+
all_data: list = []
145+
while True:
146+
data: bytes = sock.recv(1024 * 1024)
147+
if not data:
148+
break
149+
all_data.append(data.decode("utf-8"))
150+
result.append("".join(all_data))
144151

145152

146153
def find_test_line_number(test_name: str, test_file_path) -> str:

pythonFiles/vscode_pytest/__init__.py

+14-26
Original file line numberDiff line numberDiff line change
@@ -437,19 +437,13 @@ def execution_post(
437437
Request-uuid: {testuuid}
438438
439439
{data}"""
440-
test_output_file: Optional[str] = os.getenv("TEST_OUTPUT_FILE", None)
441-
if test_output_file == "stdout":
442-
print(request)
443-
elif test_output_file:
444-
pathlib.Path(test_output_file).write_text(request, encoding="utf-8")
445-
else:
446-
try:
447-
with socket_manager.SocketManager(addr) as s:
448-
if s.socket is not None:
449-
s.socket.sendall(request.encode("utf-8"))
450-
except Exception as e:
451-
print(f"Plugin error connection error[vscode-pytest]: {e}")
452-
print(f"[vscode-pytest] data: {request}")
440+
try:
441+
with socket_manager.SocketManager(addr) as s:
442+
if s.socket is not None:
443+
s.socket.sendall(request.encode("utf-8"))
444+
except Exception as e:
445+
print(f"Plugin error connection error[vscode-pytest]: {e}")
446+
print(f"[vscode-pytest] data: {request}")
453447

454448

455449
def post_response(cwd: str, session_node: TestNode) -> None:
@@ -477,16 +471,10 @@ def post_response(cwd: str, session_node: TestNode) -> None:
477471
Request-uuid: {testuuid}
478472
479473
{data}"""
480-
test_output_file: Optional[str] = os.getenv("TEST_OUTPUT_FILE", None)
481-
if test_output_file == "stdout":
482-
print(request)
483-
elif test_output_file:
484-
pathlib.Path(test_output_file).write_text(request, encoding="utf-8")
485-
else:
486-
try:
487-
with socket_manager.SocketManager(addr) as s:
488-
if s.socket is not None:
489-
s.socket.sendall(request.encode("utf-8"))
490-
except Exception as e:
491-
print(f"Plugin error connection error[vscode-pytest]: {e}")
492-
print(f"[vscode-pytest] data: {request}")
474+
try:
475+
with socket_manager.SocketManager(addr) as s:
476+
if s.socket is not None:
477+
s.socket.sendall(request.encode("utf-8"))
478+
except Exception as e:
479+
print(f"Plugin error connection error[vscode-pytest]: {e}")
480+
print(f"[vscode-pytest] data: {request}")

0 commit comments

Comments
 (0)