syncstorage-rs/tools/integration_tests/conftest.py
Nick Shirley 6f15ad546d
Some checks are pending
Glean probe-scraper / glean-probe-scraper (push) Waiting to run
test(e2e): run integration and e2e tests with pytest (#1697)
- Update docker compose steps for mysql and spanner to use pytest
- Add infra and configuration for pytest to run tests
- Remove old "run.py" test setup

Closes STOR-235
2025-05-09 14:50:18 -06:00

163 lines
4.7 KiB
Python

import os
import psutil
import signal
import subprocess
import time
import pytest
import requests
import logging
DEBUG_BUILD = "target/debug/syncserver"
RELEASE_BUILD = "/app/bin/syncserver"
# max number of attempts to check server heartbeat
SYNC_SERVER_STARTUP_MAX_ATTEMPTS = 30
JWK_CACHE_DISABLED = os.environ.get("JWK_CACHE_DISABLED")
logger = logging.getLogger("tokenserver.scripts.conftest")
# Local setup for fixtures
def _terminate_process(process):
"""
Gracefully terminate the process and its children.
"""
proc = psutil.Process(pid=process.pid)
child_proc = proc.children(recursive=True)
for p in [proc] + child_proc:
os.kill(p.pid, signal.SIGTERM)
process.wait()
def _wait_for_server_startup(max_attempts=SYNC_SERVER_STARTUP_MAX_ATTEMPTS):
"""
Waits for the __heartbeat__ endpoint to return a 200, pausing for 1 second
between attempts. Raises a RuntimeError if the server does not start after
the specific number of attempts.
"""
itter = 0
while True:
if itter >= max_attempts:
raise RuntimeError(
"Server failed to start within the timeout period."
)
try:
req = requests.get("http://localhost:8000/__heartbeat__",
timeout=2)
if req.status_code == 200:
break
except requests.exceptions.RequestException as e:
logger.warning("Connection failed: %s", e)
time.sleep(1)
itter += 1
def _start_server():
"""
Starts the syncserver process, waits for it to be running,
and return the process handle.
"""
target_binary = None
if os.path.exists(DEBUG_BUILD):
target_binary = DEBUG_BUILD
elif os.path.exists(RELEASE_BUILD):
target_binary = RELEASE_BUILD
else:
raise RuntimeError(
"Neither {DEBUG_BUILD} nor {RELEASE_BUILD} were found."
)
server_proc = subprocess.Popen(
target_binary,
shell=True,
text=True,
env=os.environ,
)
_wait_for_server_startup()
return server_proc
def _server_manager():
"""
Context manager to gracefully start and stop the server.
"""
server_process = _start_server()
try:
yield server_process
finally:
_terminate_process(server_process)
def _set_local_test_env_vars():
"""
Set environment variables for local testing.
This function sets the necessary environment variables for the syncserver.
"""
os.environ.setdefault("SYNC_MASTER_SECRET", "secret0")
os.environ.setdefault("SYNC_CORS_MAX_AGE", "555")
os.environ.setdefault("SYNC_CORS_ALLOWED_ORIGIN", "*")
os.environ["MOZSVC_TEST_REMOTE"] = "localhost"
os.environ["SYNC_TOKENSERVER__FXA_OAUTH_SERVER_URL"] = \
os.environ["MOCK_FXA_SERVER_URL"]
# Fixtures
@pytest.fixture(scope="session")
def setup_server_local_testing():
"""
Fixture to set up the server for local testing.
This fixture sets the necessary environment variables and
starts the server.
"""
_set_local_test_env_vars()
yield from _server_manager()
@pytest.fixture(scope="session")
def setup_server_local_testing_with_oauth():
"""
Fixture to set up the server for local testing with OAuth.
This fixture sets the necessary environment variables and
starts the server.
"""
_set_local_test_env_vars()
# Set OAuth-specific environment variables
os.environ["TOKENSERVER_AUTH_METHOD"] = "oauth"
# Start the server
yield from _server_manager()
@pytest.fixture(scope="session")
def setup_server_end_to_end_testing():
"""
Fixture to set up the server for end-to-end testing.
This fixture sets the necessary environment variables and
starts the server.
"""
_set_local_test_env_vars()
# debatable if this should ONLY be here since it was only
# done against the "run_end_to_end_tests" prior, of if we
# just do it in _set_local_test_env_vars...
if JWK_CACHE_DISABLED:
del os.environ["SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__KTY"]
del os.environ["SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__ALG"]
del os.environ["SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__KID"]
del os.environ[
"SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__FXA_CREATED_AT"
]
del os.environ["SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__USE"]
del os.environ["SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__N"]
del os.environ["SYNC_TOKENSERVER__FXA_OAUTH_PRIMARY_JWK__E"]
# Set OAuth-specific environment variables
os.environ["SYNC_TOKENSERVER__FXA_OAUTH_SERVER_URL"] = \
"https://oauth.stage.mozaws.net"
# Start the server
yield from _server_manager()