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]>
127 lines
4.1 KiB
Python
127 lines
4.1 KiB
Python
import time
|
|
import pytest
|
|
from helpers.cluster import ClickHouseCluster
|
|
from helpers.test_tools import wait_condition
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def started_cluster():
|
|
global cluster
|
|
try:
|
|
cluster = ClickHouseCluster(__file__)
|
|
cluster.add_instance(
|
|
"test_disk_checker",
|
|
main_configs=["config.xml"],
|
|
with_minio=False,
|
|
with_zookeeper=False,
|
|
with_remote_database_disk=False,
|
|
stay_alive=True,
|
|
)
|
|
cluster.start()
|
|
|
|
node = cluster.instances["test_disk_checker"]
|
|
node.exec_in_container(["bash", "-c", "mkdir -p /var/lib/clickhouse/path1"])
|
|
node.exec_in_container(["bash", "-c", "mkdir -p /var/lib/clickhouse/path2"])
|
|
|
|
yield cluster
|
|
finally:
|
|
cluster.shutdown()
|
|
|
|
|
|
def get_metric_value(node, metric_name):
|
|
result = node.query(
|
|
f"SELECT value FROM system.metrics WHERE metric = '{metric_name}'"
|
|
).strip()
|
|
return int(result) if result else 0
|
|
|
|
|
|
def test_disk_checker_started_log(started_cluster):
|
|
node = cluster.instances["test_disk_checker"]
|
|
|
|
# ensure that the disk checker log line exists in server logs
|
|
def assert_log_exists(disk_name):
|
|
expected_log = f"Disk check for disk {disk_name} started with period 1.00 s"
|
|
count = node.count_in_log(expected_log)
|
|
return int(count) > 0
|
|
|
|
wait_condition(lambda: assert_log_exists('test1'), lambda x: x, max_attempts=10, delay=1)
|
|
wait_condition(lambda: assert_log_exists('test2'), lambda x: x, max_attempts=10, delay=1)
|
|
|
|
|
|
def test_disk_readonly_status(started_cluster):
|
|
try:
|
|
node = cluster.instances["test_disk_checker"]
|
|
disk_path = "/var/lib/clickhouse/path1"
|
|
|
|
# a hack to make disk readonly
|
|
node.exec_in_container(["mount", "--bind", disk_path, disk_path])
|
|
# need to retry making the dir readonly because periodic task creates temporary files there to check for write access
|
|
mount_read_only_succeded = False
|
|
for retry in range(10):
|
|
try:
|
|
node.exec_in_container(["mount", "-o", "remount,ro,bind", disk_path])
|
|
mount_read_only_succeded = True
|
|
break;
|
|
except Exception:
|
|
time.sleep(0.42);
|
|
assert mount_read_only_succeded;
|
|
|
|
# assert for metric with retries
|
|
wait_condition(
|
|
func=lambda: get_metric_value(node, "ReadonlyDisks"),
|
|
condition=lambda value: value == 1,
|
|
max_attempts=10,
|
|
delay=1,
|
|
)
|
|
|
|
# restore the disk to writable state
|
|
node.exec_in_container(["mount", "-o", "remount,rw,bind", disk_path])
|
|
|
|
# again assert for metric with retries
|
|
wait_condition(
|
|
func=lambda: get_metric_value(node, "ReadonlyDisks"),
|
|
condition=lambda value: value == 0,
|
|
max_attempts=10,
|
|
delay=1,
|
|
)
|
|
finally:
|
|
try:
|
|
node.exec_in_container(["umount", disk_path])
|
|
except:
|
|
pass
|
|
|
|
|
|
def test_disk_broken_status(started_cluster):
|
|
try:
|
|
node = cluster.instances["test_disk_checker"]
|
|
disk_path = "/var/lib/clickhouse/path2"
|
|
|
|
# move the directory to simulate a borken disk
|
|
node.exec_in_container(["mv", disk_path, f"{disk_path}_broken"])
|
|
|
|
# assert for metric with retries
|
|
wait_condition(
|
|
func=lambda: get_metric_value(node, "BrokenDisks"),
|
|
condition=lambda value: value == 1,
|
|
max_attempts=10,
|
|
delay=1,
|
|
)
|
|
|
|
# restore the previously moved directory
|
|
node.exec_in_container(["mv", f"{disk_path}_broken", disk_path])
|
|
# it looks like clickhouse needs to be restarted to recover from broken disk
|
|
node.restart_clickhouse()
|
|
|
|
# again assert for metric with retries
|
|
wait_condition(
|
|
func=lambda: get_metric_value(node, "BrokenDisks"),
|
|
condition=lambda value: value == 0,
|
|
max_attempts=10,
|
|
delay=1,
|
|
)
|
|
finally:
|
|
try:
|
|
node.exec_in_container(["mv", f"{disk_path}_broken", disk_path])
|
|
except:
|
|
pass
|