Skip to content

Commit b7db23b

Browse files
committed
Another test of fixing the runners
1 parent 817bc5c commit b7db23b

1 file changed

Lines changed: 84 additions & 43 deletions

File tree

bluesky_httpserver/tests/test_console_output.py

Lines changed: 84 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
import threading
55
import time as ttime
6+
from typing import Any
67

78
import pytest
89
import requests
@@ -36,37 +37,42 @@ def __init__(self, api_key=API_KEY_FOR_TESTS, **kwargs):
3637
self._api_key = api_key
3738

3839
def run(self):
39-
kwargs = {"stream": True}
40+
kwargs: dict[str, Any] = {"stream": True}
4041
if self._api_key:
41-
auth = None
4242
headers = {"Authorization": f"ApiKey {self._api_key}"}
43-
kwargs.update({"auth": auth, "headers": headers})
43+
kwargs.update({"headers": headers})
4444

45-
with requests.get(f"http://{SERVER_ADDRESS}:{SERVER_PORT}/api/stream_console_output", **kwargs) as r:
46-
r.encoding = "utf-8"
45+
kwargs["timeout"] = (5, 1)
4746

48-
characters = []
49-
n_brackets = 0
47+
while not self._exit:
48+
try:
49+
with requests.get(
50+
f"http://{SERVER_ADDRESS}:{SERVER_PORT}/api/stream_console_output",
51+
**kwargs,
52+
) as r:
53+
r.encoding = "utf-8"
5054

51-
for ch in r.iter_content(decode_unicode=True):
52-
# Note, that some output must be received from the server before the loop exits
53-
if self._exit:
54-
break
55+
characters = []
56+
n_brackets = 0
5557

56-
characters.append(ch)
57-
if ch == "{":
58-
n_brackets += 1
59-
elif ch == "}":
60-
n_brackets -= 1
58+
for ch in r.iter_content(decode_unicode=True):
59+
if self._exit:
60+
return
6161

62-
# If the received buffer ('characters') is not empty and the message contains
63-
# equal number of opening and closing brackets then consider the message complete.
64-
if characters and not n_brackets:
65-
line = "".join(characters)
66-
characters = []
62+
characters.append(ch)
63+
if ch == "{":
64+
n_brackets += 1
65+
elif ch == "}":
66+
n_brackets -= 1
67+
68+
if characters and not n_brackets:
69+
line = "".join(characters)
70+
characters = []
6771

68-
print(f"{line}")
69-
self.received_data_buffer.append(json.loads(line))
72+
print(f"{line}")
73+
self.received_data_buffer.append(json.loads(line))
74+
except requests.exceptions.ReadTimeout:
75+
continue
7076

7177
def stop(self):
7278
"""
@@ -81,7 +87,10 @@ def __del__(self):
8187

8288
@pytest.mark.parametrize("zmq_port", (None, 60619))
8389
def test_http_server_stream_console_output_1(
84-
monkeypatch, re_manager_cmd, fastapi_server_fs, zmq_port # noqa F811
90+
monkeypatch,
91+
re_manager_cmd,
92+
fastapi_server_fs,
93+
zmq_port, # noqa F811
8594
):
8695
"""
8796
Test for ``stream_console_output`` API
@@ -103,7 +112,9 @@ def test_http_server_stream_console_output_1(
103112
resp1 = request_to_json(
104113
"post",
105114
"/queue/item/add",
106-
json={"item": {"name": "count", "args": [["det1", "det2"]], "item_type": "plan"}},
115+
json={
116+
"item": {"name": "count", "args": [["det1", "det2"]], "item_type": "plan"}
117+
},
107118
)
108119
assert resp1["success"] is True
109120
assert resp1["qsize"] == 1
@@ -122,7 +133,10 @@ def test_http_server_stream_console_output_1(
122133
assert resp2["items"][0] == resp1["item"]
123134
assert resp2["running_item"] == {}
124135

125-
rsc.join()
136+
rsc.join(timeout=10)
137+
assert not rsc.is_alive(), (
138+
"Timed out waiting for stream_console_output thread to terminate"
139+
)
126140

127141
assert len(rsc.received_data_buffer) >= 2, pprint.pformat(rsc.received_data_buffer)
128142

@@ -134,9 +148,9 @@ def test_http_server_stream_console_output_1(
134148
if emsg in msg["msg"]:
135149
expected_messages.remove(emsg)
136150

137-
assert (
138-
not expected_messages
139-
), f"Messages {expected_messages} were not found in captured output: {pprint.pformat(buffer)}"
151+
assert not expected_messages, (
152+
f"Messages {expected_messages} were not found in captured output: {pprint.pformat(buffer)}"
153+
)
140154

141155

142156
_script1 = r"""
@@ -160,7 +174,11 @@ def test_http_server_stream_console_output_1(
160174
@pytest.mark.parametrize("zmq_encoding", (None, "json", "msgpack"))
161175
@pytest.mark.parametrize("zmq_port", (None, 60619))
162176
def test_http_server_console_output_1(
163-
monkeypatch, re_manager_cmd, fastapi_server_fs, zmq_port, zmq_encoding # noqa F811
177+
monkeypatch,
178+
re_manager_cmd,
179+
fastapi_server_fs,
180+
zmq_port,
181+
zmq_encoding, # noqa F811
164182
):
165183
"""
166184
Test for ``console_output`` API (not a streaming version).
@@ -238,7 +256,10 @@ def test_http_server_console_output_1(
238256

239257
@pytest.mark.parametrize("zmq_port", (None, 60619))
240258
def test_http_server_console_output_update_1(
241-
monkeypatch, re_manager_cmd, fastapi_server_fs, zmq_port # noqa F811
259+
monkeypatch,
260+
re_manager_cmd,
261+
fastapi_server_fs,
262+
zmq_port, # noqa F811
242263
):
243264
"""
244265
Test for ``console_output`` API (not a streaming version).
@@ -270,7 +291,9 @@ def test_http_server_console_output_update_1(
270291
assert resp2a["console_output_msgs"] == []
271292

272293
# Download ALL existing messages
273-
resp2b = request_to_json("get", "/console_output_update", json={"last_msg_uid": "ALL"})
294+
resp2b = request_to_json(
295+
"get", "/console_output_update", json={"last_msg_uid": "ALL"}
296+
)
274297
assert resp2b["success"] is True
275298
assert resp2b["msg"] == ""
276299
assert resp2b["last_msg_uid"] == last_msg_uid_1
@@ -286,15 +309,19 @@ def test_http_server_console_output_update_1(
286309
ttime.sleep(3)
287310
assert wait_for_manager_state_idle(timeout=10)
288311

289-
resp4a = request_to_json("get", "/console_output_update", json={"last_msg_uid": last_msg_uid_1})
312+
resp4a = request_to_json(
313+
"get", "/console_output_update", json={"last_msg_uid": last_msg_uid_1}
314+
)
290315
last_msg_uid_2 = resp4a["last_msg_uid"]
291316
assert last_msg_uid_2 != last_msg_uid_1
292317
console_output = resp4a["console_output_msgs"]
293318
console_output_text = "".join([_["msg"] for _ in console_output])
294319
assert expected_output in console_output_text
295320
assert console_output_text.count(expected_output) == 1
296321

297-
resp4b = request_to_json("get", "/console_output_update", json={"last_msg_uid": "ALL"})
322+
resp4b = request_to_json(
323+
"get", "/console_output_update", json={"last_msg_uid": "ALL"}
324+
)
298325
assert resp4b["last_msg_uid"] == last_msg_uid_2
299326
console_output = resp4b["console_output_msgs"]
300327
console_output_text = "".join([_["msg"] for _ in console_output])
@@ -311,7 +338,9 @@ def test_http_server_console_output_update_1(
311338
assert wait_for_manager_state_idle(timeout=10)
312339

313340
# Download the lastest updates
314-
resp6a = request_to_json("get", "/console_output_update", json={"last_msg_uid": last_msg_uid_2})
341+
resp6a = request_to_json(
342+
"get", "/console_output_update", json={"last_msg_uid": last_msg_uid_2}
343+
)
315344
last_msg_uid_3 = resp6a["last_msg_uid"]
316345
assert last_msg_uid_3 != last_msg_uid_2
317346
console_output = resp6a["console_output_msgs"]
@@ -321,15 +350,19 @@ def test_http_server_console_output_update_1(
321350

322351
# Download the updates using 'old' UID. The script was uploaded twice, so the output should
323352
# contain two copies of the printed output
324-
resp6b = request_to_json("get", "/console_output_update", json={"last_msg_uid": last_msg_uid_1})
353+
resp6b = request_to_json(
354+
"get", "/console_output_update", json={"last_msg_uid": last_msg_uid_1}
355+
)
325356
assert resp6b["last_msg_uid"] == last_msg_uid_3
326357
console_output = resp6b["console_output_msgs"]
327358
console_output_text = "".join([_["msg"] for _ in console_output])
328359
assert expected_output in console_output_text
329360
assert console_output_text.count(expected_output) == 2
330361

331362
# No updates are expected since last request
332-
resp6c = request_to_json("get", "/console_output_update", json={"last_msg_uid": last_msg_uid_3})
363+
resp6c = request_to_json(
364+
"get", "/console_output_update", json={"last_msg_uid": last_msg_uid_3}
365+
)
333366
assert resp6c["last_msg_uid"] == last_msg_uid_3
334367
assert resp6c["console_output_msgs"] == []
335368

@@ -379,7 +412,10 @@ def __del__(self):
379412

380413
@pytest.mark.parametrize("zmq_port", (None, 60619))
381414
def test_http_server_console_output_socket_1(
382-
monkeypatch, re_manager_cmd, fastapi_server_fs, zmq_port # noqa F811
415+
monkeypatch,
416+
re_manager_cmd,
417+
fastapi_server_fs,
418+
zmq_port, # noqa F811
383419
):
384420
"""
385421
Test for ``/console_output/ws`` websocket
@@ -402,7 +438,9 @@ def test_http_server_console_output_socket_1(
402438
resp1 = request_to_json(
403439
"post",
404440
"/queue/item/add",
405-
json={"item": {"name": "count", "args": [["det1", "det2"]], "item_type": "plan"}},
441+
json={
442+
"item": {"name": "count", "args": [["det1", "det2"]], "item_type": "plan"}
443+
},
406444
)
407445
assert resp1["success"] is True
408446
assert resp1["qsize"] == 1
@@ -421,7 +459,10 @@ def test_http_server_console_output_socket_1(
421459
assert resp2["items"][0] == resp1["item"]
422460
assert resp2["running_item"] == {}
423461

424-
rsc.join()
462+
rsc.join(timeout=10)
463+
assert not rsc.is_alive(), (
464+
"Timed out waiting for console_output websocket thread to terminate"
465+
)
425466

426467
assert len(rsc.received_data_buffer) >= 2, pprint.pformat(rsc.received_data_buffer)
427468

@@ -433,6 +474,6 @@ def test_http_server_console_output_socket_1(
433474
if emsg in msg["msg"]:
434475
expected_messages.remove(emsg)
435476

436-
assert (
437-
not expected_messages
438-
), f"Messages {expected_messages} were not found in captured output: {pprint.pformat(buffer)}"
477+
assert not expected_messages, (
478+
f"Messages {expected_messages} were not found in captured output: {pprint.pformat(buffer)}"
479+
)

0 commit comments

Comments
 (0)