You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.2 KiB
Python
89 lines
2.2 KiB
Python
import asyncio
|
|
import subprocess
|
|
import sys
|
|
|
|
import pytest
|
|
from tornado.queues import Queue
|
|
|
|
from jupyter_lsp.stdio import LspStdIoReader
|
|
|
|
WRITER_TEMPLATE = """
|
|
from time import sleep
|
|
|
|
print('Content-Length: {length}')
|
|
print()
|
|
|
|
for repeat in range({repeats}):
|
|
sleep({interval})
|
|
print('{message}', end='')
|
|
|
|
if {add_excess}:
|
|
print("extra", end='')
|
|
|
|
print()
|
|
"""
|
|
|
|
|
|
class CommunicatorSpawner:
|
|
def __init__(self, tmp_path):
|
|
self.tmp_path = tmp_path
|
|
|
|
def spawn_writer(
|
|
self, message: str, repeats: int = 1, interval=None, add_excess=False
|
|
):
|
|
length = len(message) * repeats
|
|
commands_file = self.tmp_path / "writer.py"
|
|
commands_file.write_text(
|
|
WRITER_TEMPLATE.format(
|
|
length=length,
|
|
repeats=repeats,
|
|
interval=interval or 0,
|
|
message=message,
|
|
add_excess=add_excess,
|
|
)
|
|
)
|
|
return subprocess.Popen(
|
|
[sys.executable, "-u", str(commands_file)],
|
|
stdout=subprocess.PIPE,
|
|
bufsize=0,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def communicator_spawner(tmp_path):
|
|
return CommunicatorSpawner(tmp_path)
|
|
|
|
|
|
async def join_process(process: subprocess.Popen, headstart=1, timeout=1):
|
|
await asyncio.sleep(headstart)
|
|
result = process.wait(timeout=timeout)
|
|
if process.stdout:
|
|
process.stdout.close()
|
|
return result
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"message,repeats,interval,add_excess",
|
|
[
|
|
["short", 1, None, False],
|
|
["ab" * 10_0000, 1, None, False],
|
|
["ab", 2, 0.01, False],
|
|
["ab", 45, 0.01, False],
|
|
["message", 2, 0.01, True],
|
|
],
|
|
ids=["short", "long", "intermittent", "intensive-intermittent", "with-excess"],
|
|
)
|
|
@pytest.mark.asyncio
|
|
async def test_reader(message, repeats, interval, add_excess, communicator_spawner):
|
|
queue = Queue()
|
|
|
|
process = communicator_spawner.spawn_writer(
|
|
message=message, repeats=repeats, interval=interval, add_excess=add_excess
|
|
)
|
|
reader = LspStdIoReader(stream=process.stdout, queue=queue)
|
|
|
|
await asyncio.gather(join_process(process, headstart=3, timeout=1), reader.read())
|
|
|
|
result = queue.get_nowait()
|
|
assert result == message * repeats
|