15
15
from ethereum_test_forks import Fork
16
16
from pytest_plugins .consume .simulators .helpers .ruleset import ruleset
17
17
18
+ from .test_tracker import PreAllocGroupTestTracker
19
+
18
20
logger = logging .getLogger (__name__ )
19
21
20
22
@@ -248,12 +250,22 @@ def set_client(self, client: Client) -> None:
248
250
)
249
251
250
252
def stop (self ) -> None :
251
- """Override to log with pre_hash information."""
253
+ """Override to log with pre_hash information and actually stop the client ."""
252
254
if self ._is_started :
253
255
logger .info (
254
- f"Marking multi-test client ({ self .client_type .name } ) for pre-allocation group "
255
- f"{ self .pre_hash } as stopped after { self .test_count } tests"
256
+ f"Stopping multi-test client ({ self .client_type .name } ) for pre-allocation group "
257
+ f"{ self .pre_hash } after { self .test_count } tests"
256
258
)
259
+ # Actually stop the Hive client
260
+ if self .client is not None :
261
+ try :
262
+ self .client .stop ()
263
+ logger .debug (f"Hive client stopped for pre-allocation group { self .pre_hash } " )
264
+ except Exception as e :
265
+ logger .error (
266
+ f"Error stopping Hive client for pre-allocation group { self .pre_hash } : { e } "
267
+ )
268
+
257
269
self .client = None
258
270
self ._is_started = False
259
271
@@ -283,6 +295,7 @@ def __init__(self) -> None:
283
295
284
296
self .multi_test_clients : Dict [str , MultiTestClient ] = {}
285
297
self .pre_alloc_path : Optional [Path ] = None
298
+ self .test_tracker : Optional ["PreAllocGroupTestTracker" ] = None
286
299
self ._initialized = True
287
300
logger .info ("MultiTestClientManager initialized" )
288
301
@@ -297,6 +310,17 @@ def set_pre_alloc_path(self, path: Path) -> None:
297
310
self .pre_alloc_path = path
298
311
logger .debug (f"Pre-alloc path set to: { path } " )
299
312
313
+ def set_test_tracker (self , test_tracker : "PreAllocGroupTestTracker" ) -> None :
314
+ """
315
+ Set the test tracker for automatic client cleanup.
316
+
317
+ Args:
318
+ test_tracker: The test tracker instance
319
+
320
+ """
321
+ self .test_tracker = test_tracker
322
+ logger .debug ("Test tracker set for automatic client cleanup" )
323
+
300
324
def load_pre_alloc_group (self , pre_hash : str ) -> PreAllocGroup :
301
325
"""
302
326
Load the pre-allocation group for a given preHash.
@@ -373,12 +397,15 @@ def get_or_create_multi_test_client(
373
397
374
398
return multi_test_client
375
399
376
- def get_client_for_test (self , pre_hash : str ) -> Optional [Client ]:
400
+ def get_client_for_test (
401
+ self , pre_hash : str , test_id : Optional [str ] = None
402
+ ) -> Optional [Client ]:
377
403
"""
378
404
Get the actual client instance for a test with the given preHash.
379
405
380
406
Args:
381
407
pre_hash: The hash identifying the pre-allocation group
408
+ test_id: Optional test ID for completion tracking
382
409
383
410
Returns:
384
411
The client instance if available, None otherwise
@@ -391,6 +418,58 @@ def get_client_for_test(self, pre_hash: str) -> Optional[Client]:
391
418
return multi_test_client .client
392
419
return None
393
420
421
+ def mark_test_completed (self , pre_hash : str , test_id : str ) -> None :
422
+ """
423
+ Mark a test as completed and trigger automatic client cleanup if appropriate.
424
+
425
+ Args:
426
+ pre_hash: The hash identifying the pre-allocation group
427
+ test_id: The unique test identifier
428
+
429
+ """
430
+ if self .test_tracker is None :
431
+ logger .debug ("No test tracker available, skipping completion tracking" )
432
+ return
433
+
434
+ # Mark test as completed in tracker
435
+ is_group_complete = self .test_tracker .mark_test_completed (pre_hash , test_id )
436
+
437
+ if is_group_complete :
438
+ # All tests in this pre-allocation group are complete
439
+ self ._auto_stop_client_if_complete (pre_hash )
440
+
441
+ def _auto_stop_client_if_complete (self , pre_hash : str ) -> None :
442
+ """
443
+ Automatically stop the client for a pre-allocation group if all tests are complete.
444
+
445
+ Args:
446
+ pre_hash: The hash identifying the pre-allocation group
447
+
448
+ """
449
+ if pre_hash not in self .multi_test_clients :
450
+ logger .debug (f"No client found for pre-allocation group { pre_hash } " )
451
+ return
452
+
453
+ multi_test_client = self .multi_test_clients [pre_hash ]
454
+ if not multi_test_client .is_running :
455
+ logger .debug (f"Client for pre-allocation group { pre_hash } is already stopped" )
456
+ return
457
+
458
+ # Stop the client and remove from tracking
459
+ logger .info (
460
+ f"Auto-stopping client for pre-allocation group { pre_hash } - "
461
+ f"all tests completed ({ multi_test_client .test_count } tests executed)"
462
+ )
463
+
464
+ try :
465
+ multi_test_client .stop ()
466
+ except Exception as e :
467
+ logger .error (f"Error auto-stopping client for pre-allocation group { pre_hash } : { e } " )
468
+ finally :
469
+ # Remove from tracking to free memory
470
+ del self .multi_test_clients [pre_hash ]
471
+ logger .debug (f"Removed completed client from tracking: { pre_hash } " )
472
+
394
473
def stop_all_clients (self ) -> None :
395
474
"""Mark all multi-test clients as stopped."""
396
475
logger .info (f"Marking all { len (self .multi_test_clients )} multi-test clients as stopped" )
@@ -422,4 +501,5 @@ def reset(self) -> None:
422
501
self .stop_all_clients ()
423
502
self .multi_test_clients .clear ()
424
503
self .pre_alloc_path = None
504
+ self .test_tracker = None
425
505
logger .info ("MultiTestClientManager reset" )
0 commit comments