1
1
import logging
2
2
import ssl
3
3
import threading
4
- import time
5
4
from pathlib import Path
6
5
7
6
import pytest
7
+ import requests
8
8
import uvicorn
9
9
from fastapi import FastAPI
10
10
from starlette .responses import Response
15
15
from everest .detached .jobs .everserver import _find_open_port
16
16
from everest .gui .everest_client import EverestClient
17
17
from everest .strings import STOP_ENDPOINT
18
+ from tests .ert .utils import wait_until
18
19
19
20
20
21
@pytest .fixture
@@ -24,6 +25,10 @@ def client_server_mock() -> tuple[FastAPI, threading.Thread, EverestClient]:
24
25
port = _find_open_port (host , lower = 5000 , upper = 5800 )
25
26
server_url = f"http://{ host } :{ port } "
26
27
28
+ @server_app .get ("alive" )
29
+ def alive ():
30
+ return Response ("Hello" , status_code = 200 )
31
+
27
32
server = uvicorn .Server (
28
33
uvicorn .Config (server_app , host = host , port = port , log_level = "info" )
29
34
)
@@ -41,7 +46,23 @@ def client_server_mock() -> tuple[FastAPI, threading.Thread, EverestClient]:
41
46
ssl_context = ssl .create_default_context (),
42
47
)
43
48
44
- yield server_app , server_thread , everest_client
49
+ def wait_until_alive (timeout = 60 , sleep_between_retries = 1 ) -> None :
50
+ def ping_server () -> bool :
51
+ try :
52
+ requests .get (
53
+ f"{ server_url } /alive" ,
54
+ verify = "N/A" ,
55
+ auth = ("" , "" ),
56
+ proxies = {"http" : None , "https" : None }, # type: ignore
57
+ )
58
+
59
+ return True
60
+ except requests .exceptions .ConnectionError :
61
+ return False
62
+
63
+ wait_until (ping_server , timeout = timeout , interval = sleep_between_retries )
64
+
65
+ yield server_app , server_thread , everest_client , wait_until_alive
45
66
46
67
if server_thread .is_alive ():
47
68
server .should_exit = True
@@ -51,14 +72,14 @@ def client_server_mock() -> tuple[FastAPI, threading.Thread, EverestClient]:
51
72
def test_that_stop_invokes_correct_endpoint (
52
73
caplog , client_server_mock : tuple [FastAPI , threading .Thread , EverestClient ]
53
74
):
54
- server_app , server_thread , client = client_server_mock
75
+ server_app , server_thread , client , wait_until_alive = client_server_mock
55
76
56
77
@server_app .post (f"/{ STOP_ENDPOINT } " )
57
78
def stop ():
58
79
return Response ("STOP.." , 200 )
59
80
60
81
server_thread .start ()
61
- time . sleep ( 0.1 )
82
+ wait_until_alive ( )
62
83
63
84
with caplog .at_level (logging .INFO ):
64
85
client .stop ()
@@ -70,14 +91,14 @@ def stop():
70
91
def test_that_stop_errors_on_non_ok_httpcode (
71
92
caplog , client_server_mock : tuple [FastAPI , threading .Thread , EverestClient ]
72
93
):
73
- server_app , server_thread , client = client_server_mock
94
+ server_app , server_thread , client , wait_until_alive = client_server_mock
74
95
75
96
@server_app .post (f"/{ STOP_ENDPOINT } " )
76
97
def stop ():
77
98
return Response ("STOP.." , 505 )
78
99
79
100
server_thread .start ()
80
- time . sleep ( 0.1 )
101
+ wait_until_alive ( )
81
102
82
103
with caplog .at_level (logging .ERROR ):
83
104
client .stop ()
@@ -92,7 +113,7 @@ def stop():
92
113
def test_that_stop_errors_on_server_down (
93
114
caplog , client_server_mock : tuple [FastAPI , threading .Thread , EverestClient ]
94
115
):
95
- _ , _ , client = client_server_mock
116
+ _ , _ , client , _ = client_server_mock
96
117
97
118
with caplog .at_level (logging .ERROR ):
98
119
client .stop ()
@@ -107,10 +128,10 @@ def test_that_stop_errors_on_server_down(
107
128
def test_that_stop_errors_on_server_up_but_endpoint_down (
108
129
caplog , client_server_mock : tuple [FastAPI , threading .Thread , EverestClient ]
109
130
):
110
- _ , server_thread , client = client_server_mock
131
+ _ , server_thread , client , wait_until_alive = client_server_mock
111
132
112
133
server_thread .start ()
113
- time . sleep ( 0.1 )
134
+ wait_until_alive ( )
114
135
115
136
with caplog .at_level (logging .ERROR ):
116
137
client .stop ()
0 commit comments