Files
scylladb/test/cqlpy/test_name.py
Nadav Har'El 74a57d2872 test/cqlpy: remove unused imports
Remove many unused "import" statements or parts of import statement.
All of them were detected by Copilot, but I verified each one manually
and prepared this patch.

Signed-off-by: Nadav Har'El <nyh@scylladb.com>

Closes scylladb/scylladb#27675
2025-12-24 13:31:41 +02:00

177 lines
8.4 KiB
Python

# Copyright 2025-present ScyllaDB
#
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
#############################################################################
# Tests for limits on the *names* of keyspaces, tables, indexes, views, function and columns.
#############################################################################
import pytest
from contextlib import contextmanager
from cassandra.protocol import InvalidRequest
from .util import unique_name, new_test_table, new_secondary_index, new_function, is_scylla
# This context manager is similar to new_test_table() - creating a table and
# keeping it alive while the context manager is in scope - but allows the
# caller to pick the name of the table. This is useful to attempt to create
# a table whose name has different lengths or characters.
# Note that if used in a shared keyspace, it is recommended to base the
# given table name on the output of unique_name(), to avoid name clashes.
# See the padded_name() function below as an example.
@contextmanager
def new_named_table(cql, keyspace, table, schema, extra=""):
tbl = keyspace+'.'+table
cql.execute(f'CREATE TABLE {tbl} ({schema}) {extra}')
try:
yield tbl
finally:
cql.execute(f'DROP TABLE {tbl}')
# padded_name() creates a unique name of given length by taking the
# output of unique_name() and padding it with extra 'x' characters:
def padded_name(length):
u = unique_name()
assert length >= len(u)
return u + 'x'*(length-len(u))
# Utility function to create a new keyspace with the given name.
# Created to avoid passing the same replication option in every tests.
@contextmanager
def new_keyspace(cql, ks_name=unique_name()):
cql.execute(f"CREATE KEYSPACE {ks_name} WITH REPLICATION = {{'class': 'SimpleStrategy', 'replication_factor': 1}}")
try:
yield ks_name
finally:
cql.execute(f"DROP KEYSPACE {ks_name}")
# Utility function to create a new table with the given name.
# Created to avoid passing the same schema option in every tests.
@contextmanager
def new_table(cql, ks_name, tbl_name=unique_name(), extra=""):
qualified_table_name = ks_name + '.' + tbl_name
cql.execute(f'CREATE TABLE {qualified_table_name} (p int, x int, PRIMARY KEY (p)) {extra}')
try:
yield qualified_table_name
finally:
cql.execute(f'DROP TABLE {qualified_table_name}')
# Utility function to create a materialized view with the given name.
# Created to avoid passing the same parameter values in every tests.
@contextmanager
def new_mv(cql, qualified_table_name, mv_name):
keyspace = qualified_table_name.split('.')[0]
qualified_mv_name = keyspace + "." + mv_name
cql.execute(
f"CREATE MATERIALIZED VIEW {qualified_mv_name} AS SELECT * FROM {qualified_table_name} WHERE p is not null and x is not null PRIMARY KEY (p, x)"
)
try:
yield qualified_mv_name
finally:
cql.execute(f"DROP MATERIALIZED VIEW {qualified_mv_name}")
# Cassandra's documentation states that "Both keyspace and table name ... are
# limited in size to 48 characters". This was actually only true in Cassandra
# 3, and by Cassandra 4 and 5 this limitation was dropped (see discussion
# in CASSANDRA-20425).
# Test verifies that a 48-character name is allowed, and passes on all versions
# of Scylla and Cassandra.
def test_table_name_length_48(cql, test_keyspace):
with new_table(cql, test_keyspace, padded_name(48)):
pass
# After Cassandra removed the 48-character limit for table names, some applications began creating tables with longer names.
# ScyllaDB relaxed its own limit to maintain compatibility with these applications.
# Due to CDC-enabled tables, ScyllaDB enforces a 192-character limit (see schema::NAME_LENGTH for details),
# while Cassandra allows names up to 222 characters.
# The 192-character limit in ScyllaDB is considered sufficient for most use cases.
# Test verifies that a 192-character name is allowed, and passes on Scylla and latest Cassandra versions (4 and 5).
def test_table_name_length_192(cql, test_keyspace):
with new_table(cql, test_keyspace, padded_name(192)):
pass
# If we try an even longer table name length, e.g., 500 characters, we run
# into the problem that an attempt to create a file or directory name based
# on the table name will fail (due to filesystem capabilities). Even if we lift the 48-character limitation
# introduced in Cassandra 3, creating a 500-character name should fail gracefully.
# Test verifies that a 500-character name is rejected by ScyllaDB and Cassandra.
# We mark this test cassandra_bug because Cassandra 5 hangs on this test (CASSANDRA-20425 and CASSANDRA-20389).
def test_table_name_length_500(cql, test_keyspace, cassandra_bug):
name = padded_name(500)
with pytest.raises(InvalidRequest, match=name):
with new_table(cql, test_keyspace, name):
pass
# Test verifies that a 192-character name for CDC enabled table is accepted for Scylla and Cassandra 4/5.
def test_table_cdc_name_length_192(cql):
# Incompatible Cassandra <-> Scylla API to enable CDC. See #9859.
cdc = "{'enabled': true}" if is_scylla(cql) else 'true'
with new_keyspace(cql) as keyspace:
with new_table(cql, keyspace, padded_name(192), extra=f"with CDC = {cdc}"):
pass
# When ScyllaDB lifted the table name length restriction, it also lifted the limit on keyspace name length.
# However, Cassandra still enforces a 48-character limit for keyspace names.
# Test verifies that a keyspace name of exactly 48 characters is accepted by all versions of ScyllaDB and Cassandra.
def test_keyspace_name_length_48(cql):
with new_keyspace(cql, padded_name(48)):
pass
# Test verifies that a keyspace name of exactly 192 is accepted by ScyllaDB.
# Marked scylla_only because Cassandra keeps the 48-character limit for keyspace names.
def test_keyspace_name_length_192(cql, scylla_only):
with new_keyspace(cql, padded_name(192)):
pass
# Test verifies that too long keyspace (exceeding filesystem capabilities) is gracefully rejected.
def test_keyspace_name_length_500(cql):
name = padded_name(500)
with pytest.raises(InvalidRequest, match=name):
with new_keyspace(cql, name):
pass
# Test verifies that materialized view names follow the same length rules as table names.
def test_mv_name_length_192(cql, test_keyspace):
with new_table(cql, test_keyspace) as table:
with new_mv(cql, table, padded_name(192)):
pass
# Test verifies that materialized view names follow the same length rules as table names.
# Marked cassandra_bug because Cassandra 5 hangs on this test (CASSANDRA-20425 and CASSANDRA-20389).
def test_mv_name_length_500(cql, test_keyspace, cassandra_bug):
name = padded_name(500)
with new_table(cql, test_keyspace) as table:
with pytest.raises(InvalidRequest, match=name):
with new_mv(cql, table, name):
pass
# Test verifies that secondary index names follow the same length rules as table names.
def test_index_name_length_192(cql, test_keyspace):
with new_table(cql, test_keyspace) as table:
with new_secondary_index(cql, table, "x", padded_name(192)):
pass
# Test verifies that secondary index names follow the same length rules as table names.
# Marked cassandra_bug because Cassandra 5 hangs on this test (CASSANDRA-20425 and CASSANDRA-20389).
def test_index_name_length_500(cql, test_keyspace, cassandra_bug):
name = padded_name(500)
with new_table(cql, test_keyspace) as table:
with pytest.raises(InvalidRequest, match=name):
with new_secondary_index(cql, table, "x", name):
pass
# Test verifies that column names are not restricted by schema::NAME_LENGTH or filesystem constraints.
def test_function_name_500(cql, test_keyspace):
# ScyllaDB by default supports Lua functions while Cassandra Java only.
# In this test we only want to verify function name, hence function body is not important.
lang = "lua" if is_scylla(cql) else "java"
with new_function(cql, test_keyspace, f"() CALLED ON NULL INPUT RETURNS int LANGUAGE {lang} AS 'return 0;'",
name=padded_name(500)):
pass
# Test verifies that column names are not restricted by schema::NAME_LENGTH or filesystem constraints.
def test_column_name_500(cql, test_keyspace):
with new_test_table(cql, test_keyspace, "p int primary key, " + padded_name(500) + " int"):
pass
# TODO: add tests for the allowed characters in a table name