You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2026/09/18 10:12:43 UTC
(superset) 01/01: test(mcp): restore informational query-result envelope coverage
This is an automated email from the ASF dual-hosted git repository.
aminghadersohi pushed a commit to branch sc-119162-mcp-sunburst
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 456177777b544d8b4176d6d8d575df11e8e2dda9
Author: Amin Ghadersohi <am...@gmail.com>
AuthorDate: Fri Sep 18 10:12:27 2026 +0000
test(mcp): restore informational query-result envelope coverage
The master merge resolved tests/unit_tests/mcp_service/chart/test_query_result.py
as an add/add conflict by taking the branch side wholesale, which dropped
test_query_result_failure_allows_valid_and_informational_envelopes and the
expanded query_result_failure docstring.
Restore both, reconciled with the stricter envelope contract. The claim the
dropped test defended -- that a successful status carrying an informational
message is not a failure -- still holds, so it comes back with a real query
payload. The one payload that no longer passes, a success status with an
empty queries list, now fails closed: query_result_failure is a strict
envelope validator rather than only an embedded-failure detector, and every
caller reads data from at least one query. That behaviour gets its own test
so the contract is pinned rather than silently changed.
---
superset/mcp_service/chart/query_result.py | 13 +++++++-
.../mcp_service/chart/test_query_result.py | 39 ++++++++++++++++++++++
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/superset/mcp_service/chart/query_result.py b/superset/mcp_service/chart/query_result.py
index ce8243143df..e997971be10 100644
--- a/superset/mcp_service/chart/query_result.py
+++ b/superset/mcp_service/chart/query_result.py
@@ -1428,7 +1428,18 @@ def validate_query_result_envelope( # noqa: C901
def query_result_failure(result: Any) -> ChartError | None:
- """Return an embedded failure or malformed-envelope error."""
+ """Return a structured failure embedded in a ChartDataCommand payload.
+
+ ChartDataCommand can return an HTTP-successful envelope whose top level or
+ any query reports a failure. Every query is inspected before callers accept
+ data from the result. Successful statuses may carry informational messages,
+ so ``message`` alone is not treated as an error.
+
+ Envelope shape is validated just as strictly as embedded failures: an
+ envelope carrying no query payload is rejected as malformed rather than
+ reported as failure-free, because every caller reads data from at least one
+ query.
+ """
return validate_query_result_envelope(result)
diff --git a/tests/unit_tests/mcp_service/chart/test_query_result.py b/tests/unit_tests/mcp_service/chart/test_query_result.py
index 78d91696ac8..c0e1c43fd2e 100644
--- a/tests/unit_tests/mcp_service/chart/test_query_result.py
+++ b/tests/unit_tests/mcp_service/chart/test_query_result.py
@@ -258,6 +258,45 @@ def test_query_result_failure_rejects_arbitrary_status_enum_without_hooks():
assert failure.error_type == "InvalidQueryResult"
+@pytest.mark.parametrize(
+ "payload",
+ [
+ {
+ "status": "success",
+ "message": "served from cache",
+ "queries": [{"status": "success", "data": []}],
+ },
+ {
+ "queries": [
+ {"status": QueryStatus.SUCCESS, "message": "no rows", "data": []}
+ ]
+ },
+ {"queries": [{"status": "running", "message": "in progress", "data": []}]},
+ {"queries": [{"message": "informational", "data": []}]},
+ {"queries": [{"data": []}]},
+ ],
+)
+def test_query_result_failure_allows_valid_and_informational_envelopes(payload):
+ """Successful statuses may carry a message; ``message`` alone is no failure."""
+ assert query_result_failure(payload) is None
+
+
+def test_query_result_failure_rejects_envelope_without_any_query():
+ """Envelope shape is validated as strictly as embedded failures.
+
+ ``query_result_failure`` is a strict envelope validator, not only an
+ embedded-failure detector. Every caller reads data from at least one query,
+ so a success status carrying no query payload fails closed instead of being
+ reported as failure-free.
+ """
+ failure = query_result_failure(
+ {"status": "success", "message": "served from cache", "queries": []}
+ )
+
+ assert failure is not None
+ assert failure.error_type == "InvalidQueryResult"
+
+
@pytest.mark.parametrize(
"payload",
[