from __future__ import annotations import os import subprocess import sys from collections.abc import Callable from pathlib import Path from typing import TYPE_CHECKING from uuid import uuid4 import pytest from generalresearch.models.custom_types import PostgresDict from generalresearch.pg_helper import PostgresConfig, PostgresDsn from mypy_boto3_mturk import MTurkClient from pytest import TempPathFactory from jb.decorators import CLIENT_CONFIG from tests import generate_amt_id if TYPE_CHECKING: from jb.settings import Settings pytest_plugins = [ "test_utils.conftest", "tests.fixtures.amt", "tests.fixtures.flow", "tests.fixtures.http", "tests.fixtures.managers", "tests.fixtures.models", ] # --- IDs and Identifiers --- @pytest.fixture def amt_hit_id() -> str: return generate_amt_id() @pytest.fixture def amt_hit_type_id() -> str: return generate_amt_id() @pytest.fixture def amt_assignment_id() -> str: return generate_amt_id() @pytest.fixture def amt_worker_id() -> str: return generate_amt_id(length=21) @pytest.fixture def amt_group_id() -> str: return generate_amt_id() @pytest.fixture def tsid() -> str: return uuid4().hex @pytest.fixture def tsid1() -> str: return uuid4().hex @pytest.fixture def tsid2() -> str: return uuid4().hex @pytest.fixture def pe_id() -> str: # payout event / cashout request UUID return uuid4().hex # --- Settings --- @pytest.fixture(scope="session") def settings() -> Settings: from jb.settings import Settings as JBSettings return JBSettings() # --- Database Connectors --- @pytest.fixture(scope="session") def django_db_factory( postgres_instance: PostgresDsn, gr_repo: Callable[..., Path], django_settings_file: Callable[..., tuple[str, Path]], postgres_instance_dict: PostgresDict, tmp_path_factory: TempPathFactory, ) -> Callable[..., PostgresDsn | None]: _ran = {} def _inner( django_project: str = "generalresearch.thl_django", ) -> PostgresDsn | None: if _ran.get(django_project, False): print(f"Already ran django_db_factory:{django_project}") return postgres_instance _ran[django_project] = True _cwd = None _manage_path = "generalresearch.thl_django.app.manage" _settings_module, _settings_dir = django_settings_file( extra_installed_apps=[ "generalresearch.thl_django", ], ) pythonpath = str(_settings_dir) if existing_pythonpath := os.environ.get("PYTHONPATH"): pythonpath += os.pathsep + existing_pythonpath env = { **os.environ, "DJANGO_SETTINGS_MODULE": _settings_module, "PYTHONPATH": pythonpath, } # we check right after. if we check now, we won't print if bad res1 = subprocess.run( # noqa: PLW1510 [ sys.executable, "-m", _manage_path, "makemigrations", f"--settings={_settings_module}", ], cwd=str(_cwd) if _cwd is not None else None, env=env, capture_output=True, text=True, ) if res1.returncode != 0: print("STDOUT:", res1.stdout) print("STDERR:", res1.stderr) res1.check_returncode() res2 = subprocess.run( # noqa: PLW1510 [ sys.executable, "-m", _manage_path, "migrate", f"--settings={_settings_module}", ], env=env, cwd=str(_cwd) if _cwd is not None else None, capture_output=True, text=True, ) if res2.returncode != 0: print("STDOUT:", res2.stdout) print("STDERR:", res2.stderr) res2.check_returncode() # 3. Return the Dsn so the factory gives a way to connect return postgres_instance return _inner @pytest.fixture(scope="session") def pg_config(settings: Settings) -> PostgresConfig: return PostgresConfig( dsn=settings.amt_jb_db, connect_timeout=1, statement_timeout=1, ) # --- Redis --- @pytest.fixture(scope="session") def redis(settings: Settings): from generalresearch.redis_helper import RedisConfig redis_config = RedisConfig( dsn=settings.redis, decode_responses=True, socket_timeout=settings.redis_timeout, socket_connect_timeout=settings.redis_timeout, ) return redis_config.create_redis_client() # --- Connectors --- @pytest.fixture(scope="session") def amt_client(settings: Settings) -> MTurkClient: import boto3 client = boto3.client( service_name="mturk", region_name="us-east-1", endpoint_url=str(settings.amt_endpoint), aws_access_key_id=settings.amt_access_id, aws_secret_access_key=settings.amt_secret_key, config=CLIENT_CONFIG, ) # Confirm we're only using the Sandbox for any unittests assert "mturk-requester-sandbox" in client.meta.endpoint_url return client