Files
sol/dev/bootstrap.sh
Sienna Meridian Satterwhite 5dc739b800 feat: integration test suite — 416 tests, 61% coverage
Add OpenBao and Kratos to docker-compose dev stack with bootstrap
seeding. Full integration tests hitting real services:

- Vault SDK: KV read/write/delete, re-auth on bad token, new_with_token
  constructor for dev mode
- Kratos SDK: list/get/create/disable/enable users, session listing
- Token store: PAT lifecycle with OpenBao backing, expiry handling
- Identity tools: full tool dispatch through Kratos admin API
- Gitea SDK: resolve_username, ensure_token (PAT auto-provisioning),
  list/get repos, issues, comments, branches, file content
- Devtools: tool dispatch for all gitea_* tools against live Gitea
- Archive indexer: batch flush, periodic flush task, edit/redact/reaction
  updates against OpenSearch
- Memory store: set/query/get_recent with user scoping in OpenSearch
- Room history: context retrieval by timestamp and event_id, access
  control enforcement
- Search archive: keyword search with room/sender filters, room scoping
- Code search: language filter, repo filter, branch scoping
- Breadcrumbs: symbol retrieval, empty index handling, token budget
- Bridge: full event lifecycle mapping, request ID filtering
- Evaluator: DM/mention/silence short-circuits, LLM evaluation path,
  reply-to-human suppression
- Agent registry: list/get_id, prompt reuse, prompt-change recreation
- Conversations: token tracking, multi-turn context recall, room
  isolation

Bug fixes caught by tests:
- AgentRegistry in-memory cache skipped hash comparison on prompt change
- KratosClient::set_state sent bare PUT without traits (400 error)
- find_code_session returns None on NULL conversation_id
2026-03-24 14:34:03 +00:00

111 lines
4.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
## Bootstrap the local dev environment.
## Run after `docker compose -f docker-compose.dev.yaml up -d`
set -euo pipefail
HOMESERVER="http://localhost:8008"
USERNAME="sol"
PASSWORD="soldevpassword"
SERVER_NAME="sunbeam.local"
echo "Waiting for Tuwunel..."
until curl -sf "$HOMESERVER/_matrix/client/versions" > /dev/null 2>&1; do
sleep 1
done
echo "Tuwunel is ready."
echo "Registering @sol:$SERVER_NAME..."
RESPONSE=$(curl -s -X POST "$HOMESERVER/_matrix/client/v3/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$USERNAME\",
\"password\": \"$PASSWORD\",
\"auth\": {\"type\": \"m.login.dummy\"}
}")
ACCESS_TOKEN=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2>/dev/null || true)
DEVICE_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('device_id',''))" 2>/dev/null || true)
if [ -z "$ACCESS_TOKEN" ]; then
echo "Registration failed (user may already exist). Trying login..."
RESPONSE=$(curl -s -X POST "$HOMESERVER/_matrix/client/v3/login" \
-H "Content-Type: application/json" \
-d "{
\"type\": \"m.login.password\",
\"identifier\": {\"type\": \"m.id.user\", \"user\": \"$USERNAME\"},
\"password\": \"$PASSWORD\"
}")
ACCESS_TOKEN=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
DEVICE_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['device_id'])")
fi
# ── OpenBao: seed KV secrets engine ──────────────────────────────────────
OPENBAO="http://localhost:8200"
VAULT_TOKEN="dev-root-token"
echo ""
echo "Waiting for OpenBao..."
until curl -sf "$OPENBAO/v1/sys/health" >/dev/null 2>&1; do
sleep 1
done
echo "OpenBao is ready."
# Write a test secret for integration tests
echo "Seeding OpenBao KV..."
curl -sf -X POST "$OPENBAO/v1/secret/data/sol-test" \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":{"key":"test-secret-value","note":"seeded by bootstrap.sh"}}' \
> /dev/null 2>&1 && echo " ✓ secret/sol-test" || echo " sol-test (already exists or failed)"
# Write a test token path
curl -sf -X POST "$OPENBAO/v1/secret/data/sol-tokens/testuser/gitea" \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":{"token":"test-gitea-pat-12345","token_type":"pat","refresh_token":"","expires_at":""}}' \
> /dev/null 2>&1 && echo " ✓ secret/sol-tokens/testuser/gitea" || echo " token (already exists or failed)"
# ── Kratos: seed test identities ────────────────────────────────────────
KRATOS_ADMIN="http://localhost:4434"
echo ""
echo "Waiting for Kratos..."
until curl -sf "$KRATOS_ADMIN/admin/health/ready" >/dev/null 2>&1; do
sleep 1
done
echo "Kratos is ready."
echo "Seeding Kratos identities..."
curl -sf -X POST "$KRATOS_ADMIN/admin/identities" \
-H "Content-Type: application/json" \
-d '{"schema_id":"default","traits":{"email":"sienna@sunbeam.local","name":{"first":"Sienna","last":"V"}}}' \
> /dev/null 2>&1 && echo " ✓ sienna@sunbeam.local" || echo " sienna (already exists or failed)"
curl -sf -X POST "$KRATOS_ADMIN/admin/identities" \
-H "Content-Type: application/json" \
-d '{"schema_id":"default","traits":{"email":"lonni@sunbeam.local","name":{"first":"Lonni","last":"B"}}}' \
> /dev/null 2>&1 && echo " ✓ lonni@sunbeam.local" || echo " lonni (already exists or failed)"
curl -sf -X POST "$KRATOS_ADMIN/admin/identities" \
-H "Content-Type: application/json" \
-d '{"schema_id":"default","traits":{"email":"amber@sunbeam.local","name":{"first":"Amber","last":"K"}}}' \
> /dev/null 2>&1 && echo " ✓ amber@sunbeam.local" || echo " amber (already exists or failed)"
# ── Summary ─────────────────────────────────────────────────────────────
echo ""
echo "Add these to your .env or export them:"
echo ""
echo "export SOL_MATRIX_ACCESS_TOKEN=\"$ACCESS_TOKEN\""
echo "export SOL_MATRIX_DEVICE_ID=\"$DEVICE_ID\""
echo ""
echo "Services:"
echo " Tuwunel: $HOMESERVER"
echo " OpenBao: $OPENBAO (token: $VAULT_TOKEN)"
echo " Kratos: $KRATOS_ADMIN"
echo ""
echo "Then restart Sol: docker compose -f docker-compose.dev.yaml restart sol"