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()
|
ver, _ = get_server_versions()
|
||||||
return not (ver >= (2, 0, 13) or ver >= (2, 1, 3))
|
return not (ver >= (2, 0, 13) or ver >= (2, 1, 3))
|
||||||
|
|
||||||
|
|
||||||
def setup_connection(keyspace_name):
|
def setup_connection(keyspace_name):
|
||||||
connection.setup(['127.0.0.1'],
|
connection.setup(['127.0.0.1'],
|
||||||
consistency=ConsistencyLevel.ONE,
|
consistency=ConsistencyLevel.ONE,
|
||||||
|
|||||||
@@ -27,10 +27,17 @@ from cassandra.cqlengine import CQLEngineException
|
|||||||
from cassandra.cqlengine.management import sync_table
|
from cassandra.cqlengine.management import sync_table
|
||||||
from cassandra.cqlengine.management import drop_table
|
from cassandra.cqlengine.management import drop_table
|
||||||
from cassandra.cqlengine.models import Model
|
from cassandra.cqlengine.models import Model
|
||||||
|
from cassandra.query import SimpleStatement
|
||||||
from cassandra.util import Date, Time
|
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 import PROTOCOL_VERSION
|
||||||
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
||||||
|
from tests.integration.cqlengine import DEFAULT_KEYSPACE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestModel(Model):
|
class TestModel(Model):
|
||||||
@@ -638,6 +645,160 @@ class TestQuerying(BaseCassEngTestCase):
|
|||||||
self.assertTrue(inst.date == day)
|
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():
|
def test_none_filter_fails():
|
||||||
class NoneFilterModel(Model):
|
class NoneFilterModel(Model):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user