conftest.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # (c) Nelen & Schuurmans
  2. import asyncio
  3. import multiprocessing
  4. import os
  5. import time
  6. from urllib.error import URLError
  7. from urllib.request import urlopen
  8. import pytest
  9. import uvicorn
  10. def pytest_sessionstart(session):
  11. """
  12. Called after the Session object has been created and
  13. before performing collection and entering the run test loop.
  14. """
  15. if os.environ.get("DEBUG") or os.environ.get("DEBUG_WAIT_FOR_CLIENT"):
  16. from clean_python.testing.debugger import setup_debugger
  17. setup_debugger()
  18. @pytest.fixture(scope="session")
  19. def event_loop(request):
  20. """Create an instance of the default event loop per test session.
  21. Async fixtures need the event loop, and so must have the same or narrower scope than
  22. the event_loop fixture. Since we have async session-scoped fixtures, the default
  23. event_loop fixture, which has function scope, cannot be used. See:
  24. https://github.com/pytest-dev/pytest-asyncio#async-fixtures
  25. """
  26. loop = asyncio.get_event_loop_policy().new_event_loop()
  27. yield loop
  28. loop.close()
  29. @pytest.fixture(scope="session")
  30. async def postgres_url():
  31. return os.environ.get("POSTGRES_URL", "postgres:postgres@localhost:5432")
  32. @pytest.fixture(scope="session")
  33. async def s3_url():
  34. return os.environ.get("S3_URL", "http://localhost:9000")
  35. def wait_until_url_available(url: str, max_tries=10, interval=0.1):
  36. # wait for the server to be ready
  37. for _ in range(max_tries):
  38. try:
  39. urlopen(url)
  40. except URLError:
  41. time.sleep(interval)
  42. continue
  43. else:
  44. break
  45. @pytest.fixture(scope="session")
  46. async def fastapi_example_app():
  47. port = int(os.environ.get("API_PORT", "8005"))
  48. config = uvicorn.Config("fastapi_example:app", host="0.0.0.0", port=port)
  49. p = multiprocessing.Process(target=uvicorn.Server(config).run)
  50. p.start()
  51. try:
  52. wait_until_url_available(f"http://localhost:{port}/docs")
  53. yield f"http://localhost:{port}"
  54. finally:
  55. p.terminate()