From 3143b0eebbcf388444329e62b68cd569c9306932 Mon Sep 17 00:00:00 2001 From: Nikos Dragazis Date: Mon, 22 Sep 2025 15:27:17 +0300 Subject: [PATCH] test/cluster: Add tests for invalid SSTable compression options Complementary to the previous patch. It triggers semantic validation checks in `compression_parameters::validate()` and expects the server to exit. The tests examine both command line and YAML options. Signed-off-by: Nikos Dragazis (cherry picked from commit 8410532fa05243648fe3a622d896fbc021ba2fb7) --- .../test_sstable_compression_config.py | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 test/cluster/test_sstable_compression_config.py diff --git a/test/cluster/test_sstable_compression_config.py b/test/cluster/test_sstable_compression_config.py new file mode 100644 index 0000000000..1f6a01ee77 --- /dev/null +++ b/test/cluster/test_sstable_compression_config.py @@ -0,0 +1,108 @@ +# +# Copyright (C) 2025-present ScyllaDB +# +# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 +# + +import pytest +import logging + +from test.pylib.manager_client import ManagerClient + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + + +def yaml_to_cmdline(config): + cmdline = [] + for k, v in config.items(): + if isinstance(v, dict): + v = ','.join([f'{kk}={vv}' for kk, vv in v.items()]) + cmdline.append(f'--{k.replace("_", "-")}') + cmdline.append(str(v)) + return cmdline + + +@pytest.mark.asyncio +@pytest.mark.parametrize('cfg_source', ['yaml', 'cmdline']) +async def test_dict_compression_not_allowed(manager: ManagerClient, cfg_source: str): + config = { + 'sstable_compression_dictionaries_allow_in_ddl': False, + 'sstable_compression_user_table_options': { + 'sstable_compression': 'ZstdWithDictsCompressor', + 'chunk_length_in_kb': 4, + 'compression_level': 10 + } + } + expected_error = 'Invalid sstable_compression_user_table_options: sstable_compression ZstdWithDictsCompressor has been disabled by `sstable_compression_dictionaries_allow_in_ddl: false`' + + if cfg_source == 'yaml': + await manager.server_add(config=config, expected_error=expected_error) + else: + await manager.server_add(cmdline=yaml_to_cmdline(config), expected_error=expected_error) + + +@pytest.mark.asyncio +@pytest.mark.parametrize('cfg_source', ['yaml', 'cmdline']) +async def test_chunk_size_negative(manager: ManagerClient, cfg_source: str): + config = { + 'sstable_compression_user_table_options': { + 'sstable_compression': 'LZ4Compressor', + 'chunk_length_in_kb': -1 + } + } + expected_error = 'Invalid sstable_compression_user_table_options: Invalid negative or null for chunk_length_in_kb/chunk_length_kb' + if cfg_source == 'yaml': + await manager.server_add(config=config, expected_error=expected_error) + else: + await manager.server_add(cmdline=yaml_to_cmdline(config), expected_error=expected_error) + + +@pytest.mark.asyncio +@pytest.mark.parametrize('cfg_source', ['yaml', 'cmdline']) +async def test_chunk_size_beyond_max(manager: ManagerClient, cfg_source: str): + config = { + 'sstable_compression_user_table_options': { + 'sstable_compression': 'LZ4Compressor', + 'chunk_length_in_kb': 256 + } + } + expected_error = 'Invalid sstable_compression_user_table_options: chunk_length_in_kb/chunk_length_kb must be 128 or less.' + if cfg_source == 'yaml': + await manager.server_add(config=config, expected_error=expected_error) + else: + await manager.server_add(cmdline=yaml_to_cmdline(config), expected_error=expected_error) + + +@pytest.mark.asyncio +@pytest.mark.parametrize('cfg_source', ['yaml', 'cmdline']) +async def test_chunk_size_not_power_of_two(manager: ManagerClient, cfg_source: str): + config = { + 'sstable_compression_user_table_options': { + 'sstable_compression': 'LZ4Compressor', + 'chunk_length_in_kb': 3 + } + } + expected_error = 'Invalid sstable_compression_user_table_options: chunk_length_in_kb/chunk_length_kb must be a power of 2.' + + if cfg_source == 'yaml': + await manager.server_add(config=config, expected_error=expected_error) + else: + await manager.server_add(cmdline=yaml_to_cmdline(config), expected_error=expected_error) + + +@pytest.mark.asyncio +@pytest.mark.parametrize('cfg_source', ['yaml', 'cmdline']) +async def test_crc_check_chance_out_of_bounds(manager: ManagerClient, cfg_source: str): + config = { + 'sstable_compression_user_table_options': { + 'sstable_compression': 'LZ4Compressor', + 'chunk_length_in_kb': 128, + 'crc_check_chance': 1.1 + } + } + expected_error = 'Invalid sstable_compression_user_table_options: crc_check_chance must be between 0.0 and 1.0.' + if cfg_source == 'yaml': + await manager.server_add(config=config, expected_error=expected_error) + else: + await manager.server_add(cmdline=yaml_to_cmdline(config), expected_error=expected_error) \ No newline at end of file