@@ -12,11 +12,26 @@ class TestHubSystem:
12
12
"""Tests for Hub system operations."""
13
13
14
14
def test_ping (self , hub ):
15
- """Test basic ping connectivity."""
16
- result = hub .system .ping ()
17
- assert result is not None
18
- # The ping response should contain some basic server info
19
- assert isinstance (result , dict )
15
+ """Test basic ping connectivity with retry logic."""
16
+ # Retry with exponential backoff in case server is still starting up
17
+ max_attempts = 5
18
+ delay = 2 # Start with 2 second delay
19
+
20
+ for attempt in range (max_attempts ):
21
+ try :
22
+ result = hub .system .ping ()
23
+ assert result is not None
24
+ # The ping response should contain some basic server info
25
+ assert isinstance (result , dict )
26
+ print (f"✓ Server ping successful on attempt { attempt + 1 } " )
27
+ return # Success!
28
+ except Exception as e :
29
+ if attempt < max_attempts - 1 :
30
+ print (f"Ping attempt { attempt + 1 } failed, retrying in { delay } s... ({ e } )" )
31
+ time .sleep (delay )
32
+ delay *= 2 # Exponential backoff
33
+ else :
34
+ pytest .fail (f"Server ping failed after { max_attempts } attempts: { e } " )
20
35
21
36
def test_hub_initialization (self , api_key , cocalc_host ):
22
37
"""Test Hub client initialization."""
@@ -31,11 +46,12 @@ def test_invalid_api_key(self, cocalc_host):
31
46
with pytest .raises ((ValueError , RuntimeError , Exception )): # Should raise authentication error
32
47
hub .system .ping ()
33
48
34
- def test_ping_timeout (self , api_key , cocalc_host ):
35
- """Test ping with timeout parameter."""
36
- hub = Hub (api_key = api_key , host = cocalc_host )
37
- result = hub .system .ping ()
38
- assert result is not None
49
+ def test_multiple_pings (self , hub ):
50
+ """Test that multiple ping calls work consistently."""
51
+ for _i in range (3 ):
52
+ result = hub .system .ping ()
53
+ assert result is not None
54
+ assert isinstance (result , dict )
39
55
40
56
41
57
class TestHubProjects :
@@ -50,8 +66,22 @@ def test_create_project(self, hub):
50
66
51
67
project_id = hub .projects .create_project (title = title , description = description )
52
68
53
- assert project_id is not None
54
- assert_valid_uuid (project_id , "Project ID" )
69
+ try :
70
+ assert project_id is not None
71
+ assert_valid_uuid (project_id , "Project ID" )
72
+ print (f"✓ Created project: { project_id } " )
73
+ finally :
74
+ # Cleanup: stop then delete the project
75
+ try :
76
+ print (f"Cleaning up test project { project_id } ..." )
77
+ hub .projects .stop (project_id )
78
+ print ("✓ Project stop command sent" )
79
+ time .sleep (3 ) # Wait for process to terminate
80
+ print (f"✓ Waited for project { project_id } to stop" )
81
+ hub .projects .delete (project_id )
82
+ print (f"✓ Project { project_id } deleted" )
83
+ except Exception as e :
84
+ print (f"⚠ Failed to cleanup project { project_id } : { e } " )
55
85
56
86
def test_list_projects (self , hub ):
57
87
"""Test listing projects."""
@@ -131,13 +161,19 @@ def test_project_lifecycle(self, hub):
131
161
else :
132
162
print ("5. Skipping command execution - project not ready" )
133
163
134
- # 3. Delete the project
135
- print ("6. Deleting project..." )
164
+ # 3. Stop and delete the project
165
+ print ("6. Stopping project..." )
166
+ hub .projects .stop (project_id )
167
+ print (" ✓ Project stop command sent" )
168
+ time .sleep (3 ) # Wait for process to terminate
169
+ print (" ✓ Waited for project to stop" )
170
+
171
+ print ("7. Deleting project..." )
136
172
delete_result = hub .projects .delete (project_id )
137
- print (f" Delete result: { delete_result } " )
173
+ print (f" ✓ Delete result: { delete_result } " )
138
174
139
175
# 4. Verify project is marked as deleted in database
140
- print ("7 . Verifying project is marked as deleted..." )
176
+ print ("8 . Verifying project is marked as deleted..." )
141
177
projects = hub .projects .get (fields = ['project_id' , 'title' , 'deleted' ], project_id = project_id , all = True )
142
178
assert len (projects ) == 1 , f"Expected 1 project (still in DB), found { len (projects )} "
143
179
project = projects [0 ]
@@ -148,12 +184,16 @@ def test_project_lifecycle(self, hub):
148
184
print ("✅ Project lifecycle test completed successfully!" )
149
185
150
186
except Exception as e :
151
- # Cleanup: attempt to delete project if test fails
187
+ # Cleanup: attempt to stop and delete project if test fails
152
188
print (f"\n ❌ Test failed: { e } " )
153
189
try :
154
- print ("Attempting cleanup..." )
190
+ print ("Attempting cleanup: stopping then deleting project..." )
191
+ hub .projects .stop (project_id )
192
+ print ("✓ Project stop command sent" )
193
+ time .sleep (3 ) # Wait for process to terminate
194
+ print ("✓ Waited for project to stop" )
155
195
hub .projects .delete (project_id )
156
- print ("✓ Cleanup successful " )
196
+ print ("✓ Project deleted " )
157
197
except Exception as cleanup_error :
158
198
print (f"❌ Cleanup failed: { cleanup_error } " )
159
199
raise e
0 commit comments