MCP TAP: pass target_id explicitly in query-rules test payloads

This commit updates MCP TAP query-rules tests to always include `target_id` in tool call payloads where query execution is expected.

Details:
- Added explicit `target_id` arguments to MCP `/mcp/query` tool invocations in rule evaluation tests.
- Removed implicit dependence on server-selected defaults during test execution.

Why this change is important:
- Query-rules behavior is now route-aware and can depend on logical target selection.
- Explicit routing in tests prevents non-determinism and ensures assertions are tied to the intended backend target.

Result:
- More deterministic TAP behavior and clearer validation of rule evaluation under target-based routing.
pull/5386/head
Rene Cannao 3 months ago
parent 4a8b224038
commit 67cb1b72b5

@ -22,6 +22,7 @@ MYSQL_DATABASE="${TEST_DB_NAME:-${MYSQL_DATABASE:-testdb}}"
# MCP server configuration
MCP_HOST="${TAP_ADMINHOST:-${MCP_HOST:-127.0.0.1}}"
MCP_PORT="${TAP_MCPPORT:-${MCP_PORT:-6071}}"
MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
# Colors
RED='\033[0;31m'

@ -450,7 +450,7 @@ main() {
"Test 1: Block DROP TABLE statement" \
"query" \
"run_sql_readonly" \
'{"sql": "DROP TABLE IF EXISTS test_table;"}' \
'{"sql": "DROP TABLE IF EXISTS test_table;", "target_id": "'"${MCP_TARGET_ID}"'"}' \
"DROP TABLE statements are not allowed" \
"100"
@ -459,7 +459,7 @@ main() {
"Test 2: Block SELECT from customers table" \
"query" \
"run_sql_readonly" \
'{"sql": "SELECT * FROM customers;"}' \
'{"sql": "SELECT * FROM customers;", "target_id": "'"${MCP_TARGET_ID}"'"}' \
"customers table is restricted" \
"101"
@ -468,7 +468,7 @@ main() {
"Test 3: Allow SELECT from other tables" \
"query" \
"run_sql_readonly" \
'{"sql": "SELECT * FROM products;"}'
'{"sql": "SELECT * FROM products;", "target_id": "'"${MCP_TARGET_ID}"'"}'
# Display final stats
echo ""

@ -157,7 +157,7 @@ main() {
# Test 4.12: Execute MCP query matching rule 100 and verify hit counter increments
log_info "Executing query matching rule 100..."
PAYLOAD_100='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM test_table"}},"id":1}'
PAYLOAD_100='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM test_table","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
mcp_request "query" "${PAYLOAD_100}" >/dev/null
sleep 1
HITS_AFTER_100=$(get_hits 100)
@ -169,7 +169,7 @@ main() {
# Test 4.13: Execute MCP query matching rule 101 and verify hit counter increments
log_info "Executing query matching rule 101..."
PAYLOAD_101='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"DROP TABLE IF EXISTS dummy_table"}},"id":2}'
PAYLOAD_101='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"DROP TABLE IF EXISTS dummy_table","target_id":"'"${MCP_TARGET_ID}"'"}},"id":2}'
mcp_request "query" "${PAYLOAD_101}" >/dev/null
sleep 1
HITS_AFTER_101=$(get_hits 101)
@ -192,7 +192,7 @@ main() {
# Test 4.15: Execute query NOT matching any rule and verify no test rule counter increments
log_info "Executing query NOT matching any test rule..."
PAYLOAD_NO_MATCH='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM other_table"}},"id":3}'
PAYLOAD_NO_MATCH='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM other_table","target_id":"'"${MCP_TARGET_ID}"'"}},"id":3}'
HITS_BEFORE_NO_MATCH_100=$(get_hits 100)
HITS_BEFORE_NO_MATCH_101=$(get_hits 101)
mcp_request "query" "${PAYLOAD_NO_MATCH}" >/dev/null

@ -206,7 +206,7 @@ main() {
# Test 5.16: Execute a query and verify it appears in digest
log_info "Executing unique query: SELECT COUNT(*) FROM test_phase5_table"
PAYLOAD_1='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT COUNT(*) FROM test_phase5_table"}},"id":1}'
PAYLOAD_1='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT COUNT(*) FROM test_phase5_table","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
mcp_request "query" "${PAYLOAD_1}" >/dev/null
sleep 1
DIGEST_COUNT_AFTER_1=$(exec_admin_silent "SELECT COUNT(*) FROM stats_mcp_query_digest WHERE tool_name = 'run_sql_readonly';")
@ -233,7 +233,7 @@ main() {
# Test 5.18: Execute different query and verify new digest entry
log_info "Executing different query: SELECT * FROM another_phase5_table LIMIT 10"
PAYLOAD_2='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM another_phase5_table LIMIT 10"}},"id":2}'
PAYLOAD_2='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM another_phase5_table LIMIT 10","target_id":"'"${MCP_TARGET_ID}"'"}},"id":2}'
DIGEST_COUNT_BEFORE_2=$(exec_admin_silent "SELECT COUNT(*) FROM stats_mcp_query_digest WHERE tool_name = 'run_sql_readonly';")
log_verbose "Digest count before query 2: ${DIGEST_COUNT_BEFORE_2}"
mcp_request "query" "${PAYLOAD_2}" >/dev/null

@ -74,7 +74,7 @@ test_is_allowed() {
local payload
payload=$(cat <<EOF
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}"}},"id":1}
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","target_id":"${MCP_TARGET_ID}"}},"id":1}
EOF
)
@ -98,7 +98,7 @@ test_is_blocked() {
local payload
payload=$(cat <<EOF
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}"}},"id":1}
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","target_id":"${MCP_TARGET_ID}"}},"id":1}
EOF
)

@ -80,7 +80,7 @@ test_is_rewritten() {
local payload
payload=$(cat <<EOF
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${original_sql}"}},"id":1}
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${original_sql}","target_id":"${MCP_TARGET_ID}"}},"id":1}
EOF
)

@ -76,7 +76,7 @@ test_is_timed_out() {
local payload
payload=$(cat <<EOF
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","timeout":${timeout_sec}}},"id":1}
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","target_id":"${MCP_TARGET_ID}","timeout":${timeout_sec}}},"id":1}
EOF
)
@ -175,7 +175,7 @@ main() {
# Test that a quick query without timeout rule executes successfully
run_test "T8.3: Quick query without SLEEP executes successfully" \
bash -c "timeout 5 curl -k -s -X POST 'https://${MCP_HOST}:${MCP_PORT}/mcp/query' -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"run_sql_readonly\",\"arguments\":{\"sql\":\"SELECT phase8_data FROM quick_table\"}},\"id\":1}' | grep -q 'phase8_data'"
bash -c "timeout 5 curl -k -s -X POST 'https://${MCP_HOST}:${MCP_PORT}/mcp/query' -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"run_sql_readonly\",\"arguments\":{\"sql\":\"SELECT phase8_data FROM quick_table\",\"target_id\":\"${MCP_TARGET_ID}\"}},\"id\":1}' | grep -q 'phase8_data'"
# Display runtime rules
echo ""

@ -80,7 +80,7 @@ test_query_not_executed() {
initial_count=$(exec_mysql_silent "SELECT COUNT(*) FROM ${MYSQL_DATABASE}.status_table;")
local payload
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\"}},\"id\":1}"
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\",\"target_id\":\"${MCP_TARGET_ID}\"}},\"id\":1}"
# Execute the MCP request
mcp_request "query" "${payload}" >/dev/null 2>&1
@ -105,7 +105,7 @@ test_returns_okmsg() {
local expected_okmsg="$3"
local payload
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\"}},\"id\":1}"
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\",\"target_id\":\"${MCP_TARGET_ID}\"}},\"id\":1}"
local response
response=$(mcp_request "query" "${payload}")
@ -212,7 +212,7 @@ main() {
log_test "T9.1: Verify OK message response is successful (not error)"
TOTAL_TESTS=$((TOTAL_TESTS + 1))
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING"}},"id":1}'
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
response=$(mcp_request "query" "$payload")
log_verbose "Response: ${response}"
@ -239,7 +239,7 @@ main() {
TOTAL_TESTS=$((TOTAL_TESTS + 1))
# Execute a PING query (should be intercepted by OK_msg rule)
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING"}},"id":1}'
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
response=$(mcp_request "query" "$payload")
log_verbose "Response: ${response}"
@ -268,7 +268,7 @@ main() {
log_test "T9.2: Verify health_check queries are not tracked"
TOTAL_TESTS=$((TOTAL_TESTS + 1))
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM health_check;"}},"id":1}'
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM health_check;","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
response=$(mcp_request "query" "$payload")
log_verbose "Response: ${response}"

@ -135,7 +135,8 @@ test_rejected_query() {
"params": {
"name": "run_sql_readonly",
"arguments": {
"sql": ${sql_query}
"sql": ${sql_query},
"target_id": "${MCP_TARGET_ID}"
}
},
"id": ${TOTAL_TESTS}
@ -205,7 +206,8 @@ test_allowed_query() {
"params": {
"name": "run_sql_readonly",
"arguments": {
"sql": ${sql_query}
"sql": ${sql_query},
"target_id": "${MCP_TARGET_ID}"
}
},
"id": ${TOTAL_TESTS}

Loading…
Cancel
Save