-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_collabsession.py
More file actions
374 lines (292 loc) · 13.6 KB
/
Copy pathtest_collabsession.py
File metadata and controls
374 lines (292 loc) · 13.6 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
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#!/usr/bin/env python3
"""
Comprehensive test suite for CollabSession v1.0
Tests:
- Session creation and management
- Agent add/remove
- Role assignment
- Resource locking
- Status tracking
- History tracking
- Notifications
- Database persistence
Author: Atlas (Team Brain)
Date: January 19, 2026
"""
import unittest
import tempfile
import shutil
from pathlib import Path
from datetime import datetime
from collabsession import CollabSession, Agent, ResourceLock, AgentStatus, SessionStatus, list_sessions
class TestCollabSession(unittest.TestCase):
"""Test suite for CollabSession."""
def setUp(self):
"""Set up test environment."""
# Create temporary database
self.test_db = Path(tempfile.mkdtemp()) / "test_collab.db"
self.session_id = "test_session_001"
self.session = CollabSession(self.session_id, db_path=self.test_db)
def tearDown(self):
"""Clean up test environment."""
# Remove temporary database
if self.test_db.parent.exists():
shutil.rmtree(self.test_db.parent, ignore_errors=True)
def test_01_session_creation(self):
"""Test session creation."""
status = self.session.get_status()
self.assertEqual(status["session_id"], self.session_id)
self.assertEqual(status["status"], SessionStatus.ACTIVE.value)
self.assertIsNotNone(status["created_at"])
self.assertEqual(len(status["agents"]), 0) # No agents yet
def test_02_add_agent(self):
"""Test adding agents to session."""
# Add first agent
success = self.session.add_agent("FORGE", role="planner")
self.assertTrue(success)
# Add second agent
success = self.session.add_agent("BOLT", role="builder")
self.assertTrue(success)
# Verify agents added
agents = self.session.get_agents()
self.assertEqual(len(agents), 2)
self.assertEqual(agents[0].agent_name, "FORGE")
self.assertEqual(agents[0].role, "planner")
self.assertEqual(agents[1].agent_name, "BOLT")
self.assertEqual(agents[1].role, "builder")
def test_03_add_duplicate_agent(self):
"""Test adding duplicate agent fails."""
self.session.add_agent("FORGE", role="planner")
# Try to add same agent again
success = self.session.add_agent("FORGE", role="reviewer")
self.assertFalse(success) # Should fail
# Verify only one instance
agents = self.session.get_agents()
self.assertEqual(len(agents), 1)
def test_04_remove_agent(self):
"""Test removing agents from session."""
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
# Remove one agent
success = self.session.remove_agent("FORGE")
self.assertTrue(success)
# Verify removed
agents = self.session.get_agents()
self.assertEqual(len(agents), 1)
self.assertEqual(agents[0].agent_name, "BOLT")
def test_05_lock_resource(self):
"""Test locking a resource."""
self.session.add_agent("FORGE", role="planner")
# Lock a resource
success = self.session.lock_resource("spec.md", "FORGE", resource_type="file")
self.assertTrue(success)
# Verify lock exists
self.assertTrue(self.session.is_locked("spec.md"))
locks = self.session.get_locks()
self.assertEqual(len(locks), 1)
self.assertEqual(locks[0].resource_id, "spec.md")
self.assertEqual(locks[0].locked_by, "FORGE")
def test_06_duplicate_lock_fails(self):
"""Test that locking already-locked resource fails."""
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
# FORGE locks resource
success = self.session.lock_resource("code.py", "FORGE")
self.assertTrue(success)
# BOLT tries to lock same resource
success = self.session.lock_resource("code.py", "BOLT")
self.assertFalse(success) # Should fail
# Verify only one lock
locks = self.session.get_locks()
self.assertEqual(len(locks), 1)
self.assertEqual(locks[0].locked_by, "FORGE")
def test_07_unlock_resource(self):
"""Test unlocking a resource."""
self.session.add_agent("FORGE", role="planner")
self.session.lock_resource("file.txt", "FORGE")
# Unlock
success = self.session.unlock_resource("file.txt")
self.assertTrue(success)
# Verify unlocked
self.assertFalse(self.session.is_locked("file.txt"))
locks = self.session.get_locks()
self.assertEqual(len(locks), 0)
def test_08_remove_agent_releases_locks(self):
"""Test that removing agent releases their locks."""
self.session.add_agent("FORGE", role="planner")
self.session.lock_resource("file1.txt", "FORGE")
self.session.lock_resource("file2.txt", "FORGE")
# Verify locks exist
self.assertEqual(len(self.session.get_locks()), 2)
# Remove agent
self.session.remove_agent("FORGE")
# Verify locks released
self.assertEqual(len(self.session.get_locks()), 0)
def test_09_update_agent_status(self):
"""Test updating agent status."""
self.session.add_agent("BOLT", role="builder")
# Update status
success = self.session.update_agent_status("BOLT", AgentStatus.ACTIVE.value, "Building feature X")
self.assertTrue(success)
# Verify update
agents = self.session.get_agents()
self.assertEqual(agents[0].status, AgentStatus.ACTIVE.value)
self.assertEqual(agents[0].current_task, "Building feature X")
def test_10_get_agent_by_role(self):
"""Test retrieving agent by role."""
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
self.session.add_agent("ATLAS", role="tester")
# Get specific roles
planner = self.session.get_agent_by_role("planner")
self.assertIsNotNone(planner)
self.assertEqual(planner.agent_name, "FORGE")
builder = self.session.get_agent_by_role("builder")
self.assertEqual(builder.agent_name, "BOLT")
tester = self.session.get_agent_by_role("tester")
self.assertEqual(tester.agent_name, "ATLAS")
# Non-existent role
reviewer = self.session.get_agent_by_role("reviewer")
self.assertIsNone(reviewer)
def test_11_history_tracking(self):
"""Test session history is tracked."""
self.session.add_agent("FORGE", role="planner")
self.session.lock_resource("spec.md", "FORGE")
self.session.unlock_resource("spec.md")
# Get history
history = self.session.get_history()
# Should have: session_created, agent_joined, resource_locked, resource_unlocked
self.assertGreaterEqual(len(history), 4)
# Verify history entries have required fields
for entry in history:
self.assertIn("timestamp", entry)
self.assertIn("agent", entry)
self.assertIn("action", entry)
def test_12_session_status(self):
"""Test getting complete session status."""
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
self.session.lock_resource("code.py", "BOLT")
status = self.session.get_status()
# Verify all sections present
self.assertIn("session_id", status)
self.assertIn("status", status)
self.assertIn("agents", status)
self.assertIn("locks", status)
self.assertIn("recent_history", status)
# Verify counts
self.assertEqual(len(status["agents"]), 2)
self.assertEqual(len(status["locks"]), 1)
def test_13_complete_session(self):
"""Test marking session as complete."""
self.session.add_agent("FORGE", role="planner")
self.session.lock_resource("file.txt", "FORGE")
# Complete session
success = self.session.complete_session()
self.assertTrue(success)
# Verify status updated
status = self.session.get_status()
self.assertEqual(status["status"], SessionStatus.COMPLETED.value)
# Verify locks released
self.assertEqual(len(status["locks"]), 0)
# Verify agents marked done
for agent in status["agents"]:
self.assertEqual(agent["status"], AgentStatus.DONE.value)
def test_14_multiple_locks(self):
"""Test managing multiple resource locks."""
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
# Lock multiple resources
self.session.lock_resource("file1.py", "FORGE", "file")
self.session.lock_resource("file2.py", "BOLT", "file")
self.session.lock_resource("task_001", "FORGE", "task")
locks = self.session.get_locks()
self.assertEqual(len(locks), 3)
# Verify different resource types
file_locks = [l for l in locks if l.resource_type == "file"]
task_locks = [l for l in locks if l.resource_type == "task"]
self.assertEqual(len(file_locks), 2)
self.assertEqual(len(task_locks), 1)
def test_15_database_persistence(self):
"""Test that session persists across instances."""
# Add agents and locks
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
self.session.lock_resource("file.txt", "FORGE")
# Create new instance with same session_id and database
new_session = CollabSession(self.session_id, db_path=self.test_db)
# Verify data persisted
agents = new_session.get_agents()
self.assertEqual(len(agents), 2)
locks = new_session.get_locks()
self.assertEqual(len(locks), 1)
def test_16_list_sessions(self):
"""Test listing all sessions."""
# Create multiple sessions
session1 = CollabSession("session_001", db_path=self.test_db)
session2 = CollabSession("session_002", db_path=self.test_db)
session3 = CollabSession("session_003", db_path=self.test_db)
# List all sessions
sessions = list_sessions(db_path=self.test_db)
self.assertGreaterEqual(len(sessions), 3)
self.assertIn("session_001", sessions)
self.assertIn("session_002", sessions)
self.assertIn("session_003", sessions)
def test_17_workflow_simulation(self):
"""Test complete collaboration workflow."""
# Setup: Add agents with roles
self.session.add_agent("FORGE", role="planner")
self.session.add_agent("BOLT", role="builder")
self.session.add_agent("ATLAS", role="tester")
# Phase 1: Planning
self.session.lock_resource("spec.md", "FORGE")
self.session.update_agent_status("FORGE", AgentStatus.ACTIVE.value, "Writing specification")
# ... FORGE works ...
self.session.unlock_resource("spec.md")
self.session.update_agent_status("FORGE", AgentStatus.DONE.value)
# Phase 2: Building
self.session.notify_next_role("builder")
builder = self.session.get_agent_by_role("builder")
self.assertEqual(builder.status, AgentStatus.ACTIVE.value)
self.session.lock_resource("feature.py", "BOLT")
self.session.update_agent_status("BOLT", AgentStatus.ACTIVE.value, "Implementing feature")
# ... BOLT works ...
self.session.unlock_resource("feature.py")
self.session.update_agent_status("BOLT", AgentStatus.DONE.value)
# Phase 3: Testing
self.session.notify_next_role("tester")
tester = self.session.get_agent_by_role("tester")
self.assertEqual(tester.status, AgentStatus.ACTIVE.value)
self.session.lock_resource("test_feature.py", "ATLAS")
self.session.update_agent_status("ATLAS", AgentStatus.ACTIVE.value, "Testing feature")
# ... ATLAS works ...
self.session.unlock_resource("test_feature.py")
self.session.update_agent_status("ATLAS", AgentStatus.DONE.value)
# Complete session
self.session.complete_session()
# Verify workflow completed
status = self.session.get_status()
self.assertEqual(status["status"], SessionStatus.COMPLETED.value)
# Verify all agents done
for agent in status["agents"]:
self.assertEqual(agent["status"], AgentStatus.DONE.value)
# Verify history captured workflow
history = self.session.get_history(limit=100)
self.assertGreater(len(history), 10) # Many actions logged
def run_tests():
"""Run all tests."""
suite = unittest.TestLoader().loadTestsFromTestCase(TestCollabSession)
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
# Print summary
print("\n" + "="*70)
if result.wasSuccessful():
print(f"[SUCCESS] All {result.testsRun} tests passed!")
else:
print(f"[FAILED] {len(result.failures)} failures, {len(result.errors)} errors")
print("="*70)
return result.wasSuccessful()
if __name__ == "__main__":
import sys
success = run_tests()
sys.exit(0 if success else 1)