forked from zhangtaolab/DNALLM
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconftest.py
More file actions
127 lines (95 loc) · 3.49 KB
/
conftest.py
File metadata and controls
127 lines (95 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""Global pytest configuration and cleanup utilities.
This module provides global pytest fixtures and cleanup utilities to ensure
proper resource cleanup and prevent hanging processes.
"""
import atexit
import gc
import multiprocessing
import os
import time
import pytest
def pytest_configure(config):
"""Configure pytest with global settings."""
# Set asyncio mode to auto for better event loop handling
config.option.asyncio_mode = "auto"
def pytest_sessionstart(session):
"""Called after the Session object has been created."""
print("🚀 Starting pytest session with enhanced cleanup...")
# Register cleanup function to run on exit
atexit.register(force_cleanup_and_exit)
def pytest_sessionfinish(session, exitstatus):
"""Called after whole test run finished, right before returning
the exit status.
"""
# 不在这里强制退出, 让pytest正常显示结果
pass
def force_cleanup_and_exit():
"""Force cleanup of all resources and exit."""
try:
print("🧹 Force cleaning up resources...")
# 1. Clean up multiprocessing processes
cleanup_multiprocessing()
# 2. Clean up PyTorch/CUDA resources
cleanup_pytorch_resources()
# 3. Force garbage collection
gc.collect()
# 4. Force exit
print("🚪 Forcing exit...")
os._exit(0)
except Exception as e:
print(f"Warning: Error during cleanup: {e}")
# Force exit even if cleanup fails
os._exit(0)
def cleanup_multiprocessing():
"""Clean up all multiprocessing processes."""
try:
active_children = multiprocessing.active_children()
if active_children:
print(
f"🧹 Cleaning up {len(active_children)} "
f"multiprocessing processes..."
)
# Terminate all processes
for process in active_children:
try:
if process.is_alive():
process.terminate()
except Exception as e:
print(
f"Warning: Failed to terminate process "
f"{process.pid}: {e}"
)
# Wait briefly for termination
time.sleep(0.1)
# Force kill any remaining processes
for process in active_children:
try:
if process.is_alive():
process.kill()
except Exception as e:
print(
f"Warning: Failed to kill process {process.pid}: {e}"
)
except Exception as e:
print(f"Warning: Error during multiprocessing cleanup: {e}")
def cleanup_pytorch_resources():
"""Clean up PyTorch and CUDA resources."""
try:
import torch
# Clear CUDA cache if available
if torch.cuda.is_available():
torch.cuda.empty_cache()
torch.cuda.synchronize()
except Exception as e:
print(f"Warning: Error during PyTorch cleanup: {e}")
@pytest.fixture(scope="session", autouse=True)
def global_cleanup():
"""Global cleanup fixture that runs after all tests."""
# 不在这里强制退出, 让pytest正常显示结果
# 清理工作由atexit注册的函数处理
return
def pytest_unconfigure(config):
"""Called before test process is exited."""
# 不在这里强制退出, 让pytest正常显示结果
# 清理工作由atexit注册的函数处理
pass