Skip to content

Testing

The AI Service has the most comprehensive test suite, covering real-world conversational scenarios.

Install dependencies (npm ci). Nothing else: the suite is hermetic — the API tests drive the exported Express app in process via supertest (tests/setup.ts), so no service has to be running and no host port is bound.

Terminal window
cd services/ai-service/dev/logrite-ai-service # in a MasterControl checkout
# Run all tests
npm test
# Verbose output
npm test -- --verbose
# Specific test file
npm test -- tests/api/health.test.ts
npm test -- tests/api/chat-scenarios.test.ts
# With coverage
npm test -- --coverage
SettingValue
FrameworkJest
Base URLhttp://aiservice.logrite.ai (or TEST_BASE_URL env var)
Timeout60 seconds (AI responses can be slow)
PrerequisitesService must be running
FileDescription
health.test.tsHealth endpoint returns 200 with correct body
conversations.test.tsConversation CRUD: create, list, get, delete
chat-scenarios.test.tsReal-world AI scenarios with tool calling
error-handling.test.tsInvalid requests, missing fields, error responses
CategoryExample
Semantic Search“Find payment timeout errors in the last hour”
Troubleshooting“Why is the analyzer service slow?”
Statistical Queries“How many database errors occurred today?”
Multi-turnContext retained across messages in a conversation
SSE StreamingEvent sequence: message_start → content_delta → message_end

Quick validation that all services are working:

health-check-all.sh
#!/bin/bash
check() {
local name=$1; local url=$2
local status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
[ "$status" = "200" ] && echo "✅ $name" || echo "❌ $name (HTTP $status)"
}
check "Backend" "http://localhost:8080/health"
check "Analyzer" "http://localhost:9000/health"
check "Semantic Search" "http://localhost:9100/health"
check "AI Service" "http://localhost:9300/health"
check "MCP Server" "http://localhost:9500/health"
check "Webhook Server" "http://localhost:9999/health"
check "OpenSearch" "http://localhost:9200/_cluster/health"

Terminal window
curl -X POST http://localhost:9100/api/v1/search \
-H "Content-Type: application/json" \
-d '{
"query": "payment timeout errors",
"k": 5
}'
Terminal window
curl -X POST http://localhost:9300/api/v1/chat/sync \
-H "Content-Type: application/json" \
-d '{
"message": "How many payment errors occurred today?",
"conversationId": null
}'
Terminal window
# Health
curl http://localhost:9500/health
# SSE endpoint (MCP handshake)
curl -N -H "Accept: text/event-stream" http://localhost:9500/sse
Terminal window
curl -X POST "http://localhost:9200/payment_queries_semantic/_search" \
-H "Content-Type: application/json" \
-d '{
"query": {
"neural": {
"text_embedding": {
"query_text": "payment timeout errors",
"model_id": "YOUR_MODEL_ID",
"k": 5
}
}
}
}'

Each private repo’s checks workflow (Analyzer CI in logrite-analyzer) runs that service’s gates on every push, on the self-hosted logrite-dev runners on the dev VM rather than on billed GitHub-hosted minutes — see CI runners. What each workflow runs is that repo’s own checks.yml; the commands above are the same gates by hand. A job stuck in Queued means a runner service is down (systemctl status 'actions.runner.*' on deployd-dev).

Two things deliberately stay off Actions: deploys, which go through the Coolify push webhook and build from source on the VM, and the quality harness, which is workflow_dispatch-only in harness-verify.yml with scripts/quality/run-harness.sh as the primary attended path.

Still manual: a health-check suite after a deploy completes.