Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 0 additions & 83 deletions .github/workflows/integration-tests.yml

This file was deleted.

145 changes: 12 additions & 133 deletions .github/workflows/robot-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
env:
DEEPGRAM_API_KEY: ${{ secrets.DEEPGRAM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HF_TOKEN: ${{ secrets.HF_TOKEN }}
run: |
echo "Verifying required secrets..."
if [ -z "$DEEPGRAM_API_KEY" ]; then
Expand All @@ -38,8 +39,13 @@ jobs:
echo "❌ ERROR: OPENAI_API_KEY secret is not set"
exit 1
fi
if [ -z "$HF_TOKEN" ]; then
echo "❌ ERROR: HF_TOKEN secret is not set"
exit 1
fi
echo "✓ DEEPGRAM_API_KEY is set (length: ${#DEEPGRAM_API_KEY})"
echo "✓ OPENAI_API_KEY is set (length: ${#OPENAI_API_KEY})"
echo "✓ HF_TOKEN is set (length: ${#HF_TOKEN})"
echo "✓ All required secrets verified"

- name: Set up Docker Buildx
Expand Down Expand Up @@ -71,28 +77,6 @@ jobs:
run: |
uv pip install --system robotframework robotframework-requests python-dotenv websockets

- name: Create test environment file
working-directory: tests/setup
run: |
cat > .env.test << EOF
# API URLs
API_URL=http://localhost:8001
BACKEND_URL=http://localhost:8001
FRONTEND_URL=http://localhost:3001

# Test Admin Credentials
ADMIN_EMAIL=test-admin@example.com
ADMIN_PASSWORD=test-admin-password-123

# API Keys (from GitHub secrets)
OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
DEEPGRAM_API_KEY=${{ secrets.DEEPGRAM_API_KEY }}

# Test Configuration
TEST_TIMEOUT=120
TEST_DEVICE_NAME=robot-test
EOF

- name: Create test config.yml
run: |
echo "Copying test configuration file..."
Expand All @@ -101,122 +85,17 @@ jobs:
echo "✓ Test config.yml created from tests/configs/deepgram-openai.yml"
ls -lh config/config.yml

- name: Start test environment
working-directory: backends/advanced
env:
DEEPGRAM_API_KEY: ${{ secrets.DEEPGRAM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_PROVIDER: openai
TRANSCRIPTION_PROVIDER: deepgram
MEMORY_PROVIDER: friend_lite
run: |
# Debug: Check if secrets are available
echo "Checking environment variables..."
echo "DEEPGRAM_API_KEY is set: $([ -n "$DEEPGRAM_API_KEY" ] && echo 'YES' || echo 'NO')"
echo "OPENAI_API_KEY is set: $([ -n "$OPENAI_API_KEY" ] && echo 'YES' || echo 'NO')"
echo "LLM_PROVIDER: $LLM_PROVIDER"
echo "TRANSCRIPTION_PROVIDER: $TRANSCRIPTION_PROVIDER"

# Clean any existing test containers for fresh start
echo "Cleaning up any existing test containers..."
docker compose -f docker-compose-test.yml down -v || true

# Start ALL services in parallel - Docker Compose handles dependencies via healthchecks
echo "Starting all services in parallel (docker-compose-test.yml)..."
echo "Note: Using test compose file with source mounts for faster startup"

# Export API keys so docker-compose can use them
export DEEPGRAM_API_KEY
export OPENAI_API_KEY
export LLM_PROVIDER
export TRANSCRIPTION_PROVIDER
export MEMORY_PROVIDER

DOCKER_BUILDKIT=0 docker compose -f docker-compose-test.yml up -d

# Show container status
echo "Container status:"
docker compose -f docker-compose-test.yml ps

# Single wait for backend readiness (backend depends_on ensures infra is ready)
echo "Waiting for backend readiness (up to 120s)..."
for i in {1..40}; do
if curl -s http://localhost:8001/readiness > /dev/null 2>&1; then
echo "✓ Backend is ready (all dependencies satisfied)"
break
fi
# Show logs every 10 attempts to help debug
if [ $((i % 10)) -eq 0 ]; then
echo "Still waiting... showing recent logs:"
docker compose -f docker-compose-test.yml logs --tail=20 chronicle-backend-test
fi
if [ $i -eq 40 ]; then
echo "✗ Backend failed to start - showing full logs:"
docker compose -f docker-compose-test.yml logs
exit 1
fi
echo "Attempt $i/40..."
sleep 3
done

echo "✓ Backend is ready!"

# Verify workers are registered with Redis (Robot tests need stable workers)
echo "Waiting for workers to register with Redis (up to 60s)..."
for i in {1..30}; do
WORKER_COUNT=$(docker compose -f docker-compose-test.yml exec -T workers-test uv run python -c 'from rq import Worker; from redis import Redis; import os; r = Redis.from_url(os.getenv("REDIS_URL", "redis://redis-test:6379/0")); print(len(Worker.all(connection=r)))' 2>/dev/null || echo "0")

if [ "$WORKER_COUNT" -ge 6 ]; then
echo "✓ Found $WORKER_COUNT workers registered"
# Show worker details
docker compose -f docker-compose-test.yml exec -T workers-test uv run python -c 'from rq import Worker; from redis import Redis; import os; r = Redis.from_url(os.getenv("REDIS_URL", "redis://redis-test:6379/0")); workers = Worker.all(connection=r); print(f"Total registered workers: {len(workers)}"); [print(f" - {w.name}: queues={w.queue_names()}, state={w.get_state()}") for w in workers]'
break
fi

if [ $i -eq 30 ]; then
echo "✗ Workers failed to register after 60s"
echo "Showing worker logs:"
docker compose -f docker-compose-test.yml logs --tail=50 workers-test
exit 1
fi

echo "Attempt $i/30: $WORKER_COUNT workers registered (waiting for 6+)..."
sleep 2
done

echo "✓ All services ready!"

- name: Verify checked out code
working-directory: tests
run: |
echo "Current git commit:"
git log -1 --oneline
echo ""
echo "Test files in current checkout:"
find . -name "*.robot" -type f | head -10
echo ""
echo "Sample of tags in test files:"
grep -h "\[Tags\]" endpoints/*.robot infrastructure/*.robot integration/*.robot 2>/dev/null | head -20 || echo "No tag files found"

- name: Clean previous test results
working-directory: tests
run: |
echo "Cleaning any previous test results..."
rm -rf results
mkdir -p results
echo "✓ Fresh results directory created"

- name: Run Robot Framework tests
working-directory: tests
env:
# Required for backend imports in test libraries
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_BASE_URL: https://api.openai.com/v1
OPENAI_MODEL: gpt-4o-mini
# Required for test runner script
DEEPGRAM_API_KEY: ${{ secrets.DEEPGRAM_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HF_TOKEN: ${{ secrets.HF_TOKEN }}
CLEANUP_CONTAINERS: "false" # Don't cleanup in CI - handled by workflow
run: |
# Run all tests (don't fail workflow to allow artifact upload)
make all OUTPUTDIR=results
# Use the unified test script that mirrors local development
./run-robot-tests.sh
TEST_EXIT_CODE=$?
echo "test_exit_code=$TEST_EXIT_CODE" >> $GITHUB_ENV
exit 0 # Don't fail here, we'll fail at the end after uploading artifacts
Expand Down
45 changes: 42 additions & 3 deletions backends/advanced/docker-compose-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ services:
- OPENMEMORY_USER_ID=${OPENMEMORY_USER_ID:-openmemory}
- MYCELIA_URL=http://mycelia-backend-test:5173
- MYCELIA_DB=mycelia_test
# Disable speaker recognition in test environment to prevent segment duplication
# Enable speaker recognition in test environment
- DISABLE_SPEAKER_RECOGNITION=false
- SPEAKER_SERVICE_URL=https://localhost:8085
- SPEAKER_SERVICE_URL=http://speaker-service-test:8085
- CORS_ORIGINS=http://localhost:3001,http://localhost:8001,https://localhost:3001,https://localhost:8001
# Set low inactivity timeout for tests (2 seconds instead of 60)
- SPEECH_INACTIVITY_THRESHOLD_SECONDS=2
Expand All @@ -54,6 +54,8 @@ services:
condition: service_healthy
redis-test:
condition: service_started
speaker-service-test:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/readiness"]
interval: 10s
Expand Down Expand Up @@ -119,6 +121,36 @@ services:
timeout: 3s
retries: 5

speaker-service-test:
build:
context: ../../extras/speaker-recognition
dockerfile: Dockerfile
args:
PYTORCH_CUDA_VERSION: cpu
image: speaker-recognition-test:latest
ports:
- "8086:8085" # Avoid conflict with dev speaker service on 8085
volumes:
- ../../extras/speaker-recognition/src:/app/src
- ../../extras/speaker-recognition/model_cache:/models
- ../../extras/speaker-recognition/audio_chunks:/app/audio_chunks
- ../../extras/speaker-recognition/debug:/app/debug
- ../../extras/speaker-recognition/speaker_data:/app/data
environment:
- HF_HOME=/models
- HF_TOKEN=${HF_TOKEN}
- SIMILARITY_THRESHOLD=0.15
- SPEAKER_SERVICE_HOST=0.0.0.0
- SPEAKER_SERVICE_PORT=8085
- DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8085/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
restart: unless-stopped

workers-test:
build:
context: .
Expand Down Expand Up @@ -151,7 +183,7 @@ services:
- MYCELIA_URL=http://mycelia-backend-test:5173
- MYCELIA_DB=mycelia_test
- DISABLE_SPEAKER_RECOGNITION=false
- SPEAKER_SERVICE_URL=https://localhost:8085
- SPEAKER_SERVICE_URL=http://speaker-service-test:8085
# Set low inactivity timeout for tests (2 seconds instead of 60)
- SPEECH_INACTIVITY_THRESHOLD_SECONDS=2
# Wait for audio queue to drain before timing out (test mode)
Expand All @@ -165,6 +197,8 @@ services:
condition: service_started
qdrant-test:
condition: service_started
speaker-service-test:
condition: service_healthy
restart: unless-stopped

# Mycelia - AI memory and timeline service (test environment)
Expand Down Expand Up @@ -237,6 +271,11 @@ services:
# condition: service_healthy
# restart: unless-stopped

# Use default bridge network for test isolation (no external network dependency)
networks:
default:
driver: bridge

# CI Considerations (for future implementation):
# - GitHub Actions can run these services in isolated containers
# - Port conflicts won't exist in CI since each job runs in isolation
Expand Down
8 changes: 4 additions & 4 deletions backends/advanced/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,8 @@ if [ ! -f "diarization_config.json" ] && [ -f "diarization_config.json.template"
print_success "diarization_config.json created"
fi

# Install dependencies with uv
print_info "Installing dependencies with uv..."
uv sync --dev --group test
# Note: Robot Framework dependencies are managed via tests/test-requirements.txt
# The integration tests use Docker containers for service dependencies

# Set up environment variables for testing
print_info "Setting up test environment variables..."
Expand Down Expand Up @@ -211,8 +210,9 @@ export DOCKER_BUILDKIT=0
export TEST_MODE=dev

# Run the Robot Framework integration tests with extended timeout (mem0 needs time for comprehensive extraction)
# IMPORTANT: Robot tests must be run from the repository root where backends/ and tests/ are siblings
print_info "Starting Robot Framework integration tests (timeout: 15 minutes)..."
if timeout 900 uv run robot --outputdir ../../test-results --loglevel INFO ../../tests/integration/integration_test.robot; then
if (cd ../.. && timeout 900 robot --outputdir test-results --loglevel INFO tests/integration/integration_test.robot); then
print_success "Integration tests completed successfully!"
else
TEST_EXIT_CODE=$?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,16 @@ async def initialize(self) -> None:
vector_ok = await self.vector_store.test_connection()

if not llm_ok:
raise RuntimeError("LLM provider connection failed")
raise RuntimeError(
f"LLM provider connection failed for {self.config.llm_provider.value}. "
f"Check API keys, network connectivity, and service availability. "
f"Memory processing cannot proceed without a working LLM connection."
)
if not vector_ok:
raise RuntimeError("Vector store connection failed")
raise RuntimeError(
f"Vector store connection failed for {self.config.vector_store_provider.value}. "
f"Check that Qdrant service is running and accessible."
)

self._initialized = True
memory_logger.info(
Expand Down
Loading
Loading