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
	 GregBestland
					GregBestland