schema: add validation for PERCENTILE values in speculative_retry configuration

This commit addresses issue #21825, where invalid PERCENTILE values for
the `speculative_retry` setting were not properly handled, causing potential
server crashes. The valid range for PERCENTILE is between 0 and 100, as defined
in the documentation for speculative retry options, where values above 100 or
below 0 are invalid and should be rejected.

The added validation ensures that such invalid values are rejected with a clear
error message, improving system stability and user experience.

Fixes #21825

Closes scylladb/scylladb#21879
This commit is contained in:
aberry-21
2024-12-27 12:57:40 +00:00
committed by Botond Dénes
parent ed4bfad5c3
commit 69a0431cce
2 changed files with 32 additions and 1 deletions

View File

@@ -84,6 +84,10 @@ speculative_retry::from_sstring(sstring str) {
} else if (str.compare(str.size() - percentile.size(), percentile.size(), percentile) == 0) {
t = type::PERCENTILE;
v = convert(percentile) / 100;
if (v <= 0.0 || v >= 1.0) {
throw exceptions::configuration_exception(
format("Invalid value {} for PERCENTILE option 'speculative_retry': must be between (0.0 and 100.0)", str));
}
} else {
throw std::invalid_argument(format("cannot convert {} to speculative_retry\n", str));
}

View File

@@ -4,9 +4,10 @@
# Tests for alter table statement
import time
import re
import pytest
from cassandra.protocol import ConfigurationException
from .util import new_test_table, unique_name
from .nodetool import flush
@@ -69,3 +70,29 @@ def testDropColumnWithTimestampPreparedNonExistingSchema(scylla_only, cql, test_
])
finally:
cql.execute(f"DROP TABLE {table}")
@pytest.mark.parametrize("percentile", ["-1.1", "-1", "-0", "0", "+0", "100", "+100", "101", "+101", "+101.1"])
def test_invalid_percentile_speculative_retry_values(cql, test_keyspace, percentile):
"""
In test_invalid_percentile_speculative_retry_values, we verify that invalid values for the
PERCENTILE option in the `speculative_retry` setting are properly rejected. According to the
documentation (https://enterprise.docs.scylladb.com/stable/cql/ddl.html#speculative-retry-options),
the valid range for PERCENTILE is between 0.0 and 100.0.
This test ensures that the system correctly rejects invalid inputs such as negative values
or values exceeding the maximum. Additionally, it verifies the correct handling of valid
but less common formats, such as values with a "+" sign.
See issue #21825.
"""
# For negative values and zero, Cassandra returns a shortened error message compared to ScyllaDB.
# Therefore, a regular expression is used to match both formats of the error message.
message = (
f"Invalid value {re.escape(percentile)}PERCENTILE "
r"for (?:PERCENTILE option|option) 'speculative_retry'"
r"(?:\: must be between \(0\.0 and 100\.0\))?"
)
with new_test_table(cql, test_keyspace, "id UUID PRIMARY KEY, value TEXT") as table:
with pytest.raises(ConfigurationException, match=message):
cql.execute(f"ALTER TABLE {table} WITH speculative_retry = '{percentile}PERCENTILE'")