33import re
44import threading
55import time as ttime
6+ from typing import Any
67
78import pytest
89import 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 ))
8389def 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 ))
162176def 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 ))
240258def 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 ))
381414def 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