Repository: fractal-analytics-platform/fractal-client (language: python)

Issue:
Prevent `httpx.ConnectError`s in CI
See e.g.
* https://github.com/fractal-analytics-platform/fractal/pull/493#issuecomment-1563963117
* https://github.com/fractal-analytics-platform/fractal/pull/495 

This can likely be fixed by adding more checks in the `testserver` fixture.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a95847658..4ab13ae46 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@
     * Fix a bug in tests, by starting the fractal-server FastAPI app in a more standard way (\#481).
     * Require pydantic version to be `>=1.10.8` (\#486, \#490).
     * Make `sqlmodel` a development depedency (\#493).
+    * Improve handling of a `ConnectError` in the CI (\#502).
 
 # 1.2.0
 


Test patch:
diff --git a/tests/fixtures_testserver.py b/tests/fixtures_testserver.py
index b1acff95e..1f54b9ea7 100644
--- a/tests/fixtures_testserver.py
+++ b/tests/fixtures_testserver.py
@@ -3,6 +3,7 @@
 from os import environ
 from typing import Optional
 
+import httpx
 import pytest
 
 
@@ -55,14 +56,16 @@ async def testserver(override_server_settings):
     logger.debug(DB.engine_sync().url)
     SQLModel.metadata.create_all(DB.engine_sync())
 
-    # Running testserver in a separate process
+    # Run testserver in a separate process
     # cf. https://stackoverflow.com/a/57816608/283972
 
+    PORT = 10080
+
     def run_server():
         asyncio.run(
             uvicorn.run(
                 "fractal_server.main:app",
-                port=10080,
+                port=PORT,
                 log_level="debug",
                 timeout_keep_alive=10,
             )
@@ -71,7 +74,24 @@ def run_server():
     proc = Process(target=run_server, args=(), daemon=True)
     proc.start()
 
-    time.sleep(2)  # NOTE required to let the server comes up
+    # Wait until the server is up
+    TIMEOUT = 8
+    time_used = 0
+    while True:
+        try:
+            res = httpx.get(f"http://localhost:{PORT}/api/alive/")
+            assert res.status_code == 200
+            break
+        except httpx.ConnectError:
+            logger.debug("Fractal server not ready, wait one more second.")
+            time.sleep(1)
+            time_used += 1
+            if time_used > TIMEOUT:
+                raise RuntimeError(
+                    f"Could not start up server within {TIMEOUT} seconds,"
+                    " in `testserver` fixture."
+                )
+
     logger.debug(environ["FRACTAL_SERVER"])
     yield environ["FRACTAL_SERVER"]
     proc.kill()