# ── Timmy Time — Test Stack ────────────────────────────────────────────────── # # Clean containers for test runs. Designed for fast iteration: # • Cached builder layers — only rebuilds when pyproject.toml changes # • Bind-mounted source — code changes are instant, no rebuild needed # • Ephemeral test-data — every run starts with clean state # # ── Profiles ──────────────────────────────────────────────────────────────── # (default) test runner only (unit + integration tests) # functional adds a live dashboard on port 18000 for HTTP-level tests # ollama adds containerised Ollama (CPU, qwen2.5:0.5b) for LLM tests # agents adds swarm agent workers for multi-agent tests # # ── Quick-start ───────────────────────────────────────────────────────────── # make test-docker # unit + integration in container # make test-docker ARGS="-k swarm" # filter tests # make test-docker-functional # full-stack functional tests # make test-docker-cov # with coverage report # # ── Manual usage ──────────────────────────────────────────────────────────── # docker compose -f docker-compose.test.yml run --rm test # docker compose -f docker-compose.test.yml run --rm test pytest tests/swarm -v # docker compose -f docker-compose.test.yml --profile functional up -d --wait # docker compose -f docker-compose.test.yml down -v services: # ── Test Runner ─────────────────────────────────────────────────────────── # Runs pytest in a clean container. Exits when tests complete. # Source and tests are bind-mounted so code changes don't require a rebuild. test: build: context: . dockerfile: docker/Dockerfile.test cache_from: - timmy-test:latest image: timmy-test:latest volumes: - ./src:/app/src:ro - ./tests:/app/tests:ro - ./static:/app/static:ro - ./hands:/app/hands:ro - ./docker:/app/docker:ro - ./Dockerfile:/app/Dockerfile:ro - ./docker-compose.yml:/app/docker-compose.yml:ro - ./docker-compose.dev.yml:/app/docker-compose.dev.yml:ro - ./docker-compose.prod.yml:/app/docker-compose.prod.yml:ro - ./docker-compose.test.yml:/app/docker-compose.test.yml:ro - ./docker-compose.microservices.yml:/app/docker-compose.microservices.yml:ro - ./pyproject.toml:/app/pyproject.toml:ro - test-data:/app/data environment: TIMMY_TEST_MODE: "1" LIGHTNING_BACKEND: "mock" PYTHONDONTWRITEBYTECODE: "1" networks: - test-net # Default command — override with: docker compose run --rm test pytest command: ["pytest", "tests/", "-q", "--tb=short"] # ── Dashboard — live server for functional tests ────────────────────────── # Activated with: --profile functional dashboard: build: context: . dockerfile: docker/Dockerfile.test cache_from: - timmy-test:latest image: timmy-test:latest profiles: - functional container_name: timmy-test-dashboard ports: - "18000:8000" volumes: - ./src:/app/src:ro - ./static:/app/static:ro - ./hands:/app/hands:ro - test-data:/app/data environment: DEBUG: "true" TIMMY_TEST_MODE: "1" OLLAMA_URL: "${OLLAMA_URL:-http://host.docker.internal:11434}" OLLAMA_MODEL: "${OLLAMA_MODEL:-llama3.2}" LIGHTNING_BACKEND: "mock" extra_hosts: - "host.docker.internal:host-gateway" networks: - test-net command: ["uvicorn", "dashboard.app:app", "--host", "0.0.0.0", "--port", "8000"] healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 5s timeout: 3s retries: 10 start_period: 10s # ── Ollama — local LLM for functional tests ────────────────────────────── # Activated with: --profile ollama # Uses a tiny model (qwen2.5:0.5b, ~400 MB) so it runs on CPU-only CI. ollama: image: ollama/ollama:latest container_name: timmy-test-ollama profiles: - ollama networks: - test-net healthcheck: test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"] interval: 5s timeout: 5s retries: 20 start_period: 10s # ── Agent — swarm worker for multi-agent tests ─────────────────────────── # Activated with: --profile agents # Scale: docker compose -f docker-compose.test.yml --profile agents up --scale agent=4 agent: build: context: . dockerfile: docker/Dockerfile.test cache_from: - timmy-test:latest image: timmy-test:latest profiles: - agents volumes: - ./src:/app/src:ro - ./hands:/app/hands:ro - test-data:/app/data environment: COORDINATOR_URL: "http://dashboard:8000" OLLAMA_URL: "${OLLAMA_URL:-http://host.docker.internal:11434}" OLLAMA_MODEL: "${OLLAMA_MODEL:-llama3.2}" AGENT_NAME: "${AGENT_NAME:-TestWorker}" AGENT_CAPABILITIES: "${AGENT_CAPABILITIES:-general}" TIMMY_TEST_MODE: "1" extra_hosts: - "host.docker.internal:host-gateway" command: >- sh -c "python -m swarm.agent_runner --agent-id agent-$$(hostname) --name $${AGENT_NAME:-TestWorker}" networks: - test-net depends_on: dashboard: condition: service_healthy # ── Ephemeral volume — destroyed with `docker compose down -v` ───────────── volumes: test-data: # ── Isolated test network ───────────────────────────────────────────────── networks: test-net: driver: bridge