import pytest import tempfile import subprocess import random import os import time import requests @pytest.fixture def temp(): """Write data to a temporary file and return the handle This is a fixture instead of a utility function so that temporary files have a test-scoped lifetime """ handles = [] def fun(data): handle = tempfile.NamedTemporaryFile(delete=False) if type(data) is str: data = data.encode("utf8") handle.write(data) handle.flush() handles.append(handle) return handle.name yield fun del handles # Useless but explicit @pytest.fixture(scope="module") def app(username, password): """Run an isolated application instance and return the URL""" data = tempfile.TemporaryDirectory() port = 5000 + random.randint(1, 999) # Port = 5XXX url = f"http://localhost:{port}" env = os.environ env.update(FLASK_APP="hiboo", SQLALCHEMY_DATABASE_URI=f"sqlite:///{data.name}/hiboo.db") subprocess.run(["flask", "db", "upgrade"], env=env) subprocess.run(["flask", "user", "create", username, password], env=env) subprocess.run(["flask", "user", "promote", username], env=env) proc = subprocess.Popen(["flask", "run", "-p", str(port)], env=env) # Wait for the server to be ready for _ in range(30): try: assert requests.get(url).status_code == 200 except Exception as e: print(e) time.sleep(1) else: yield url break proc.terminate() proc.wait() del data @pytest.fixture(scope="session") def username(): """Default username for tests""" return "admin" @pytest.fixture(scope="session") def password(): """Default password for tests""" return "admin" @pytest.fixture def service_name(): """A randomly generated service name""" return "Test service " + random.randbytes(3).hex()