2021-12-17 18:14:13 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# pylint: disable=line-too-long
|
|
|
|
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import multiprocessing
|
|
|
|
from tempfile import NamedTemporaryFile
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
CPU_ID = 4
|
|
|
|
|
|
|
|
|
|
|
|
def run_command_in_container(cmd, *args):
|
2022-01-07 18:44:06 +00:00
|
|
|
# /clickhouse is mounted by integration tests runner
|
2021-12-17 18:14:13 +00:00
|
|
|
alternative_binary = os.getenv("CLICKHOUSE_BINARY", "/clickhouse")
|
|
|
|
if alternative_binary:
|
|
|
|
args += (
|
|
|
|
"--volume",
|
|
|
|
f"{alternative_binary}:/usr/bin/clickhouse",
|
|
|
|
)
|
|
|
|
|
|
|
|
return subprocess.check_output(
|
2022-03-22 16:39:58 +00:00
|
|
|
[
|
2021-12-17 18:14:13 +00:00
|
|
|
"docker",
|
|
|
|
"run",
|
|
|
|
"--rm",
|
|
|
|
*args,
|
2023-06-22 23:46:29 +00:00
|
|
|
"ubuntu:22.04",
|
2021-12-17 18:14:13 +00:00
|
|
|
"sh",
|
|
|
|
"-c",
|
|
|
|
cmd,
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def run_with_cpu_limit(cmd, *args):
|
|
|
|
with NamedTemporaryFile() as online_cpu:
|
|
|
|
# NOTE: this is not the number of CPUs, but specific CPU ID
|
|
|
|
online_cpu.write(f"{CPU_ID}".encode())
|
|
|
|
online_cpu.flush()
|
|
|
|
|
|
|
|
# replace /sys/devices/system/cpu/online to full _SC_NPROCESSORS_ONLN
|
|
|
|
# like LXD/LXC from [1] does.
|
|
|
|
#
|
|
|
|
# [1]: https://github.com/ClickHouse/ClickHouse/issues/32806
|
|
|
|
args += (
|
|
|
|
"--volume",
|
|
|
|
f"{online_cpu.name}:/sys/devices/system/cpu/online",
|
|
|
|
)
|
|
|
|
|
|
|
|
return run_command_in_container(cmd, *args)
|
|
|
|
|
|
|
|
|
|
|
|
def skip_if_jemalloc_disabled():
|
|
|
|
output = run_command_in_container(
|
|
|
|
"""clickhouse local -q "
|
|
|
|
SELECT value FROM system.build_options WHERE name = 'USE_JEMALLOC'"
|
|
|
|
"""
|
|
|
|
).strip()
|
2021-12-22 07:50:41 +00:00
|
|
|
if output != b"ON" and output != b"1":
|
2022-04-17 22:16:53 +00:00
|
|
|
pytest.skip(f"Compiled without jemalloc (USE_JEMALLOC={output})")
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-12-17 18:14:13 +00:00
|
|
|
|
|
|
|
# Ensure that clickhouse works even when number of online CPUs
|
|
|
|
# (_SC_NPROCESSORS_ONLN) is smaller then available (_SC_NPROCESSORS_CONF).
|
|
|
|
#
|
|
|
|
# Refs: https://github.com/jemalloc/jemalloc/pull/2181
|
|
|
|
def test_jemalloc_percpu_arena():
|
2021-12-28 08:21:33 +00:00
|
|
|
skip_if_jemalloc_disabled()
|
2021-12-17 18:14:13 +00:00
|
|
|
|
|
|
|
assert multiprocessing.cpu_count() > CPU_ID
|
|
|
|
|
2021-12-22 07:49:03 +00:00
|
|
|
online_cpus = int(run_with_cpu_limit("getconf _NPROCESSORS_ONLN"))
|
|
|
|
assert online_cpus == 1, online_cpus
|
2021-12-17 18:14:13 +00:00
|
|
|
|
2021-12-22 07:49:03 +00:00
|
|
|
all_cpus = int(run_with_cpu_limit("getconf _NPROCESSORS_CONF"))
|
|
|
|
assert all_cpus == multiprocessing.cpu_count(), all_cpus
|
2021-12-17 18:14:13 +00:00
|
|
|
|
|
|
|
# implicitly disable percpu arena
|
|
|
|
result = run_with_cpu_limit(
|
|
|
|
'clickhouse local -q "select 1"',
|
|
|
|
# NOTE: explicitly disable, since it is enabled by default in debug build
|
|
|
|
# (and even though debug builds are not in CI let's state this).
|
|
|
|
"--env",
|
|
|
|
"MALLOC_CONF=abort_conf:false",
|
|
|
|
)
|
|
|
|
assert int(result) == int(1), result
|
|
|
|
|
|
|
|
# should fail because of abort_conf:true
|
|
|
|
with pytest.raises(subprocess.CalledProcessError):
|
|
|
|
run_with_cpu_limit(
|
|
|
|
'clickhouse local -q "select 1"', "--env", "MALLOC_CONF=abort_conf:true"
|
|
|
|
)
|
|
|
|
|
2021-12-22 07:49:03 +00:00
|
|
|
# should not fail even with abort_conf:true, due to explicit narenas
|
|
|
|
# NOTE: abort:false to make it compatible with debug build
|
|
|
|
run_with_cpu_limit(
|
|
|
|
'clickhouse local -q "select 1"',
|
|
|
|
"--env",
|
|
|
|
f"MALLOC_CONF=abort_conf:true,abort:false,narenas:{all_cpus}",
|
|
|
|
)
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-12-22 07:49:03 +00:00
|
|
|
|
2021-12-17 18:14:13 +00:00
|
|
|
# For manual run.
|
|
|
|
if __name__ == "__main__":
|
|
|
|
test_jemalloc_percpu_arena()
|