Skip to content

Commit 67cb1b7

Browse files
committed
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.
1 parent 4a8b224 commit 67cb1b7

9 files changed

+23
-20
lines changed

test/tap/tests/mcp_rules_testing/mcp_test_helpers.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ MYSQL_DATABASE="${TEST_DB_NAME:-${MYSQL_DATABASE:-testdb}}"
2222
# MCP server configuration
2323
MCP_HOST="${TAP_ADMINHOST:-${MCP_HOST:-127.0.0.1}}"
2424
MCP_PORT="${TAP_MCPPORT:-${MCP_PORT:-6071}}"
25+
MCP_TARGET_ID="${MCP_TARGET_ID:-tap_mysql_default}"
2526

2627
# Colors
2728
RED='\033[0;31m'

test/tap/tests/mcp_rules_testing/test_mcp_query_rules_block.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ main() {
450450
"Test 1: Block DROP TABLE statement" \
451451
"query" \
452452
"run_sql_readonly" \
453-
'{"sql": "DROP TABLE IF EXISTS test_table;"}' \
453+
'{"sql": "DROP TABLE IF EXISTS test_table;", "target_id": "'"${MCP_TARGET_ID}"'"}' \
454454
"DROP TABLE statements are not allowed" \
455455
"100"
456456

@@ -459,7 +459,7 @@ main() {
459459
"Test 2: Block SELECT from customers table" \
460460
"query" \
461461
"run_sql_readonly" \
462-
'{"sql": "SELECT * FROM customers;"}' \
462+
'{"sql": "SELECT * FROM customers;", "target_id": "'"${MCP_TARGET_ID}"'"}' \
463463
"customers table is restricted" \
464464
"101"
465465

@@ -468,7 +468,7 @@ main() {
468468
"Test 3: Allow SELECT from other tables" \
469469
"query" \
470470
"run_sql_readonly" \
471-
'{"sql": "SELECT * FROM products;"}'
471+
'{"sql": "SELECT * FROM products;", "target_id": "'"${MCP_TARGET_ID}"'"}'
472472

473473
# Display final stats
474474
echo ""

test/tap/tests/mcp_rules_testing/test_phase4_stats.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ main() {
157157

158158
# Test 4.12: Execute MCP query matching rule 100 and verify hit counter increments
159159
log_info "Executing query matching rule 100..."
160-
PAYLOAD_100='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM test_table"}},"id":1}'
160+
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}'
161161
mcp_request "query" "${PAYLOAD_100}" >/dev/null
162162
sleep 1
163163
HITS_AFTER_100=$(get_hits 100)
@@ -169,7 +169,7 @@ main() {
169169

170170
# Test 4.13: Execute MCP query matching rule 101 and verify hit counter increments
171171
log_info "Executing query matching rule 101..."
172-
PAYLOAD_101='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"DROP TABLE IF EXISTS dummy_table"}},"id":2}'
172+
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}'
173173
mcp_request "query" "${PAYLOAD_101}" >/dev/null
174174
sleep 1
175175
HITS_AFTER_101=$(get_hits 101)
@@ -192,7 +192,7 @@ main() {
192192

193193
# Test 4.15: Execute query NOT matching any rule and verify no test rule counter increments
194194
log_info "Executing query NOT matching any test rule..."
195-
PAYLOAD_NO_MATCH='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM other_table"}},"id":3}'
195+
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}'
196196
HITS_BEFORE_NO_MATCH_100=$(get_hits 100)
197197
HITS_BEFORE_NO_MATCH_101=$(get_hits 101)
198198
mcp_request "query" "${PAYLOAD_NO_MATCH}" >/dev/null

test/tap/tests/mcp_rules_testing/test_phase5_digest.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ main() {
206206

207207
# Test 5.16: Execute a query and verify it appears in digest
208208
log_info "Executing unique query: SELECT COUNT(*) FROM test_phase5_table"
209-
PAYLOAD_1='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT COUNT(*) FROM test_phase5_table"}},"id":1}'
209+
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}'
210210
mcp_request "query" "${PAYLOAD_1}" >/dev/null
211211
sleep 1
212212
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() {
233233

234234
# Test 5.18: Execute different query and verify new digest entry
235235
log_info "Executing different query: SELECT * FROM another_phase5_table LIMIT 10"
236-
PAYLOAD_2='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM another_phase5_table LIMIT 10"}},"id":2}'
236+
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}'
237237
DIGEST_COUNT_BEFORE_2=$(exec_admin_silent "SELECT COUNT(*) FROM stats_mcp_query_digest WHERE tool_name = 'run_sql_readonly';")
238238
log_verbose "Digest count before query 2: ${DIGEST_COUNT_BEFORE_2}"
239239
mcp_request "query" "${PAYLOAD_2}" >/dev/null

test/tap/tests/mcp_rules_testing/test_phase6_eval_block.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ test_is_allowed() {
7474

7575
local payload
7676
payload=$(cat <<EOF
77-
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}"}},"id":1}
77+
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","target_id":"${MCP_TARGET_ID}"}},"id":1}
7878
EOF
7979
)
8080

@@ -98,7 +98,7 @@ test_is_blocked() {
9898

9999
local payload
100100
payload=$(cat <<EOF
101-
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}"}},"id":1}
101+
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","target_id":"${MCP_TARGET_ID}"}},"id":1}
102102
EOF
103103
)
104104

test/tap/tests/mcp_rules_testing/test_phase7_eval_rewrite.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ test_is_rewritten() {
8080

8181
local payload
8282
payload=$(cat <<EOF
83-
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${original_sql}"}},"id":1}
83+
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${original_sql}","target_id":"${MCP_TARGET_ID}"}},"id":1}
8484
EOF
8585
)
8686

test/tap/tests/mcp_rules_testing/test_phase8_eval_timeout.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ test_is_timed_out() {
7676

7777
local payload
7878
payload=$(cat <<EOF
79-
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","timeout":${timeout_sec}}},"id":1}
79+
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"${tool_name}","arguments":{"sql":"${sql}","target_id":"${MCP_TARGET_ID}","timeout":${timeout_sec}}},"id":1}
8080
EOF
8181
)
8282

@@ -175,7 +175,7 @@ main() {
175175

176176
# Test that a quick query without timeout rule executes successfully
177177
run_test "T8.3: Quick query without SLEEP executes successfully" \
178-
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'"
178+
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'"
179179

180180
# Display runtime rules
181181
echo ""

test/tap/tests/mcp_rules_testing/test_phase9_eval_okmsg.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ test_query_not_executed() {
8080
initial_count=$(exec_mysql_silent "SELECT COUNT(*) FROM ${MYSQL_DATABASE}.status_table;")
8181

8282
local payload
83-
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\"}},\"id\":1}"
83+
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\",\"target_id\":\"${MCP_TARGET_ID}\"}},\"id\":1}"
8484

8585
# Execute the MCP request
8686
mcp_request "query" "${payload}" >/dev/null 2>&1
@@ -105,7 +105,7 @@ test_returns_okmsg() {
105105
local expected_okmsg="$3"
106106

107107
local payload
108-
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\"}},\"id\":1}"
108+
payload="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"${tool_name}\",\"arguments\":{\"sql\":\"${sql}\",\"target_id\":\"${MCP_TARGET_ID}\"}},\"id\":1}"
109109

110110
local response
111111
response=$(mcp_request "query" "${payload}")
@@ -212,7 +212,7 @@ main() {
212212
log_test "T9.1: Verify OK message response is successful (not error)"
213213
TOTAL_TESTS=$((TOTAL_TESTS + 1))
214214

215-
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING"}},"id":1}'
215+
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
216216
response=$(mcp_request "query" "$payload")
217217
log_verbose "Response: ${response}"
218218

@@ -239,7 +239,7 @@ main() {
239239
TOTAL_TESTS=$((TOTAL_TESTS + 1))
240240

241241
# Execute a PING query (should be intercepted by OK_msg rule)
242-
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING"}},"id":1}'
242+
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"PING","target_id":"'"${MCP_TARGET_ID}"'"}},"id":1}'
243243
response=$(mcp_request "query" "$payload")
244244
log_verbose "Response: ${response}"
245245

@@ -268,7 +268,7 @@ main() {
268268
log_test "T9.2: Verify health_check queries are not tracked"
269269
TOTAL_TESTS=$((TOTAL_TESTS + 1))
270270

271-
payload='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_sql_readonly","arguments":{"sql":"SELECT * FROM health_check;"}},"id":1}'
271+
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}'
272272
response=$(mcp_request "query" "$payload")
273273
log_verbose "Response: ${response}"
274274

test/tap/tests/mcp_rules_testing/test_run_sql_readonly_validation.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ test_rejected_query() {
135135
"params": {
136136
"name": "run_sql_readonly",
137137
"arguments": {
138-
"sql": ${sql_query}
138+
"sql": ${sql_query},
139+
"target_id": "${MCP_TARGET_ID}"
139140
}
140141
},
141142
"id": ${TOTAL_TESTS}
@@ -205,7 +206,8 @@ test_allowed_query() {
205206
"params": {
206207
"name": "run_sql_readonly",
207208
"arguments": {
208-
"sql": ${sql_query}
209+
"sql": ${sql_query},
210+
"target_id": "${MCP_TARGET_ID}"
209211
}
210212
},
211213
"id": ${TOTAL_TESTS}

0 commit comments

Comments
 (0)