File size: 5,295 Bytes
a2b5c58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f9b2131
a2b5c58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import pytest
from sandbox.session_manager import SessionManager
from sandbox.models import CreateSessionRequest, SessionStatus, SandboxConfig
import time


@pytest.fixture
def session_manager():
    """Create session manager for testing"""
    try:
        manager = SessionManager(SandboxConfig())
        yield manager
        # Cleanup all sessions
        manager.shutdown()
    except RuntimeError as e:
        pytest.skip(f"Docker not available: {e}")


def test_create_session(session_manager):
    """Test creating a new session"""
    request = CreateSessionRequest(
        metadata={"test": "true", "user": "pytest"},
        timeout_minutes=30
    )
    
    session = session_manager.create_session(request)
    
    assert session.session_id is not None
    assert session.container_id is not None
    assert session.volume_name is not None
    assert session.status in [SessionStatus.CREATING, SessionStatus.READY]
    assert session.metadata["test"] == "true"
    assert session.timeout_minutes == 30


def test_get_session(session_manager):
    """Test retrieving a session"""
    request = CreateSessionRequest(metadata={"test": "get"})
    session = session_manager.create_session(request)
    
    # Get session by ID
    retrieved = session_manager.get_session(session.session_id)
    
    assert retrieved is not None
    assert retrieved.session_id == session.session_id
    assert retrieved.container_id == session.container_id


def test_get_nonexistent_session(session_manager):
    """Test getting a session that doesn't exist"""
    session = session_manager.get_session("nonexistent-id")
    assert session is None


def test_list_sessions(session_manager):
    """Test listing all sessions"""
    # Create multiple sessions
    request1 = CreateSessionRequest(metadata={"num": 1})
    request2 = CreateSessionRequest(metadata={"num": 2})
    
    session1 = session_manager.create_session(request1)
    session2 = session_manager.create_session(request2)
    
    # List sessions
    sessions = session_manager.list_sessions()
    
    assert len(sessions) >= 2
    session_ids = [s.session_id for s in sessions]
    assert session1.session_id in session_ids
    assert session2.session_id in session_ids


def test_destroy_session(session_manager):
    """Test destroying a session"""
    request = CreateSessionRequest(metadata={"test": "destroy"})
    session = session_manager.create_session(request)
    
    # Destroy session
    result = session_manager.destroy_session(session.session_id)
    assert result is True
    
    # Verify it's gone
    retrieved = session_manager.get_session(session.session_id)
    assert retrieved is None


def test_destroy_nonexistent_session(session_manager):
    """Test destroying a session that doesn't exist"""
    result = session_manager.destroy_session("nonexistent-id")
    assert result is False


def test_update_activity(session_manager):
    """Test updating session activity timestamp"""
    request = CreateSessionRequest()
    session = session_manager.create_session(request)
    
    original_activity = session.last_activity
    
    # Wait a bit
    time.sleep(0.1)
    
    # Update activity
    session_manager.update_activity(session.session_id)
    
    # Get updated session
    updated = session_manager.get_session(session.session_id)
    
    assert updated.last_activity > original_activity


def test_session_timeout_cleanup(session_manager):
    """Test that idle sessions are cleaned up"""
    # Create session with very short timeout
    request = CreateSessionRequest(timeout_minutes=1)  # 1 minute
    session = session_manager.create_session(request)
    
    # Manually trigger cleanup (simulate timeout by modifying activity time)
    import datetime
    with session_manager._lock:
        # Set activity to 2 minutes ago
        session_manager.sessions[session.session_id].last_activity = \
            datetime.datetime.utcnow() - datetime.timedelta(minutes=2)
    
    # Trigger cleanup
    session_manager._cleanup_idle_sessions()
    
    # Session should be gone
    retrieved = session_manager.get_session(session.session_id)
    assert retrieved is None


def test_concurrent_sessions(session_manager):
    """Test creating multiple concurrent sessions"""
    sessions = []
    num_sessions = 3
    
    for i in range(num_sessions):
        request = CreateSessionRequest(metadata={"index": i})
        session = session_manager.create_session(request)
        sessions.append(session)
    
    # Verify all exist
    all_sessions = session_manager.list_sessions()
    assert len(all_sessions) >= num_sessions
    
    # Cleanup
    for session in sessions:
        session_manager.destroy_session(session.session_id)


def test_session_persistence(session_manager):
    """Test that session containers are actually running"""
    import docker
    
    request = CreateSessionRequest(metadata={"test": "persistence"})
    session = session_manager.create_session(request)
    
    # Verify container exists and is running
    client = docker.from_env()
    try:
        container = client.containers.get(session.container_id)
        assert container.status == 'running'
    except docker.errors.NotFound:
        pytest.fail(f"Container {session.container_id} not found")