mirror of https://github.com/sysown/proxysql
This commit migrates the ai TAP group from its legacy hook-based approach to the standard test/infra/ Unified CI Infrastructure pattern. Changes: - Added generic hook system to infrastructure scripts: * ensure-infras.bash: Executes group-specific setup-infras.bash hook * run-tests-isolated.bash: Executes group-specific pre-cleanup.bash hook - Migrated ai group infrastructure: * Created infras.lst with infra-mysql84 and docker-pgsql16-single * Renamed seed files: mysql-seed.sql -> seed-mysql.sql, pgsql-seed.sql -> seed-pgsql.sql * Deleted legacy docker-compose.yml, docker-compose-init.bash, docker-compose-destroy.bash * Deleted legacy hooks: pre-proxysql.bash, post-proxysql.bash - Added group-specific MCP configuration: * setup-infras.bash: Configures MCP targets and seeds test data * pre-cleanup.bash: Removes MCP configuration after tests * mcp-config.sql: SQL template for MCP setup * cleanup.sql: SQL template for MCP cleanup * seed-mysql.sql & seed-pgsql.sql: Test data for AI tests - Updated documentation in README.md with usage examples Architecture: - ai is the supergroup (defines infrastructure and shared config) - ai-g1, ai-g2, etc. are subgroups (define test sets in groups.json) - Group-specific hooks live in test/tap/groups/ai/ directory - Infrastructure scripts remain generic and delegate to group hookspull/5461/head
parent
0c4e0cae6a
commit
0b9806c46e
@ -0,0 +1,5 @@
|
||||
# AI-g1 Subgroup Environment Configuration
|
||||
# Sources the parent ai group configuration
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../ai/env.sh"
|
||||
@ -1,80 +1,172 @@
|
||||
# AI TAP Group Local Infra
|
||||
# AI TAP Group
|
||||
|
||||
This group supports running AI/MCP TAP tests with an isolated local backend infra, without relying on Jenkins helper repos.
|
||||
This group runs AI/MCP TAP tests using the **Unified CI Infrastructure** pattern, with isolated Docker network and automated infrastructure management.
|
||||
|
||||
## What it starts
|
||||
## Architecture
|
||||
|
||||
- MySQL 9.0 on `127.0.0.1:13306`
|
||||
- PostgreSQL 16 on `127.0.0.1:15432`
|
||||
The AI group uses the standard `test/infra/` pattern:
|
||||
|
||||
Both are started from `test/tap/groups/ai/docker-compose.yml`.
|
||||
- **MySQL Backend**: `infra-mysql84` (3-node MySQL 8.4 cluster with replication)
|
||||
- **PostgreSQL Backend**: `docker-pgsql16-single` (single PostgreSQL 16 instance)
|
||||
- **MCP Server**: Configured on port 6071 with MySQL and PostgreSQL targets
|
||||
- **Network**: Isolated Docker network `${INFRA_ID}_backend`
|
||||
|
||||
## Group hooks
|
||||
## Group Structure
|
||||
|
||||
- `pre-proxysql.bash`
|
||||
- starts local containers (`docker-compose-init.bash`)
|
||||
- seeds deterministic static-harvest datasets on both backends:
|
||||
- MySQL: `tap_mysql_static_customers`, `tap_mysql_static_orders`
|
||||
- PostgreSQL: `tap_pgsql_static_accounts`, `tap_pgsql_static_events`
|
||||
- enables MCP
|
||||
- configures backend hostgroups and MCP profiles/targets:
|
||||
- MySQL target: `tap_mysql_default`
|
||||
- PostgreSQL target: `tap_pgsql_default`
|
||||
- `post-proxysql.bash`
|
||||
- removes group-specific MCP profiles/targets/hostgroups
|
||||
- destroys local containers (`docker-compose-destroy.bash`)
|
||||
The `ai` group follows the **supergroup/subgroup** pattern:
|
||||
- `ai` is the supergroup (defines infrastructure and shared configuration)
|
||||
- `ai-g1`, `ai-g2`, etc. are subgroups (define specific test sets in `groups.json`)
|
||||
|
||||
## Manual run (without Jenkins)
|
||||
When running with `TAP_GROUP=ai-g1`, the system:
|
||||
1. Looks for `test/tap/groups/ai/infras.lst` (infrastructure requirements)
|
||||
2. Looks for `test/tap/groups/ai/env.sh` (environment configuration)
|
||||
3. Runs only tests tagged with `ai-g1` in `groups.json`
|
||||
|
||||
From repository root:
|
||||
## Infrastructure Files
|
||||
|
||||
```bash
|
||||
source test/tap/groups/ai/env.sh
|
||||
bash test/tap/groups/ai/pre-proxysql.bash
|
||||
# run your TAP tests here
|
||||
bash test/tap/groups/ai/post-proxysql.bash
|
||||
```
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `infras.lst` | Lists required infrastructures (`infra-mysql84`, `docker-pgsql16-single`) |
|
||||
| `env.sh` | Environment variables for MCP configuration |
|
||||
| `mcp-config.sql` | SQL template for MCP setup (variables substituted at runtime) |
|
||||
| `cleanup.sql` | SQL template for MCP cleanup after tests |
|
||||
| `seed-mysql.sql` | Test data for MySQL (seeded on mysql1, replicated to others) |
|
||||
| `seed-pgsql.sql` | Test data for PostgreSQL |
|
||||
| `setup-infras.bash` | **Group hook**: Configures MCP and seeds test data after infrastructure is ready |
|
||||
| `pre-cleanup.bash` | **Group hook**: Removes MCP configuration before test runner cleanup |
|
||||
|
||||
## MCP Configuration
|
||||
|
||||
The MCP (Model Context Protocol) is automatically configured with:
|
||||
|
||||
- **MySQL Target**: `tap_mysql_default` (hostgroup 9100)
|
||||
- **PostgreSQL Target**: `tap_pgsql_default` (hostgroup 9200)
|
||||
- **Port**: 6071 (SSL enabled)
|
||||
|
||||
Test data includes:
|
||||
- MySQL: `test.tap_mysql_static_customers`, `test.tap_mysql_static_orders`
|
||||
- PostgreSQL: `public.tap_pgsql_static_accounts`, `public.tap_pgsql_static_events`
|
||||
|
||||
For MCP query-rules suite:
|
||||
## Usage
|
||||
|
||||
### Running the Full AI Group
|
||||
|
||||
```bash
|
||||
source test/tap/groups/ai/env.sh
|
||||
bash test/tap/groups/ai/pre-proxysql.bash
|
||||
bash test/tap/tests/test_mcp_query_rules-t.sh
|
||||
bash test/tap/groups/ai/post-proxysql.bash
|
||||
# Set unique INFRA_ID to avoid conflicts with other runs
|
||||
export INFRA_ID="ai-test-$(date +%s)"
|
||||
export TAP_GROUP="ai-g1"
|
||||
export WORKSPACE=$(pwd)
|
||||
|
||||
# Source common environment
|
||||
source test/infra/common/env.sh
|
||||
|
||||
# Start infrastructure (ProxySQL + MySQL + PostgreSQL)
|
||||
./test/infra/control/ensure-infras.bash
|
||||
|
||||
# Run tests
|
||||
./test/infra/control/run-tests-isolated.bash
|
||||
|
||||
# Cleanup
|
||||
./test/infra/control/stop-proxysql-isolated.bash
|
||||
./test/infra/control/destroy-infras.bash
|
||||
```
|
||||
|
||||
For static-harvest phase-A suite (mysql + pgsql targets):
|
||||
### Running a Single Test
|
||||
|
||||
```bash
|
||||
source test/tap/groups/ai/env.sh
|
||||
bash test/tap/groups/ai/pre-proxysql.bash
|
||||
bash test/tap/tests/test_mcp_static_harvest-t.sh
|
||||
bash test/tap/groups/ai/post-proxysql.bash
|
||||
export INFRA_ID="ai-single-$(date +%s)"
|
||||
export TAP_GROUP="ai-g1"
|
||||
export TEST_PY_TAP_INCL="mcp_module-t"
|
||||
export WORKSPACE=$(pwd)
|
||||
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/ensure-infras.bash
|
||||
./test/infra/control/run-tests-isolated.bash
|
||||
./test/infra/control/stop-proxysql-isolated.bash
|
||||
./test/infra/control/destroy-infras.bash
|
||||
```
|
||||
|
||||
For phase-B MCP discovery primitives (agent/llm/catalog tools, CI-safe):
|
||||
### Running Specific MCP Test Suites
|
||||
|
||||
**MCP Static Harvest (MySQL + PostgreSQL):**
|
||||
```bash
|
||||
source test/tap/groups/ai/env.sh
|
||||
bash test/tap/groups/ai/pre-proxysql.bash
|
||||
bash test/tap/tests/test_mcp_llm_discovery_phaseb-t.sh
|
||||
bash test/tap/groups/ai/post-proxysql.bash
|
||||
export INFRA_ID="ai-harvest-$(date +%s)"
|
||||
export TAP_GROUP="ai-g1"
|
||||
export TEST_PY_TAP_INCL="test_mcp_static_harvest-t"
|
||||
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/ensure-infras.bash
|
||||
./test/infra/control/run-tests-isolated.bash
|
||||
./test/infra/control/stop-proxysql-isolated.bash
|
||||
./test/infra/control/destroy-infras.bash
|
||||
```
|
||||
|
||||
For Claude headless flow smoke (dry-run + optional real Claude execution):
|
||||
**MCP Discovery Phase B:**
|
||||
```bash
|
||||
export INFRA_ID="ai-discovery-$(date +%s)"
|
||||
export TAP_GROUP="ai-g1"
|
||||
export TEST_PY_TAP_INCL="test_mcp_llm_discovery_phaseb-t"
|
||||
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/ensure-infras.bash
|
||||
./test/infra/control/run-tests-isolated.bash
|
||||
./test/infra/control/stop-proxysql-isolated.bash
|
||||
./test/infra/control/destroy-infras.bash
|
||||
```
|
||||
|
||||
**Claude Headless Flow:**
|
||||
```bash
|
||||
source test/tap/groups/ai/env.sh
|
||||
bash test/tap/groups/ai/pre-proxysql.bash
|
||||
bash test/tap/tests/test_mcp_claude_headless_flow-t.sh
|
||||
# Optional real run:
|
||||
# TAP_RUN_REAL_CLAUDE=1 TAP_CLAUDE_MCP_CONFIG=./scripts/mcp/DiscoveryAgent/ClaudeCode_Headless/mcp_config.json \
|
||||
# bash test/tap/tests/test_mcp_claude_headless_flow-t.sh
|
||||
bash test/tap/groups/ai/post-proxysql.bash
|
||||
export INFRA_ID="ai-claude-$(date +%s)"
|
||||
export TAP_GROUP="ai-g1"
|
||||
export TEST_PY_TAP_INCL="test_mcp_claude_headless_flow-t"
|
||||
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/ensure-infras.bash
|
||||
./test/infra/control/run-tests-isolated.bash
|
||||
./test/infra/control/stop-proxysql-isolated.bash
|
||||
./test/infra/control/destroy-infras.bash
|
||||
|
||||
# Optional: Run with real Claude execution
|
||||
# export TAP_RUN_REAL_CLAUDE=1
|
||||
# export TAP_CLAUDE_MCP_CONFIG=./scripts/mcp/DiscoveryAgent/ClaudeCode_Headless/mcp_config.json
|
||||
```
|
||||
|
||||
## Test Categories
|
||||
|
||||
Tests included in the AI group (defined in `groups.json`):
|
||||
|
||||
- **AI Module Tests**: `ai_validation-t`, `ai_error_handling_edge_cases-t`, `ai_llm_retry_scenarios-t`
|
||||
- **Anomaly Detection**: `anomaly_detection-t`, `anomaly_detector_unit-t`, `anomaly_detection_integration-t`
|
||||
- **GenAI Tests**: `genai_module-t`, `genai_async-t`, `genai_embedding_rerank-t`, `genai_live_validation-t`
|
||||
- **MCP Tests**: `mcp_module-t`, `mcp_query_rules-t`, `mcp_stats_refresh-t`, `mcp_semantic_lifecycle-t`, etc.
|
||||
- **NL2SQL Tests**: `nl2sql_integration-t`, `nl2sql_prompt_builder-t`, `nl2sql_model_selection-t`, etc.
|
||||
- **Vector Tests**: `vector_features-t`, `vector_db_performance-t`
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `TAP_MCPPORT` | 6071 | MCP server port |
|
||||
| `MCP_TARGET_ID` | tap_mysql_default | MySQL MCP target ID |
|
||||
| `MCP_PGSQL_TARGET_ID` | tap_pgsql_default | PostgreSQL MCP target ID |
|
||||
| `MCP_MYSQL_HOSTGROUP_ID` | 9100 | MySQL hostgroup for MCP |
|
||||
| `MCP_PGSQL_HOSTGROUP_ID` | 9200 | PostgreSQL hostgroup for MCP |
|
||||
| `TEST_PY_TAP_INCL` | (see env.sh) | Test filter pattern |
|
||||
|
||||
## Notes
|
||||
|
||||
- All variables can be overridden from the environment before running hooks.
|
||||
- The scripts still work in Jenkins-driven TAP flows because they do not require Jenkins-only paths.
|
||||
- All containers run on an isolated Docker network (`${INFRA_ID}_backend`)
|
||||
- MySQL replication automatically propagates seed data from mysql1 to mysql2/mysql3
|
||||
- MCP configuration is applied by the group-specific `setup-infras.bash` hook and cleaned up by `pre-cleanup.bash`
|
||||
- The `INFRA_ID` must be unique for each test run to avoid conflicts
|
||||
|
||||
## Group-Specific Hooks
|
||||
|
||||
The AI group uses the generic hook system provided by the Unified CI Infrastructure:
|
||||
|
||||
| Hook | Executed By | Purpose |
|
||||
|------|-------------|---------|
|
||||
| `setup-infras.bash` | `ensure-infras.bash` after backends start | Configures MCP, seeds test data |
|
||||
| `pre-cleanup.bash` | `run-tests-isolated.bash` before cleanup | Removes MCP configuration |
|
||||
|
||||
These hooks are group-specific and live in the `test/tap/groups/ai/` directory. They are discovered and executed automatically by the infrastructure scripts based on `TAP_GROUP`.
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
-- AI Group MCP Cleanup
|
||||
-- Removes MCP configuration after tests complete
|
||||
-- Variables are substituted using envsubst before execution
|
||||
|
||||
DELETE FROM mcp_target_profiles WHERE target_id IN ('${MCP_TARGET_ID}', '${MCP_PGSQL_TARGET_ID}');
|
||||
DELETE FROM mcp_auth_profiles WHERE auth_profile_id IN ('${MCP_AUTH_PROFILE_ID}', '${MCP_PGSQL_AUTH_PROFILE_ID}');
|
||||
LOAD MCP PROFILES TO RUNTIME;
|
||||
SAVE MCP PROFILES TO DISK;
|
||||
|
||||
DELETE FROM mysql_servers WHERE hostgroup_id IN (${MCP_MYSQL_HOSTGROUP_ID});
|
||||
DELETE FROM pgsql_servers WHERE hostgroup_id IN (${MCP_PGSQL_HOSTGROUP_ID});
|
||||
LOAD MYSQL SERVERS TO RUNTIME;
|
||||
SAVE MYSQL SERVERS TO DISK;
|
||||
LOAD PGSQL SERVERS TO RUNTIME;
|
||||
SAVE PGSQL SERVERS TO DISK;
|
||||
@ -1,23 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o pipefail
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose -f "${COMPOSE_FILE}" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose -f "${COMPOSE_FILE}" "$@"
|
||||
else
|
||||
echo "[ERROR] docker compose is not available" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo "[INFO] Stopping AI TAP group backend containers..."
|
||||
compose down -v --remove-orphans
|
||||
echo "[INFO] AI TAP group backend containers removed"
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o pipefail
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose -f "${COMPOSE_FILE}" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose -f "${COMPOSE_FILE}" "$@"
|
||||
else
|
||||
echo "[ERROR] docker compose is not available" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_health() {
|
||||
local service="$1"
|
||||
local max_wait="${2:-180}"
|
||||
local waited=0
|
||||
local cid
|
||||
cid="$(compose ps -q "${service}")"
|
||||
if [ -z "${cid}" ]; then
|
||||
echo "[ERROR] Service '${service}' has no running container" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while [ "${waited}" -lt "${max_wait}" ]; do
|
||||
local status
|
||||
status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "${cid}" 2>/dev/null || true)"
|
||||
if [ "${status}" = "healthy" ] || [ "${status}" = "running" ]; then
|
||||
echo "[INFO] ${service} status=${status}"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
waited=$((waited + 2))
|
||||
done
|
||||
|
||||
echo "[ERROR] Timeout waiting for service '${service}' to become healthy" >&2
|
||||
compose ps
|
||||
compose logs --tail 100 "${service}" || true
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "[INFO] Starting AI TAP group backend containers..."
|
||||
compose up -d --remove-orphans
|
||||
|
||||
wait_for_health mysql90 240
|
||||
wait_for_health pgsql 240
|
||||
|
||||
echo "[INFO] AI TAP group backend containers are ready"
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
services:
|
||||
mysql90:
|
||||
image: mysql:9.0
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: testdb
|
||||
ports:
|
||||
- "13306:3306"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "mysqladmin ping -h127.0.0.1 -uroot -prootpass --silent"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 40
|
||||
|
||||
pgsql:
|
||||
image: postgres:16
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: testdb
|
||||
ports:
|
||||
- "15432:5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -d testdb -h 127.0.0.1"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 40
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
export TEST_PY_TAP_INCL="ai_.*-t anomaly_.*-t genai.*-t mcp.*-t nl2sql_.*-t test_mcp.*-t vector.*-t"
|
||||
# AI TAP Group Environment Configuration
|
||||
# Defines the primary targets for AI/MCP tests using standard test/infra/ pattern
|
||||
|
||||
# Local AI group backend defaults (used by MCP TAP tests).
|
||||
# These variables can be overridden by the runner environment.
|
||||
export TAP_MYSQLHOST="${TAP_MYSQLHOST:-127.0.0.1}"
|
||||
export TAP_MYSQLPORT="${TAP_MYSQLPORT:-13306}"
|
||||
export TAP_MYSQLUSERNAME="${TAP_MYSQLUSERNAME:-root}"
|
||||
export TAP_MYSQLPASSWORD="${TAP_MYSQLPASSWORD:-rootpass}"
|
||||
export TEST_DB_NAME="${TEST_DB_NAME:-testdb}"
|
||||
export DEFAULT_MYSQL_INFRA="infra-mysql84"
|
||||
export DEFAULT_PGSQL_INFRA="docker-pgsql16-single"
|
||||
|
||||
# MCP-specific environment variables for AI tests
|
||||
export TAP_MCPPORT="${TAP_MCPPORT:-6071}"
|
||||
export MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
|
||||
export MCP_AUTH_PROFILE_ID="${MCP_AUTH_PROFILE_ID:-tap_mysql_auth}"
|
||||
export MCP_PGSQL_TARGET_ID="${MCP_PGSQL_TARGET_ID:-tap_pgsql_default}"
|
||||
export MCP_PGSQL_AUTH_PROFILE_ID="${MCP_PGSQL_AUTH_PROFILE_ID:-tap_pgsql_auth}"
|
||||
export MCP_MYSQL_HOSTGROUP_ID="${MCP_MYSQL_HOSTGROUP_ID:-9100}"
|
||||
export MCP_PGSQL_HOSTGROUP_ID="${MCP_PGSQL_HOSTGROUP_ID:-9200}"
|
||||
|
||||
# Test data database name
|
||||
export MYSQL_DATABASE="${MYSQL_DATABASE:-test}"
|
||||
export PGSQL_DATABASE="${PGSQL_DATABASE:-postgres}"
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
infra-mysql84
|
||||
docker-pgsql16-single
|
||||
@ -0,0 +1,56 @@
|
||||
-- AI Group MCP Configuration
|
||||
-- This SQL is executed by the test runner to configure MCP for AI tests
|
||||
-- Variables are substituted using envsubst before execution
|
||||
|
||||
-- Configure MCP variables
|
||||
SET mcp-port='${TAP_MCPPORT}';
|
||||
SET mcp-use_ssl='true';
|
||||
SET mcp-enabled='false';
|
||||
LOAD MCP VARIABLES TO RUNTIME;
|
||||
SAVE MCP VARIABLES TO DISK;
|
||||
|
||||
-- Configure MySQL servers for MCP
|
||||
DELETE FROM mysql_servers WHERE hostgroup_id IN (0, ${MCP_MYSQL_HOSTGROUP_ID});
|
||||
INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, weight, comment)
|
||||
VALUES (0, '${TAP_MYSQLHOST}', ${TAP_MYSQLPORT}, 'ONLINE', 1, 'ai local mysql');
|
||||
INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, weight, comment)
|
||||
VALUES (${MCP_MYSQL_HOSTGROUP_ID}, '${TAP_MYSQLHOST}', ${TAP_MYSQLPORT}, 'ONLINE', 1, 'ai mcp mysql');
|
||||
LOAD MYSQL SERVERS TO RUNTIME;
|
||||
SAVE MYSQL SERVERS TO DISK;
|
||||
|
||||
-- Configure PostgreSQL servers for MCP
|
||||
DELETE FROM pgsql_servers WHERE hostgroup_id IN (${MCP_PGSQL_HOSTGROUP_ID});
|
||||
INSERT INTO pgsql_servers (hostgroup_id, hostname, port, status, weight, comment)
|
||||
VALUES (${MCP_PGSQL_HOSTGROUP_ID}, '${TAP_PGSQLSERVER_HOST}', ${TAP_PGSQLSERVER_PORT}, 'ONLINE', 1, 'ai mcp pgsql');
|
||||
LOAD PGSQL SERVERS TO RUNTIME;
|
||||
SAVE PGSQL SERVERS TO DISK;
|
||||
|
||||
-- Configure frontend users for TAP tests
|
||||
INSERT OR IGNORE INTO mysql_users (username, password, active, default_hostgroup, comment)
|
||||
VALUES ('${TAP_MYSQLUSERNAME}', '${TAP_MYSQLPASSWORD}', 1, 0, 'ai local');
|
||||
INSERT OR IGNORE INTO mysql_users (username, password, active, default_hostgroup, comment)
|
||||
VALUES ('testuser', 'testuser', 1, 0, 'ai local');
|
||||
LOAD MYSQL USERS TO RUNTIME;
|
||||
SAVE MYSQL USERS TO DISK;
|
||||
|
||||
-- Configure MCP auth profiles
|
||||
DELETE FROM mcp_auth_profiles WHERE auth_profile_id IN ('${MCP_AUTH_PROFILE_ID}', '${MCP_PGSQL_AUTH_PROFILE_ID}');
|
||||
INSERT INTO mcp_auth_profiles (auth_profile_id, db_username, db_password, default_schema, use_ssl, ssl_mode, comment)
|
||||
VALUES ('${MCP_AUTH_PROFILE_ID}', '${TAP_MYSQLUSERNAME}', '${TAP_MYSQLPASSWORD}', '${MYSQL_DATABASE}', 0, '', 'ai mysql mcp auth');
|
||||
INSERT INTO mcp_auth_profiles (auth_profile_id, db_username, db_password, default_schema, use_ssl, ssl_mode, comment)
|
||||
VALUES ('${MCP_PGSQL_AUTH_PROFILE_ID}', '${TAP_PGSQLSERVER_USERNAME}', '${TAP_PGSQLSERVER_PASSWORD}', '${PGSQL_DATABASE}', 0, '', 'ai pgsql mcp auth');
|
||||
|
||||
-- Configure MCP target profiles
|
||||
DELETE FROM mcp_target_profiles WHERE target_id IN ('${MCP_TARGET_ID}', '${MCP_PGSQL_TARGET_ID}');
|
||||
INSERT INTO mcp_target_profiles (target_id, protocol, hostgroup_id, auth_profile_id, description, max_rows, timeout_ms, allow_explain, allow_discovery, active, comment)
|
||||
VALUES ('${MCP_TARGET_ID}', 'mysql', ${MCP_MYSQL_HOSTGROUP_ID}, '${MCP_AUTH_PROFILE_ID}', 'AI local MySQL target', 200, 5000, 1, 1, 1, 'ai local');
|
||||
INSERT INTO mcp_target_profiles (target_id, protocol, hostgroup_id, auth_profile_id, description, max_rows, timeout_ms, allow_explain, allow_discovery, active, comment)
|
||||
VALUES ('${MCP_PGSQL_TARGET_ID}', 'pgsql', ${MCP_PGSQL_HOSTGROUP_ID}, '${MCP_PGSQL_AUTH_PROFILE_ID}', 'AI local PostgreSQL target', 200, 5000, 1, 1, 1, 'ai local');
|
||||
|
||||
LOAD MCP PROFILES TO RUNTIME;
|
||||
SAVE MCP PROFILES TO DISK;
|
||||
|
||||
-- Enable MCP
|
||||
SET mcp-enabled='true';
|
||||
LOAD MCP VARIABLES TO RUNTIME;
|
||||
SAVE MCP VARIABLES TO DISK;
|
||||
@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o pipefail
|
||||
#
|
||||
# AI TAP group post-hook:
|
||||
# - cleans MCP targets/profiles created by pre-hook
|
||||
# - removes isolated compose containers
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
|
||||
MCP_AUTH_PROFILE_ID="${MCP_AUTH_PROFILE_ID:-tap_mysql_auth}"
|
||||
MCP_PGSQL_TARGET_ID="${MCP_PGSQL_TARGET_ID:-tap_pgsql_default}"
|
||||
MCP_PGSQL_AUTH_PROFILE_ID="${MCP_PGSQL_AUTH_PROFILE_ID:-tap_pgsql_auth}"
|
||||
MCP_MYSQL_HOSTGROUP_ID="${MCP_MYSQL_HOSTGROUP_ID:-9100}"
|
||||
MCP_PGSQL_HOSTGROUP_ID="${MCP_PGSQL_HOSTGROUP_ID:-9200}"
|
||||
|
||||
ADMIN_HOST="${TAP_ADMINHOST:-127.0.0.1}"
|
||||
ADMIN_PORT="${TAP_ADMINPORT:-6032}"
|
||||
ADMIN_USER="${TAP_ADMINUSERNAME:-radmin}"
|
||||
ADMIN_PASS="${TAP_ADMINPASSWORD:-radmin}"
|
||||
|
||||
if [[ $(mysql --skip-ssl-verify-server-cert -h 2>&1) =~ skip-ssl-verify-server-cert ]]; then
|
||||
SSLOPT=--skip-ssl-verify-server-cert
|
||||
else
|
||||
SSLOPT=
|
||||
fi
|
||||
|
||||
exec_admin() {
|
||||
mysql ${SSLOPT} -h"${ADMIN_HOST}" -P"${ADMIN_PORT}" -u"${ADMIN_USER}" -p"${ADMIN_PASS}" -e "$1" 2>&1 | sed '/^mysql: .*Warning/d'
|
||||
}
|
||||
|
||||
try_admin() {
|
||||
if ! exec_admin "$1"; then
|
||||
echo "[WARN] admin cleanup statement failed: $1" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
echo "[INFO] AI post-hook: cleaning ProxySQL MCP/group-specific config"
|
||||
|
||||
try_admin "DELETE FROM mcp_target_profiles WHERE target_id IN ('${MCP_TARGET_ID}', '${MCP_PGSQL_TARGET_ID}');"
|
||||
try_admin "DELETE FROM mcp_auth_profiles WHERE auth_profile_id IN ('${MCP_AUTH_PROFILE_ID}', '${MCP_PGSQL_AUTH_PROFILE_ID}');"
|
||||
try_admin "LOAD MCP PROFILES TO RUNTIME; SAVE MCP PROFILES TO DISK;"
|
||||
|
||||
try_admin "DELETE FROM mysql_servers WHERE hostgroup_id IN (${MCP_MYSQL_HOSTGROUP_ID});"
|
||||
try_admin "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
|
||||
try_admin "DELETE FROM pgsql_servers WHERE hostgroup_id IN (${MCP_PGSQL_HOSTGROUP_ID});"
|
||||
try_admin "LOAD PGSQL SERVERS TO RUNTIME; SAVE PGSQL SERVERS TO DISK;"
|
||||
|
||||
echo "[INFO] AI post-hook: destroying group-local containers"
|
||||
"${SCRIPT_DIR}/docker-compose-destroy.bash"
|
||||
|
||||
echo "[INFO] AI post-hook completed"
|
||||
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
set -uo pipefail
|
||||
#
|
||||
# AI TAP Group Pre-Cleanup Hook
|
||||
# Executed by run-tests-isolated.bash before test runner cleanup
|
||||
# Removes MCP configuration from ProxySQL
|
||||
#
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Check required environment variables
|
||||
if [ -z "${INFRA_ID:-}" ]; then
|
||||
echo "WARNING: INFRA_ID is not set, skipping MCP cleanup"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "${WORKSPACE:-}" ]; then
|
||||
echo "WARNING: WORKSPACE is not set, skipping MCP cleanup"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
export ROOT_PASSWORD=$(echo -n "${INFRA_ID}" | sha256sum | head -c 10)
|
||||
PROXY_CONTAINER="proxysql.${INFRA_ID}"
|
||||
|
||||
# Check if ProxySQL container is running
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${PROXY_CONTAINER}$"; then
|
||||
echo ">>> AI pre-cleanup hook: ProxySQL container not running, skipping cleanup"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Set MCP-specific environment variables (with defaults)
|
||||
export MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
|
||||
export MCP_AUTH_PROFILE_ID="${MCP_AUTH_PROFILE_ID:-tap_mysql_auth}"
|
||||
export MCP_PGSQL_TARGET_ID="${MCP_PGSQL_TARGET_ID:-tap_pgsql_default}"
|
||||
export MCP_PGSQL_AUTH_PROFILE_ID="${MCP_PGSQL_AUTH_PROFILE_ID:-tap_pgsql_auth}"
|
||||
export MCP_MYSQL_HOSTGROUP_ID="${MCP_MYSQL_HOSTGROUP_ID:-9100}"
|
||||
export MCP_PGSQL_HOSTGROUP_ID="${MCP_PGSQL_HOSTGROUP_ID:-9200}"
|
||||
|
||||
echo ">>> AI pre-cleanup hook: Removing MCP configuration..."
|
||||
|
||||
CLEANUP_SQL="${SCRIPT_DIR}/cleanup.sql"
|
||||
if [ -f "${CLEANUP_SQL}" ]; then
|
||||
if command -v envsubst >/dev/null 2>&1; then
|
||||
envsubst < "${CLEANUP_SQL}" | docker exec -i "${PROXY_CONTAINER}" mysql -uradmin -pradmin -h127.0.0.1 -P6032 2>/dev/null || true
|
||||
else
|
||||
# Fallback: use bash variable expansion
|
||||
bash -c "cat <<EOF
|
||||
$(cat "${CLEANUP_SQL}")
|
||||
EOF" | docker exec -i "${PROXY_CONTAINER}" mysql -uradmin -pradmin -h127.0.0.1 -P6032 2>/dev/null || true
|
||||
fi
|
||||
echo ">>> MCP cleanup completed"
|
||||
else
|
||||
echo ">>> WARNING: Cleanup SQL not found at ${CLEANUP_SQL}"
|
||||
fi
|
||||
@ -1,135 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o pipefail
|
||||
#
|
||||
# AI TAP group pre-hook:
|
||||
# - starts isolated mysql90 + pgsql containers (group-local compose)
|
||||
# - configures ProxySQL MCP variables, backends, and MCP profiles/targets
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# TAP defaults (can be overridden by environment).
|
||||
TAP_MYSQLHOST="${TAP_MYSQLHOST:-127.0.0.1}"
|
||||
TAP_MYSQLPORT="${TAP_MYSQLPORT:-13306}"
|
||||
TAP_MYSQLUSERNAME="${TAP_MYSQLUSERNAME:-root}"
|
||||
TAP_MYSQLPASSWORD="${TAP_MYSQLPASSWORD:-rootpass}"
|
||||
TEST_DB_NAME="${TEST_DB_NAME:-testdb}"
|
||||
TAP_MCPPORT="${TAP_MCPPORT:-6071}"
|
||||
MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
|
||||
MCP_AUTH_PROFILE_ID="${MCP_AUTH_PROFILE_ID:-tap_mysql_auth}"
|
||||
MCP_PGSQL_TARGET_ID="${MCP_PGSQL_TARGET_ID:-tap_pgsql_default}"
|
||||
MCP_PGSQL_AUTH_PROFILE_ID="${MCP_PGSQL_AUTH_PROFILE_ID:-tap_pgsql_auth}"
|
||||
MCP_MYSQL_HOSTGROUP_ID="${MCP_MYSQL_HOSTGROUP_ID:-9100}"
|
||||
MCP_PGSQL_HOSTGROUP_ID="${MCP_PGSQL_HOSTGROUP_ID:-9200}"
|
||||
AI_PGSQL_HOST="${AI_PGSQL_HOST:-127.0.0.1}"
|
||||
AI_PGSQL_PORT="${AI_PGSQL_PORT:-15432}"
|
||||
AI_PGSQL_USER="${AI_PGSQL_USER:-postgres}"
|
||||
AI_PGSQL_PASSWORD="${AI_PGSQL_PASSWORD:-postgres}"
|
||||
AI_PGSQL_DB="${AI_PGSQL_DB:-testdb}"
|
||||
|
||||
ADMIN_HOST="${TAP_ADMINHOST:-127.0.0.1}"
|
||||
ADMIN_PORT="${TAP_ADMINPORT:-6032}"
|
||||
ADMIN_USER="${TAP_ADMINUSERNAME:-radmin}"
|
||||
ADMIN_PASS="${TAP_ADMINPASSWORD:-radmin}"
|
||||
|
||||
if [[ $(mysql --skip-ssl-verify-server-cert -h 2>&1) =~ skip-ssl-verify-server-cert ]]; then
|
||||
SSLOPT=--skip-ssl-verify-server-cert
|
||||
else
|
||||
SSLOPT=
|
||||
fi
|
||||
|
||||
exec_admin() {
|
||||
mysql ${SSLOPT} -h"${ADMIN_HOST}" -P"${ADMIN_PORT}" -u"${ADMIN_USER}" -p"${ADMIN_PASS}" -e "$1" 2>&1 | sed '/^mysql: .*Warning/d'
|
||||
}
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose -f "${SCRIPT_DIR}/docker-compose.yml" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose -f "${SCRIPT_DIR}/docker-compose.yml" "$@"
|
||||
else
|
||||
echo "[ERROR] docker compose is not available" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
create_mysql_monitor_user() {
|
||||
echo "[INFO] AI pre-hook: creating MySQL monitor user monitor/monitor on backend ${TAP_MYSQLHOST}:${TAP_MYSQLPORT}"
|
||||
mysql -h"${TAP_MYSQLHOST}" -P"${TAP_MYSQLPORT}" -u"${TAP_MYSQLUSERNAME}" -p"${TAP_MYSQLPASSWORD}" -e "\
|
||||
CREATE USER IF NOT EXISTS 'monitor'@'%' IDENTIFIED BY 'monitor'; \
|
||||
GRANT USAGE, PROCESS, REPLICATION CLIENT ON *.* TO 'monitor'@'%'; \
|
||||
FLUSH PRIVILEGES;"
|
||||
}
|
||||
|
||||
create_pgsql_monitor_user() {
|
||||
echo "[INFO] AI pre-hook: creating PostgreSQL monitor user monitor/monitor on backend ${AI_PGSQL_HOST}:${AI_PGSQL_PORT}"
|
||||
local sql="DO \$\$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname='monitor') THEN CREATE ROLE monitor LOGIN PASSWORD 'monitor'; END IF; END \$\$; GRANT pg_monitor TO monitor; GRANT CONNECT ON DATABASE postgres TO monitor; GRANT CONNECT ON DATABASE ${AI_PGSQL_DB} TO monitor;"
|
||||
if command -v psql >/dev/null 2>&1; then
|
||||
PGPASSWORD="${AI_PGSQL_PASSWORD}" psql -h "${AI_PGSQL_HOST}" -p "${AI_PGSQL_PORT}" -U "${AI_PGSQL_USER}" -d "${AI_PGSQL_DB}" -v ON_ERROR_STOP=1 -c "${sql}"
|
||||
else
|
||||
compose exec -T pgsql psql -U "${AI_PGSQL_USER}" -d "${AI_PGSQL_DB}" -v ON_ERROR_STOP=1 -c "${sql}"
|
||||
fi
|
||||
}
|
||||
|
||||
seed_mysql_test_data() {
|
||||
echo "[INFO] AI pre-hook: seeding MySQL static-harvest test data"
|
||||
mysql -h"${TAP_MYSQLHOST}" -P"${TAP_MYSQLPORT}" -u"${TAP_MYSQLUSERNAME}" -p"${TAP_MYSQLPASSWORD}" < "${SCRIPT_DIR}/mysql-seed.sql"
|
||||
}
|
||||
|
||||
seed_pgsql_test_data() {
|
||||
echo "[INFO] AI pre-hook: seeding PostgreSQL static-harvest test data"
|
||||
if command -v psql >/dev/null 2>&1; then
|
||||
PGPASSWORD="${AI_PGSQL_PASSWORD}" psql -h "${AI_PGSQL_HOST}" -p "${AI_PGSQL_PORT}" -U "${AI_PGSQL_USER}" -d "${AI_PGSQL_DB}" -v ON_ERROR_STOP=1 -f "${SCRIPT_DIR}/pgsql-seed.sql"
|
||||
else
|
||||
compose exec -T pgsql psql -U "${AI_PGSQL_USER}" -d "${AI_PGSQL_DB}" -v ON_ERROR_STOP=1 < "${SCRIPT_DIR}/pgsql-seed.sql"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "[INFO] AI pre-hook: starting group-local containers"
|
||||
"${SCRIPT_DIR}/docker-compose-init.bash"
|
||||
create_mysql_monitor_user
|
||||
create_pgsql_monitor_user
|
||||
seed_mysql_test_data
|
||||
seed_pgsql_test_data
|
||||
|
||||
echo "[INFO] AI pre-hook: configuring ProxySQL MCP and backend routing"
|
||||
|
||||
# Configure MCP runtime variables.
|
||||
exec_admin "SET mcp-port='${TAP_MCPPORT}';"
|
||||
exec_admin "SET mcp-use_ssl='true';"
|
||||
exec_admin "SET mcp-enabled='false';"
|
||||
exec_admin "LOAD MCP VARIABLES TO RUNTIME; SAVE MCP VARIABLES TO DISK;"
|
||||
|
||||
# Keep predictable hostgroups for both direct tests and MCP target routing.
|
||||
exec_admin "DELETE FROM mysql_servers WHERE hostgroup_id IN (0, ${MCP_MYSQL_HOSTGROUP_ID});"
|
||||
exec_admin "INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, weight, comment) VALUES (0, '${TAP_MYSQLHOST}', ${TAP_MYSQLPORT}, 'ONLINE', 1, 'ai local mysql');"
|
||||
exec_admin "INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, weight, comment) VALUES (${MCP_MYSQL_HOSTGROUP_ID}, '${TAP_MYSQLHOST}', ${TAP_MYSQLPORT}, 'ONLINE', 1, 'ai mcp mysql');"
|
||||
exec_admin "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
|
||||
|
||||
exec_admin "DELETE FROM pgsql_servers WHERE hostgroup_id IN (${MCP_PGSQL_HOSTGROUP_ID});"
|
||||
exec_admin "INSERT INTO pgsql_servers (hostgroup_id, hostname, port, status, weight, comment) VALUES (${MCP_PGSQL_HOSTGROUP_ID}, '${AI_PGSQL_HOST}', ${AI_PGSQL_PORT}, 'ONLINE', 1, 'ai mcp pgsql');"
|
||||
exec_admin "LOAD PGSQL SERVERS TO RUNTIME; SAVE PGSQL SERVERS TO DISK;"
|
||||
|
||||
# Basic frontend mysql users for TAP scripts that connect through ProxySQL.
|
||||
exec_admin "INSERT OR IGNORE INTO mysql_users (username, password, active, default_hostgroup, comment) VALUES ('${TAP_MYSQLUSERNAME}', '${TAP_MYSQLPASSWORD}', 1, 0, 'ai local');"
|
||||
exec_admin "INSERT OR IGNORE INTO mysql_users (username, password, active, default_hostgroup, comment) VALUES ('testuser', 'testuser', 1, 0, 'ai local');"
|
||||
exec_admin "LOAD MYSQL USERS TO RUNTIME; SAVE MYSQL USERS TO DISK;"
|
||||
|
||||
# Configure MCP auth and target profiles (mysql + pgsql).
|
||||
exec_admin "DELETE FROM mcp_target_profiles WHERE target_id IN ('${MCP_TARGET_ID}', '${MCP_PGSQL_TARGET_ID}');"
|
||||
exec_admin "DELETE FROM mcp_auth_profiles WHERE auth_profile_id IN ('${MCP_AUTH_PROFILE_ID}', '${MCP_PGSQL_AUTH_PROFILE_ID}');"
|
||||
|
||||
exec_admin "INSERT INTO mcp_auth_profiles (auth_profile_id, db_username, db_password, default_schema, use_ssl, ssl_mode, comment) VALUES ('${MCP_AUTH_PROFILE_ID}', '${TAP_MYSQLUSERNAME}', '${TAP_MYSQLPASSWORD}', '${TEST_DB_NAME}', 0, '', 'ai mysql mcp auth');"
|
||||
exec_admin "INSERT INTO mcp_auth_profiles (auth_profile_id, db_username, db_password, default_schema, use_ssl, ssl_mode, comment) VALUES ('${MCP_PGSQL_AUTH_PROFILE_ID}', '${AI_PGSQL_USER}', '${AI_PGSQL_PASSWORD}', '${AI_PGSQL_DB}', 0, '', 'ai pgsql mcp auth');"
|
||||
|
||||
exec_admin "INSERT INTO mcp_target_profiles (target_id, protocol, hostgroup_id, auth_profile_id, description, max_rows, timeout_ms, allow_explain, allow_discovery, active, comment) VALUES ('${MCP_TARGET_ID}', 'mysql', ${MCP_MYSQL_HOSTGROUP_ID}, '${MCP_AUTH_PROFILE_ID}', 'AI local MySQL target', 200, 5000, 1, 1, 1, 'ai local');"
|
||||
exec_admin "INSERT INTO mcp_target_profiles (target_id, protocol, hostgroup_id, auth_profile_id, description, max_rows, timeout_ms, allow_explain, allow_discovery, active, comment) VALUES ('${MCP_PGSQL_TARGET_ID}', 'pgsql', ${MCP_PGSQL_HOSTGROUP_ID}, '${MCP_PGSQL_AUTH_PROFILE_ID}', 'AI local PostgreSQL target', 200, 5000, 1, 1, 1, 'ai local');"
|
||||
|
||||
exec_admin "LOAD MCP PROFILES TO RUNTIME; SAVE MCP PROFILES TO DISK;"
|
||||
exec_admin "SET mcp-enabled='true';"
|
||||
exec_admin "LOAD MCP VARIABLES TO RUNTIME; SAVE MCP VARIABLES TO DISK;"
|
||||
|
||||
sleep 2
|
||||
echo "[INFO] AI pre-hook completed"
|
||||
@ -1,3 +1,7 @@
|
||||
-- AI Group PostgreSQL Test Data Seeding
|
||||
-- Creates tables needed by AI/MCP tests
|
||||
-- This is executed by docker-pgsql-post.bash when TAP_GROUP starts with 'ai'
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.tap_pgsql_static_accounts (
|
||||
account_id INT PRIMARY KEY,
|
||||
account_name TEXT NOT NULL UNIQUE,
|
||||
@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
#
|
||||
# AI TAP Group Post-Infrastructure Hook
|
||||
# Executed by ensure-infras.bash after all backends are running
|
||||
# Configures MCP and seeds test data
|
||||
#
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Check required environment variables
|
||||
if [ -z "${INFRA_ID:-}" ]; then
|
||||
echo "ERROR: INFRA_ID is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORKSPACE:-}" ]; then
|
||||
echo "ERROR: WORKSPACE is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Derive DEFAULT_MYSQL_INFRA and DEFAULT_PGSQL_INFRA from infras.lst if not set
|
||||
if [ -z "${DEFAULT_MYSQL_INFRA:-}" ] || [ -z "${DEFAULT_PGSQL_INFRA:-}" ]; then
|
||||
INFRAS_LST="${SCRIPT_DIR}/infras.lst"
|
||||
if [ -f "${INFRAS_LST}" ]; then
|
||||
for INFRA_NAME in $(cat "${INFRAS_LST}"); do
|
||||
if [[ "${INFRA_NAME}" == *mysql* ]] || [[ "${INFRA_NAME}" == *mariadb* ]]; then
|
||||
DEFAULT_MYSQL_INFRA="${DEFAULT_MYSQL_INFRA:-${INFRA_NAME}}"
|
||||
fi
|
||||
if [[ "${INFRA_NAME}" == *pgsql* ]] || [[ "${INFRA_NAME}" == *pgdb* ]]; then
|
||||
DEFAULT_PGSQL_INFRA="${DEFAULT_PGSQL_INFRA:-${INFRA_NAME}}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
export ROOT_PASSWORD=$(echo -n "${INFRA_ID}" | sha256sum | head -c 10)
|
||||
PROXY_CONTAINER="proxysql.${INFRA_ID}"
|
||||
|
||||
# Wait for ProxySQL admin to be ready
|
||||
echo ">>> AI post-infras hook: Waiting for ProxySQL admin..."
|
||||
MAX_WAIT=30
|
||||
COUNT=0
|
||||
while [ $COUNT -lt $MAX_WAIT ]; do
|
||||
if docker exec "${PROXY_CONTAINER}" mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e "SELECT 1" >/dev/null 2>&1; then
|
||||
echo ">>> ProxySQL admin is ready"
|
||||
break
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
|
||||
if [ $COUNT -ge $MAX_WAIT ]; then
|
||||
echo " TIMEOUT - ProxySQL admin not accessible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configure MCP
|
||||
echo ">>> AI post-infras hook: Configuring MCP..."
|
||||
|
||||
# Set MCP-specific environment variables (with defaults)
|
||||
export TAP_MCPPORT="${TAP_MCPPORT:-6071}"
|
||||
export MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
|
||||
export MCP_AUTH_PROFILE_ID="${MCP_AUTH_PROFILE_ID:-tap_mysql_auth}"
|
||||
export MCP_PGSQL_TARGET_ID="${MCP_PGSQL_TARGET_ID:-tap_pgsql_default}"
|
||||
export MCP_PGSQL_AUTH_PROFILE_ID="${MCP_PGSQL_AUTH_PROFILE_ID:-tap_pgsql_auth}"
|
||||
export MCP_MYSQL_HOSTGROUP_ID="${MCP_MYSQL_HOSTGROUP_ID:-9100}"
|
||||
export MCP_PGSQL_HOSTGROUP_ID="${MCP_PGSQL_HOSTGROUP_ID:-9200}"
|
||||
export MYSQL_DATABASE="${MYSQL_DATABASE:-test}"
|
||||
export PGSQL_DATABASE="${PGSQL_DATABASE:-postgres}"
|
||||
|
||||
# Set backend connection variables
|
||||
export TAP_MYSQLHOST="mysql1.${DEFAULT_MYSQL_INFRA}"
|
||||
export TAP_MYSQLPORT="3306"
|
||||
export TAP_MYSQLUSERNAME="root"
|
||||
export TAP_MYSQLPASSWORD="${ROOT_PASSWORD}"
|
||||
export TAP_PGSQLSERVER_HOST="pgsql1.${DEFAULT_PGSQL_INFRA}"
|
||||
export TAP_PGSQLSERVER_PORT="5432"
|
||||
export TAP_PGSQLSERVER_USERNAME="postgres"
|
||||
export TAP_PGSQLSERVER_PASSWORD="${ROOT_PASSWORD}"
|
||||
|
||||
# Apply MCP configuration
|
||||
MCP_CONFIG_SQL="${SCRIPT_DIR}/mcp-config.sql"
|
||||
if [ -f "${MCP_CONFIG_SQL}" ]; then
|
||||
if command -v envsubst >/dev/null 2>&1; then
|
||||
envsubst < "${MCP_CONFIG_SQL}" | docker exec -i "${PROXY_CONTAINER}" mysql -uradmin -pradmin -h127.0.0.1 -P6032
|
||||
else
|
||||
# Fallback: use bash variable expansion
|
||||
bash -c "cat <<EOF
|
||||
$(cat "${MCP_CONFIG_SQL}")
|
||||
EOF" | docker exec -i "${PROXY_CONTAINER}" mysql -uradmin -pradmin -h127.0.0.1 -P6032
|
||||
fi
|
||||
echo ">>> MCP configuration completed"
|
||||
else
|
||||
echo ">>> WARNING: MCP config SQL not found at ${MCP_CONFIG_SQL}"
|
||||
fi
|
||||
|
||||
# Seed test data on MySQL
|
||||
echo ">>> AI post-infras hook: Seeding MySQL test data..."
|
||||
MYSQL_SEED_SQL="${SCRIPT_DIR}/seed-mysql.sql"
|
||||
if [ -f "${MYSQL_SEED_SQL}" ]; then
|
||||
# Seed only mysql1 (replication will propagate to others)
|
||||
MYSQL1_CONTAINER="${DEFAULT_MYSQL_INFRA}-${INFRA_ID}-mysql1-1"
|
||||
docker exec -i "${MYSQL1_CONTAINER}" mysql -h127.0.0.1 -uroot -p"${ROOT_PASSWORD}" < "${MYSQL_SEED_SQL}" || echo ">>> WARNING: MySQL seed may have partially failed (data may already exist)"
|
||||
echo ">>> MySQL test data seeding completed"
|
||||
else
|
||||
echo ">>> WARNING: MySQL seed SQL not found at ${MYSQL_SEED_SQL}"
|
||||
fi
|
||||
|
||||
# Seed test data on PostgreSQL
|
||||
echo ">>> AI post-infras hook: Seeding PostgreSQL test data..."
|
||||
PGSQL_SEED_SQL="${SCRIPT_DIR}/seed-pgsql.sql"
|
||||
if [ -f "${PGSQL_SEED_SQL}" ]; then
|
||||
PGSQL_CONTAINER="${DEFAULT_PGSQL_INFRA}-${INFRA_ID}-pgdb1-1"
|
||||
docker exec -i "${PGSQL_CONTAINER}" psql -X -Upostgres < "${PGSQL_SEED_SQL}" || echo ">>> WARNING: PostgreSQL seed may have partially failed (data may already exist)"
|
||||
echo ">>> PostgreSQL test data seeding completed"
|
||||
else
|
||||
echo ">>> WARNING: PostgreSQL seed SQL not found at ${PGSQL_SEED_SQL}"
|
||||
fi
|
||||
|
||||
echo ">>> AI post-infras hook completed"
|
||||
Loading…
Reference in new issue