Files
scylladb/test/cql-pytest/test_tablets.py
Pavel Emelyanov 8910d37994 keyspace_metadata: Include tablets property in DESCRIBE
When tablets are enabled and a keyspace being described has them
explicitly disabled or non-automatic initial value of zero, include this
into the returned describe statement too

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
2024-02-05 12:49:20 +03:00

110 lines
6.0 KiB
Python

# Copyright 2023-present ScyllaDB
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#############################################################################
# Some tests for the new "tablets"-based replication, replicating the old
# "vnodes". Eventually, ScyllaDB will use tablets by default and all tests
# will run using tablets, but these tests are for specific issues discovered
# while developing tablets that didn't exist for vnodes. Note that most tests
# for tablets require multiple nodes, and are in the test/topology*
# directory, so here we'll probably only ever have a handful of single-node
# tests.
#############################################################################
import pytest
from util import new_test_keyspace, new_test_table, unique_name
from cassandra.protocol import ConfigurationException, InvalidRequest
# A fixture similar to "test_keyspace", just creates a keyspace that enables
# tablets with initial_tablets=128
# The "initial_tablets" feature doesn't work if the "tablets" experimental
# feature is not turned on; In such a case, the tests using this fixture
# will be skipped.
@pytest.fixture(scope="module")
def test_keyspace_128_tablets(cql, this_dc):
name = unique_name()
try:
cql.execute("CREATE KEYSPACE " + name + " WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', '" + this_dc + "': 1 } AND TABLETS = { 'enabled': true, 'initial': 128 }")
except ConfigurationException:
pytest.skip('Scylla does not support initial_tablets, or the tablets feature is not enabled')
yield name
cql.execute("DROP KEYSPACE " + name)
# In the past (issue #16493), repeatedly creating and deleting a table
# would leak memory. Creating a table with 128 tablets would make this
# leak 128 times more serious and cause a failure faster. This is a
# reproducer for this problem. We basically expect this test not to
# OOM Scylla - the test doesn't "check" anything, the way it failed was
# for Scylla to run out of memory and then fail one of the CREATE TABLE
# or DROP TABLE operations in the loop.
# Note that this test doesn't even involve any data inside the table.
# Reproduces #16493.
def test_create_loop_with_tablets(cql, test_keyspace_128_tablets):
table = test_keyspace_128_tablets + "." + unique_name()
for i in range(100):
cql.execute(f"CREATE TABLE {table} (p int PRIMARY KEY, v int)")
cql.execute("DROP TABLE " + table)
# Converting vnodes-based keyspace to tablets-based in not implemented yet
def test_alter_cannot_change_vnodes_to_tablets(cql, skip_without_tablets):
ksdef = "WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'replication_factor' : '1' } AND TABLETS = { 'enabled' : false }"
with new_test_keyspace(cql, ksdef) as keyspace:
with pytest.raises(InvalidRequest, match="Cannot alter replication strategy vnode/tablets flavor"):
cql.execute(f"ALTER KEYSPACE {keyspace} WITH replication = {{'class': 'NetworkTopologyStrategy', 'replication_factor': 1}} AND tablets = {{'initial': 1}};")
# Converting vnodes-based keyspace to tablets-based in not implemented yet
def test_alter_doesnt_enable_tablets(cql, skip_without_tablets):
ksdef = "WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"
with new_test_keyspace(cql, ksdef) as keyspace:
cql.execute(f"ALTER KEYSPACE {keyspace} WITH replication = {{'class': 'NetworkTopologyStrategy'}};")
res = cql.execute(f"DESCRIBE KEYSPACE {keyspace}").one()
assert "NetworkTopologyStrategy" in res.create_statement
res = cql.execute(f"SELECT * FROM system_schema.scylla_keyspaces WHERE keyspace_name = '{keyspace}'")
assert len(list(res)) == 0, "tablets replication strategy turned on"
def test_tablet_default_initialization(cql, skip_without_tablets):
ksdef = "WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1};"
with new_test_keyspace(cql, ksdef) as keyspace:
res = cql.execute(f"SELECT * FROM system_schema.scylla_keyspaces WHERE keyspace_name = '{keyspace}'").one()
assert res.initial_tablets == 0, "initial_tablets not configured"
with new_test_table(cql, keyspace, "pk int PRIMARY KEY, c int") as table:
table = table.split('.')[1]
res = cql.execute("SELECT * FROM system.tablets")
for row in res:
if row.keyspace_name == keyspace and row.table_name == table:
assert row.tablet_count > 0, "zero tablets allocated"
break
else:
assert False, "tablets not allocated"
def test_tablets_can_be_explicitly_disabled(cql, skip_without_tablets):
ksdef = "WITH REPLICATION = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1} AND TABLETS = {'enabled': false};"
with new_test_keyspace(cql, ksdef) as keyspace:
res = cql.execute(f"SELECT * FROM system_schema.scylla_keyspaces WHERE keyspace_name = '{keyspace}'")
assert len(list(res)) == 0, "tablets replication strategy turned on"
def test_alter_changes_initial_tablets(cql, skip_without_tablets):
ksdef = "WITH replication = {'class': 'NetworkTopologyStrategy', 'replication_factor': 1} AND tablets = {'initial': 1};"
with new_test_keyspace(cql, ksdef) as keyspace:
cql.execute(f"ALTER KEYSPACE {keyspace} WITH replication = {{'class': 'NetworkTopologyStrategy', 'replication_factor': 1}} AND tablets = {{'initial': 2}};")
res = cql.execute(f"SELECT * FROM system_schema.scylla_keyspaces WHERE keyspace_name = '{keyspace}'").one()
assert res.initial_tablets == 2
# Test that initial number of tablets is preserved in describe
def test_describe_initial_tablets(cql, skip_without_tablets):
ksdef = "WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'replication_factor' : '1' } " \
"AND TABLETS = { 'initial' : 1 }"
with new_test_keyspace(cql, ksdef) as keyspace:
desc = cql.execute(f"DESCRIBE KEYSPACE {keyspace}")
assert "and tablets = {'initial': 1}" in desc.one().create_statement.lower()