@@ -12,11 +12,26 @@ class TestHubSystem:
1212 """Tests for Hub system operations."""
1313
1414 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 } " )
2035
2136 def test_hub_initialization (self , api_key , cocalc_host ):
2237 """Test Hub client initialization."""
@@ -31,11 +46,12 @@ def test_invalid_api_key(self, cocalc_host):
3146 with pytest .raises ((ValueError , RuntimeError , Exception )): # Should raise authentication error
3247 hub .system .ping ()
3348
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 )
3955
4056
4157class TestHubProjects :
@@ -50,8 +66,22 @@ def test_create_project(self, hub):
5066
5167 project_id = hub .projects .create_project (title = title , description = description )
5268
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 } " )
5585
5686 def test_list_projects (self , hub ):
5787 """Test listing projects."""
@@ -131,13 +161,19 @@ def test_project_lifecycle(self, hub):
131161 else :
132162 print ("5. Skipping command execution - project not ready" )
133163
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..." )
136172 delete_result = hub .projects .delete (project_id )
137- print (f" Delete result: { delete_result } " )
173+ print (f" ✓ Delete result: { delete_result } " )
138174
139175 # 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..." )
141177 projects = hub .projects .get (fields = ['project_id' , 'title' , 'deleted' ], project_id = project_id , all = True )
142178 assert len (projects ) == 1 , f"Expected 1 project (still in DB), found { len (projects )} "
143179 project = projects [0 ]
@@ -148,12 +184,16 @@ def test_project_lifecycle(self, hub):
148184 print ("✅ Project lifecycle test completed successfully!" )
149185
150186 except Exception as e :
151- # Cleanup: attempt to delete project if test fails
187+ # Cleanup: attempt to stop and delete project if test fails
152188 print (f"\n ❌ Test failed: { e } " )
153189 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" )
155195 hub .projects .delete (project_id )
156- print ("✓ Cleanup successful " )
196+ print ("✓ Project deleted " )
157197 except Exception as cleanup_error :
158198 print (f"❌ Cleanup failed: { cleanup_error } " )
159199 raise e
0 commit comments