mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
"""
|
|
Test that worker task failures in distributed plan queries are propagated
|
|
to the initiator with the correct error message instead of QUERY_WAS_CANCELLED.
|
|
|
|
Reproduces https://github.com/ClickHouse/clickhouse-private/issues/40546
|
|
(error-propagation part).
|
|
"""
|
|
|
|
import logging
|
|
import pytest
|
|
|
|
from helpers.cluster import ClickHouseCluster
|
|
from helpers.client import QueryRuntimeException
|
|
|
|
cluster = ClickHouseCluster(__file__)
|
|
|
|
node1 = cluster.add_instance(
|
|
"node1",
|
|
main_configs=["configs/config.d/stateless_worker.xml"],
|
|
stay_alive=True,
|
|
)
|
|
node2 = cluster.add_instance(
|
|
"node2",
|
|
main_configs=["configs/config.d/stateless_worker.xml"],
|
|
stay_alive=True,
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def started_cluster():
|
|
try:
|
|
cluster.start()
|
|
yield cluster
|
|
finally:
|
|
cluster.shutdown()
|
|
|
|
|
|
DISTRIBUTED_SETTINGS = (
|
|
"make_distributed_plan = 1, "
|
|
"enable_parallel_replicas = 0, "
|
|
"distributed_plan_default_shuffle_join_bucket_count = 2, "
|
|
"distributed_plan_default_reader_bucket_count = 2, "
|
|
"distributed_plan_max_rows_to_broadcast = 0"
|
|
)
|
|
|
|
|
|
def test_worker_error_not_masked(started_cluster):
|
|
"""A worker task error must surface to the initiator with the real error, not QUERY_WAS_CANCELLED.
|
|
|
|
The initiator sets max_rows_to_read = 5, which is propagated to the workers; each worker reads
|
|
more than 5 rows and fails with TOO_MANY_ROWS, and the initiator must report that. This also
|
|
covers settings propagation: without it the workers would not enforce the limit and the query
|
|
would silently succeed.
|
|
"""
|
|
for node in [node1, node2]:
|
|
node.query(
|
|
"CREATE TABLE IF NOT EXISTS test_err_mask (id UInt64) "
|
|
"ENGINE = MergeTree() ORDER BY id"
|
|
)
|
|
node.query("INSERT INTO test_err_mask SELECT number FROM numbers(10000)")
|
|
|
|
with pytest.raises(QueryRuntimeException) as exc_info:
|
|
node1.query(
|
|
f"""
|
|
SELECT sum(id)
|
|
FROM test_err_mask
|
|
SETTINGS {DISTRIBUTED_SETTINGS},
|
|
max_rows_to_read = 5
|
|
""",
|
|
timeout=30,
|
|
)
|
|
|
|
error_msg = str(exc_info.value)
|
|
logging.info(f"Query failed with: {error_msg}")
|
|
|
|
# The error should be the worker's limit failure, not QUERY_WAS_CANCELLED.
|
|
assert "QUERY_WAS_CANCELLED" not in error_msg, (
|
|
f"Initiator masked the worker error with QUERY_WAS_CANCELLED: {error_msg}"
|
|
)
|
|
assert (
|
|
"TOO_MANY_ROWS" in error_msg
|
|
or "max_rows_to_read" in error_msg
|
|
or "Limit for rows" in error_msg
|
|
), f"Expected the propagated max_rows_to_read limit to be enforced on the worker, got: {error_msg}"
|
|
|
|
for node in [node1, node2]:
|
|
node.query("DROP TABLE IF EXISTS test_err_mask")
|