mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
Follow-up to #105171, which added `ruff` with a deliberately narrow, bug-class-only rule set and left the unused-name and star-import rules off pending a dedicated cleanup pass. This enables that second batch in `pyproject.toml` and fixes every violation across the tree (the bulk in integration tests): - `F401` unused-import and `F841` unused-variable: removed, preserving any side-effecting right-hand side (e.g. `result = node.query(...)` becomes `node.query(...)`). Two `try: import ...` feature probes are kept with `# noqa: F401`. - `F541` f-string-missing-placeholders: dropped the redundant `f` prefix. - `F403`/`F405` star imports: every `from module import *` is expanded into explicit imports of the names actually used, taken from each name's real origin, so stdlib/third-party names import from their real source rather than through a test "convenience bundle". The now-empty `tests/integration/helpers/kafka/common_direct.py` bundle is removed and its three remaining consumers import `_VarintBytes`/`KafkaAdminClient` directly. Eliminating the star imports surfaced a real bug the wildcard had masked from `F821`: `generate_presets.py` in `test_prometheus_protocols` called an undefined `execute_instant_query_with_http_api`; fixed to the existing `execute_query_via_http_api`. No `black`/`isort` reformatting was applied (neither is enforced in the style check), so the diff is limited to the lint fixes themselves. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
"""
|
|
This test makes sure interserver cluster queries handle invalid DNS
|
|
records for replicas.
|
|
"""
|
|
|
|
import multiprocessing.dummy
|
|
from contextlib import contextmanager
|
|
|
|
from helpers.client import QueryRuntimeException
|
|
from helpers.cluster import ClickHouseCluster, ClickHouseInstance
|
|
|
|
|
|
def bootstrap(cluster: ClickHouseCluster):
|
|
node: ClickHouseInstance
|
|
for node in cluster.instances.values():
|
|
node_number = int(node.name[-1])
|
|
|
|
# getaddrinfo(...) may hang for a log time without these options.
|
|
node.exec_in_container(
|
|
[
|
|
"bash",
|
|
"-c",
|
|
'echo -e "options timeout:1\noptions attempts:1" >> /etc/resolv.conf',
|
|
],
|
|
privileged=True,
|
|
user="root",
|
|
)
|
|
|
|
node.query("DROP DATABASE IF EXISTS r0")
|
|
node.query("CREATE DATABASE r0")
|
|
node.query("CREATE TABLE r0.test_data(v UInt64) ENGINE = Memory()")
|
|
node.query(
|
|
f"INSERT INTO r0.test_data SELECT number + {node_number} * 10 FROM numbers(10)"
|
|
)
|
|
node.query(
|
|
"""CREATE TABLE default.test AS r0.test_data ENGINE = Distributed(cluster_missing_replica, 'r0', test_data, rand())"""
|
|
)
|
|
|
|
|
|
@contextmanager
|
|
def start_cluster():
|
|
cluster = ClickHouseCluster(__file__)
|
|
# node1 is missing on purpose to test DNS resolution errors.
|
|
# It exists in configs/remote_servers.xml to create the failure condition.
|
|
for node in ["node2", "node3", "node4"]:
|
|
cluster.add_instance(node, main_configs=["configs/remote_servers.xml"])
|
|
try:
|
|
cluster.start()
|
|
bootstrap(cluster)
|
|
yield cluster
|
|
finally:
|
|
cluster.shutdown()
|
|
|
|
|
|
def test_query():
|
|
with start_cluster() as cluster:
|
|
n_queries = 16
|
|
|
|
# thread-based pool
|
|
p = multiprocessing.dummy.Pool(n_queries)
|
|
|
|
def send_query(x):
|
|
try:
|
|
# queries start at operational shard 2, and will hit either the
|
|
# 'normal' node2 or the missing node1 on shard 1.
|
|
node = (
|
|
cluster.instances["node3"]
|
|
if (x % 2 == 0)
|
|
else cluster.instances["node4"]
|
|
)
|
|
# numbers between 0 and 19 are on the first ("broken") shard.
|
|
# we need to make sure we're querying them successfully
|
|
assert node.query(
|
|
"SELECT count() FROM default.test where v < (rand64() % 20)"
|
|
)
|
|
return 1
|
|
except QueryRuntimeException as e:
|
|
# DNS_ERROR because node1 doesn't exist.
|
|
assert 198 == e.returncode
|
|
# We shouldn't be getting here due to interserver retries.
|
|
raise
|
|
|
|
p.map(send_query, range(n_queries))
|