ClickHouse/tests/integration/test_library_bridge/test_exiled.py
2024-11-21 09:53:31 +00:00

100 lines
2.8 KiB
Python

import logging
import os
import os.path as p
import time
import pytest
from helpers.cluster import ClickHouseCluster, run_and_check
from test_library_bridge.test import create_dict_simple
cluster = ClickHouseCluster(__file__)
instance = cluster.add_instance(
"instance",
dictionaries=["configs/dictionaries/dict1.xml"],
main_configs=["configs/config.d/config.xml"],
stay_alive=True,
)
@pytest.fixture(scope="module")
def ch_cluster():
try:
cluster.start()
instance.query("CREATE DATABASE test")
instance.copy_file_to_container(
os.path.join(
os.path.dirname(os.path.realpath(__file__)), "configs/dict_lib.cpp"
),
"/etc/clickhouse-server/config.d/dictionaries_lib/dict_lib.cpp",
)
instance.query("SYSTEM RELOAD CONFIG")
instance.exec_in_container(
[
"bash",
"-c",
"/usr/bin/g++ -shared -o /etc/clickhouse-server/config.d/dictionaries_lib/dict_lib.so -fPIC /etc/clickhouse-server/config.d/dictionaries_lib/dict_lib.cpp",
],
user="root",
)
yield cluster
finally:
cluster.shutdown()
def test_bridge_dies_with_parent(ch_cluster):
if instance.is_built_with_memory_sanitizer():
pytest.skip("Memory Sanitizer cannot work with third-party shared libraries")
if instance.is_built_with_address_sanitizer():
pytest.skip(
"Leak sanitizer falsely reports about a leak of 16 bytes in clickhouse-odbc-bridge"
)
create_dict_simple(instance)
result = instance.query("""select dictGet(lib_dict_c, 'value1', toUInt64(1));""")
assert result.strip() == "101"
clickhouse_pid = instance.get_process_pid("clickhouse server")
bridge_pid = instance.get_process_pid("library-bridge")
assert clickhouse_pid is not None
assert bridge_pid is not None
try:
instance.exec_in_container(
["kill", str(clickhouse_pid)], privileged=True, user="root"
)
except:
pass
for i in range(60):
time.sleep(1)
clickhouse_pid = instance.get_process_pid("clickhouse server")
if clickhouse_pid is None:
break
for i in range(60):
time.sleep(1)
bridge_pid = instance.get_process_pid("library-bridge")
if bridge_pid is None:
break
if bridge_pid:
out = instance.exec_in_container(
["gdb", "-p", str(bridge_pid), "--ex", "thread apply all bt", "--ex", "q"],
privileged=True,
user="root",
)
logging.debug(f"Bridge is running, gdb output:\n{out}")
try:
assert clickhouse_pid is None
assert bridge_pid is None
finally:
instance.start_clickhouse(60)
instance.query("DROP DICTIONARY lib_dict_c")