PYTHON-535 Tests for cqlengine routing key generation
This commit is contained in:
@@ -38,6 +38,7 @@ def is_prepend_reversed():
|
||||
ver, _ = get_server_versions()
|
||||
return not (ver >= (2, 0, 13) or ver >= (2, 1, 3))
|
||||
|
||||
|
||||
def setup_connection(keyspace_name):
|
||||
connection.setup(['127.0.0.1'],
|
||||
consistency=ConsistencyLevel.ONE,
|
||||
|
||||
@@ -27,10 +27,17 @@ from cassandra.cqlengine import CQLEngineException
|
||||
from cassandra.cqlengine.management import sync_table
|
||||
from cassandra.cqlengine.management import drop_table
|
||||
from cassandra.cqlengine.models import Model
|
||||
from cassandra.query import SimpleStatement
|
||||
from cassandra.util import Date, Time
|
||||
from cassandra.cqltypes import Int32Type
|
||||
from cassandra.cqlengine.statements import SelectStatement, DeleteStatement, WhereClause
|
||||
from cassandra.cqlengine.operators import EqualsOperator
|
||||
|
||||
from tests.integration import PROTOCOL_VERSION
|
||||
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
||||
from tests.integration.cqlengine import DEFAULT_KEYSPACE
|
||||
|
||||
|
||||
|
||||
|
||||
class TestModel(Model):
|
||||
@@ -638,6 +645,160 @@ class TestQuerying(BaseCassEngTestCase):
|
||||
self.assertTrue(inst.date == day)
|
||||
|
||||
|
||||
class BasicModel(Model):
|
||||
__table_name__ = 'basic_model_routing'
|
||||
k = columns.Integer(primary_key=True)
|
||||
v = columns.Integer()
|
||||
|
||||
|
||||
class BasicModelMulti(Model):
|
||||
__table_name__ = 'basic_model_routing_multi'
|
||||
k = columns.Integer(partition_key=True)
|
||||
v = columns.Integer(partition_key=True)
|
||||
|
||||
|
||||
class ComplexModelRouting(Model):
|
||||
__table_name__ = 'complex_model_routing'
|
||||
partition = columns.UUID(partition_key=True, default=uuid4)
|
||||
cluster = columns.Integer(partition_key=True)
|
||||
count = columns.Integer()
|
||||
text = columns.Text(partition_key=True)
|
||||
float = columns.Float(partition_key=True)
|
||||
text_2 = columns.Text()
|
||||
|
||||
|
||||
class TestModelRoutingKeys(BaseCassEngTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestModelRoutingKeys, cls).setUpClass()
|
||||
sync_table(BasicModel)
|
||||
sync_table(BasicModelMulti)
|
||||
sync_table(ComplexModelRouting)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
super(TestModelRoutingKeys, cls).tearDownClass()
|
||||
drop_table(BasicModel)
|
||||
drop_table(BasicModelMulti)
|
||||
drop_table(ComplexModelRouting)
|
||||
|
||||
def test_routing_key_generation_basic(self):
|
||||
"""
|
||||
Compares the routing key generated by simple partition key using the model with the one generated by the equivalent
|
||||
bound statement
|
||||
@since 3.2
|
||||
@jira_ticket PYTHON-535
|
||||
@expected_result they should match
|
||||
|
||||
@test_category object_mapper
|
||||
"""
|
||||
|
||||
prepared = self.session.prepare(
|
||||
"""
|
||||
INSERT INTO {0}.basic_model_routing (k, v) VALUES (?, ?)
|
||||
""".format(DEFAULT_KEYSPACE))
|
||||
bound = prepared.bind((1, 2))
|
||||
|
||||
mrk = BasicModel._routing_key_from_values([1], self.session.cluster.protocol_version)
|
||||
simple = SimpleStatement("")
|
||||
simple.routing_key = mrk
|
||||
self.assertEqual(bound.routing_key, simple.routing_key)
|
||||
|
||||
def test_routing_key_generation_multi(self):
|
||||
"""
|
||||
Compares the routing key generated by composite partition key using the model with the one generated by the equivalent
|
||||
bound statement
|
||||
@since 3.2
|
||||
@jira_ticket PYTHON-535
|
||||
@expected_result they should match
|
||||
|
||||
@test_category object_mapper
|
||||
"""
|
||||
|
||||
prepared = self.session.prepare(
|
||||
"""
|
||||
INSERT INTO {0}.basic_model_routing_multi (k, v) VALUES (?, ?)
|
||||
""".format(DEFAULT_KEYSPACE))
|
||||
bound = prepared.bind((1, 2))
|
||||
mrk = BasicModelMulti._routing_key_from_values([1, 2], self.session.cluster.protocol_version)
|
||||
simple = SimpleStatement("")
|
||||
simple.routing_key = mrk
|
||||
self.assertEqual(bound.routing_key, simple.routing_key)
|
||||
|
||||
def test_routing_key_generation_complex(self):
|
||||
"""
|
||||
Compares the routing key generated by complex composite partition key using the model with the one generated by the equivalent
|
||||
bound statement
|
||||
@since 3.2
|
||||
@jira_ticket PYTHON-535
|
||||
@expected_result they should match
|
||||
|
||||
@test_category object_mapper
|
||||
"""
|
||||
prepared = self.session.prepare(
|
||||
"""
|
||||
INSERT INTO {0}.complex_model_routing (partition, cluster, count, text, float, text_2) VALUES (?, ?, ?, ?, ?, ?)
|
||||
""".format(DEFAULT_KEYSPACE))
|
||||
partition = uuid4()
|
||||
cluster = 1
|
||||
count = 2
|
||||
text = "text"
|
||||
float = 1.2
|
||||
text_2 = "text_2"
|
||||
bound = prepared.bind((partition, cluster, count, text, float, text_2))
|
||||
mrk = ComplexModelRouting._routing_key_from_values([partition, cluster, text, float], self.session.cluster.protocol_version)
|
||||
simple = SimpleStatement("")
|
||||
simple.routing_key = mrk
|
||||
self.assertEqual(bound.routing_key, simple.routing_key)
|
||||
|
||||
def test_partition_key_index(self):
|
||||
"""
|
||||
Test to ensure that statement partition key generation is in the correct order
|
||||
@since 3.2
|
||||
@jira_ticket PYTHON-535
|
||||
@expected_result .
|
||||
|
||||
@test_category object_mapper
|
||||
"""
|
||||
self._check_partition_value_generation(BasicModel, SelectStatement(BasicModel.__table_name__))
|
||||
self._check_partition_value_generation(BasicModel, DeleteStatement(BasicModel.__table_name__))
|
||||
self._check_partition_value_generation(BasicModelMulti, SelectStatement(BasicModelMulti.__table_name__))
|
||||
self._check_partition_value_generation(BasicModelMulti, DeleteStatement(BasicModelMulti.__table_name__))
|
||||
self._check_partition_value_generation(ComplexModelRouting, SelectStatement(ComplexModelRouting.__table_name__))
|
||||
self._check_partition_value_generation(ComplexModelRouting, DeleteStatement(ComplexModelRouting.__table_name__))
|
||||
self._check_partition_value_generation(BasicModel, SelectStatement(BasicModel.__table_name__), reverse=True)
|
||||
self._check_partition_value_generation(BasicModel, DeleteStatement(BasicModel.__table_name__), reverse=True)
|
||||
self._check_partition_value_generation(BasicModelMulti, SelectStatement(BasicModelMulti.__table_name__), reverse=True)
|
||||
self._check_partition_value_generation(BasicModelMulti, DeleteStatement(BasicModelMulti.__table_name__), reverse=True)
|
||||
self._check_partition_value_generation(ComplexModelRouting, SelectStatement(ComplexModelRouting.__table_name__), reverse=True)
|
||||
self._check_partition_value_generation(ComplexModelRouting, DeleteStatement(ComplexModelRouting.__table_name__), reverse=True)
|
||||
|
||||
def _check_partition_value_generation(self, model, state, reverse=False):
|
||||
"""
|
||||
This generates a some statements based on the partition_key_index of the model.
|
||||
It then validates that order of the partition key values in the statement matches the index
|
||||
specified in the models partition_key_index
|
||||
"""
|
||||
# Setup some unique values for statement generation
|
||||
uuid = uuid4()
|
||||
values = {'k': 5, 'v': 3, 'partition': uuid, 'cluster': 6, 'count': 42, 'text': 'text', 'float': 3.1415, 'text_2': 'text_2'}
|
||||
res = dict((v, k) for k, v in values.items())
|
||||
items = model._partition_key_index.items()
|
||||
if(reverse):
|
||||
items.reverse()
|
||||
# Add where clauses for each partition key
|
||||
for partition_key, position in items:
|
||||
wc = WhereClause(partition_key, EqualsOperator(), values.get(partition_key))
|
||||
state._add_where_clause(wc)
|
||||
|
||||
# Iterate over the partition key values check to see that their index matches
|
||||
# Those specified in the models partition field
|
||||
for indx, value in enumerate(state.partition_key_values(model._partition_key_index)):
|
||||
name = res.get(value)
|
||||
self.assertEqual(indx, model._partition_key_index.get(name))
|
||||
|
||||
|
||||
def test_none_filter_fails():
|
||||
class NoneFilterModel(Model):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user