1313
1414
1515SPIKE_ROOT = Path (__file__ ).resolve ().parent
16- THREAD_TIMEOUT = 5.0
16+ TIMEOUT_MULTIPLIER = float (
17+ os .environ .get ("GRAPHCODE_REMOTE_BRIDGE_TEST_TIMEOUT_MULTIPLIER" , "1" )
18+ )
19+ if not math .isfinite (TIMEOUT_MULTIPLIER ) or not 1 <= TIMEOUT_MULTIPLIER <= 10 :
20+ raise ValueError (
21+ "GRAPHCODE_REMOTE_BRIDGE_TEST_TIMEOUT_MULTIPLIER must be between 1 and 10"
22+ )
23+ SOCKET_TIMEOUT = 1.0 * TIMEOUT_MULTIPLIER
24+ THREAD_TIMEOUT = 5.0 * TIMEOUT_MULTIPLIER
1725sys .path .insert (0 , str (SPIKE_ROOT ))
1826
1927from remote_bridge import ( # noqa: E402
@@ -40,6 +48,7 @@ def setUp(self):
4048 self .backend .address ,
4149 ttl_seconds = 30.0 ,
4250 previous_overlap_seconds = 0.4 ,
51+ request_timeout = 2.0 * TIMEOUT_MULTIPLIER ,
4352 )
4453 self .bridge .start ()
4554
@@ -57,7 +66,7 @@ def raw_request(
5766 omit_capability = False ,
5867 ):
5968 with socket .create_connection (
60- (state ["host" ], state ["port" ]), timeout = 1.0
69+ (state ["host" ], state ["port" ]), timeout = SOCKET_TIMEOUT
6170 ) as connection :
6271 message = {
6372 "generation" : generation or state ["generation" ],
@@ -99,21 +108,21 @@ def test_slow_drip_connections_are_bounded_by_cumulative_deadline(self):
99108 for _ in range (2 ):
100109 connection = socket .create_connection (
101110 (state ["host" ], state ["port" ]),
102- timeout = 1.0 ,
111+ timeout = SOCKET_TIMEOUT ,
103112 )
104113 connection .sendall (b"\0 " )
105114 connections .append (connection )
106- deadline = time .time () + 1
115+ deadline = time .time () + SOCKET_TIMEOUT
107116 while self .bridge .active_client_count < 2 :
108117 if time .time () >= deadline :
109118 self .fail ("bounded client workers did not start" )
110119 time .sleep (0.01 )
111120
112121 rejected = socket .create_connection (
113122 (state ["host" ], state ["port" ]),
114- timeout = 1.0 ,
123+ timeout = SOCKET_TIMEOUT ,
115124 )
116- rejected .settimeout (1.0 )
125+ rejected .settimeout (SOCKET_TIMEOUT )
117126 try :
118127 self .assertEqual (rejected .recv (1 ), b"" )
119128 finally :
@@ -125,15 +134,18 @@ def test_slow_drip_connections_are_bounded_by_cumulative_deadline(self):
125134 connection .sendall (b"\0 " )
126135 except OSError :
127136 pass
128- expiry = time .monotonic () + 0.35
137+ expiry = time .monotonic () + 0.35 * TIMEOUT_MULTIPLIER
129138 while self .bridge .active_client_count :
130139 if time .monotonic () >= expiry :
131140 self .fail ("slow-drip worker exceeded cumulative deadline plus scheduler margin" )
132141 time .sleep (0.005 )
133142 self .assertEqual (self .bridge .active_client_count , 0 )
134143 stop_started = time .monotonic ()
135144 self .bridge .stop ()
136- self .assertLess (time .monotonic () - stop_started , 1.0 )
145+ self .assertLess (
146+ time .monotonic () - stop_started ,
147+ 1.0 * TIMEOUT_MULTIPLIER ,
148+ )
137149 self .assertEqual (self .bridge .worker_count , 0 )
138150 finally :
139151 for connection in connections :
@@ -144,18 +156,18 @@ def test_stop_closes_active_client_sockets(self):
144156 state = BridgeStateStore (self .state_path ).read ()
145157 connection = socket .create_connection (
146158 (state ["host" ], state ["port" ]),
147- timeout = 1.0 ,
159+ timeout = SOCKET_TIMEOUT ,
148160 )
149161 connection .sendall (b"\0 " )
150- deadline = time .time () + 1
162+ deadline = time .time () + SOCKET_TIMEOUT
151163 while self .bridge .active_client_count < 1 :
152164 if time .time () >= deadline :
153165 connection .close ()
154166 self .fail ("client worker did not start" )
155167 time .sleep (0.01 )
156168
157169 self .bridge .stop ()
158- connection .settimeout (1.0 )
170+ connection .settimeout (SOCKET_TIMEOUT )
159171 try :
160172 result = connection .recv (1 )
161173 except ConnectionResetError :
@@ -215,7 +227,10 @@ def test_state_timestamps_must_be_finite(self):
215227 invalid_path .unlink (missing_ok = True )
216228
217229 def test_client_reads_state_and_bridges_framed_request_response (self ):
218- client = RemoteBridgeClient (self .state_path )
230+ client = RemoteBridgeClient (
231+ self .state_path ,
232+ timeout = 2.0 * TIMEOUT_MULTIPLIER ,
233+ )
219234
220235 response = client .request ({"command" : "status" })
221236
@@ -226,7 +241,7 @@ def test_client_reads_state_and_bridges_framed_request_response(self):
226241 def test_authenticated_session_relays_multiple_frames_on_one_connection (self ):
227242 state = BridgeStateStore (self .state_path ).read ()
228243 with socket .create_connection (
229- (state ["host" ], state ["port" ]), timeout = 1.0
244+ (state ["host" ], state ["port" ]), timeout = SOCKET_TIMEOUT
230245 ) as connection :
231246 bodies = ({"command" : "openProject" }, {"command" : "status" })
232247 for body in bodies [:1 ]:
@@ -339,7 +354,7 @@ def test_malformed_frame_is_rejected(self):
339354 state = BridgeStateStore (self .state_path ).read ()
340355 payload = b"not-json"
341356 with socket .create_connection (
342- (state ["host" ], state ["port" ]), timeout = 1.0
357+ (state ["host" ], state ["port" ]), timeout = SOCKET_TIMEOUT
343358 ) as connection :
344359 connection .sendall (len (payload ).to_bytes (4 , "big" ) + payload )
345360 response = read_frame (connection )
@@ -731,7 +746,7 @@ def read_states():
731746 def test_oversized_frame_is_rejected (self ):
732747 state = BridgeStateStore (self .state_path ).read ()
733748 with socket .create_connection (
734- (state ["host" ], state ["port" ]), timeout = 1.0
749+ (state ["host" ], state ["port" ]), timeout = SOCKET_TIMEOUT
735750 ) as connection :
736751 connection .sendall ((1_048_577 ).to_bytes (4 , "big" ))
737752 response = read_frame (connection )
0 commit comments