Files
scylladb/test/cqlpy/test_counter.py
Michael Litvak 1dbf53ca29 test: enable counters tests with tablets
Enable all counters-related tests that were disabled for tablets because
counters was not supported with tablets until now.

Some tests were parametrized to run with both vnodes and tablets, and
the tablets case was skipped, in order to not lose coverage. We change
them to run with the default configuration since now counters is
supported with both vnodes and tablets, and the implementation is the
same, so there is no benefit in running them with both configurations.
2025-11-03 16:04:37 +01:00

76 lines
3.8 KiB
Python

# Copyright 2023-present ScyllaDB
#
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
###############################################################################
# Tests for various operations on COUNTER columns.
# See also tests for casting involving counter columns in test_cast_data.py
###############################################################################
import pytest
from .util import new_test_table, unique_key_int
from cassandra.protocol import InvalidRequest
from .rest_api import scylla_inject_error
@pytest.fixture(scope="module")
def table1(cql, test_keyspace):
with new_test_table(cql, test_keyspace, "p int PRIMARY KEY, i bigint, v int") as table:
yield table
@pytest.fixture(scope="module")
def table2(cql, test_keyspace):
with new_test_table(cql, test_keyspace, "p int PRIMARY KEY, c counter") as table:
yield table
# Test that the function counterasblob() exists and works as expected -
# same as bigintasblob on the same number (a counter is a 64-bit number).
# Reproduces #14742
def test_counter_to_blob(cql, table1, table2):
p = unique_key_int()
cql.execute(f'UPDATE {table1} SET i = 1000 WHERE p = {p}')
cql.execute(f'UPDATE {table2} SET c = c + 1000 WHERE p = {p}')
expected = b'\x00\x00\x00\x00\x00\x00\x03\xe8'
assert [(expected,)] == list(cql.execute(f"SELECT bigintasblob(i) FROM {table1} WHERE p={p}"))
assert [(expected,)] == list(cql.execute(f"SELECT counterasblob(c) FROM {table2} WHERE p={p}"))
# Although the representation of the counter and bigint types are the
# same (64-bit), you can't use the wrong "*asblob()" function:
with pytest.raises(InvalidRequest, match='counterasblob'):
cql.execute(f"SELECT counterasblob(i) FROM {table1} WHERE p={p}")
# The opposite order is allowed in Scylla because of #14319, so let's
# split it into a second test test_counter_to_blob2:
@pytest.mark.xfail(reason="issue #14319")
def test_counter_to_blob2(cql, table1, table2):
p = unique_key_int()
cql.execute(f'UPDATE {table2} SET c = c + 1000 WHERE p = {p}')
# Reproduces #14319:
with pytest.raises(InvalidRequest, match='bigintasblob'):
cql.execute(f"SELECT bigintasblob(c) FROM {table2} WHERE p={p}")
# Test that the function blobascounter() exists and works as expected.
# Reproduces #14742
def test_counter_from_blob(cql, table1):
p = unique_key_int()
cql.execute(f'UPDATE {table1} SET i = 1000 WHERE p = {p}')
assert [(1000,)] == list(cql.execute(f"SELECT blobascounter(bigintasblob(i)) FROM {table1} WHERE p={p}"))
# blobascounter() must insist to receive a properly-sized (8-byte) blob.
# If it accepts a shorter blob (e.g., 4 bytes) and returns that to the driver,
# it will confuse the driver (the driver will expect to read 8 bytes for the
# bigint but will get only 4).
# We have test_native_functions.py::test_blobas_wrong_size() that verifies
# that this protection works for the bigint type, but it turns out it also
# needs to be separately enforced for the counter type.
def test_blobascounter_wrong_size(cql, table1):
p = unique_key_int()
cql.execute(f'UPDATE {table1} SET v = 1000 WHERE p = {p}')
with pytest.raises(InvalidRequest, match='blobascounter'):
cql.execute(f"SELECT blobascounter(intasblob(v)) FROM {table1} WHERE p={p}")
# Drop a table while there is a counter update operation in progress.
# Verify the table waits for the operation to complete before it's destroyed.
# Reproduces scylladb/scylla-enterprise#4475
def test_counter_update_while_table_dropped(cql, test_keyspace):
with new_test_table(cql, test_keyspace, "p int PRIMARY KEY, c counter") as table, \
scylla_inject_error(cql, "apply_counter_update_delay_5s", one_shot=True):
cql.execute_async(f'UPDATE {table} SET c = c + 1 WHERE p = 0')