Adding decorator for counting underlying query execution, updating some tests to add expected query counts
This commit is contained in:
@@ -14,15 +14,23 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
|
try:
|
||||||
|
import unittest2 as unittest
|
||||||
|
except ImportError:
|
||||||
|
import unittest # noqa
|
||||||
from cassandra import ConsistencyLevel
|
from cassandra import ConsistencyLevel
|
||||||
|
|
||||||
from cassandra.cqlengine import connection
|
from cassandra.cqlengine import connection
|
||||||
from cassandra.cqlengine.management import create_keyspace_simple, CQLENG_ALLOW_SCHEMA_MANAGEMENT
|
from cassandra.cqlengine.management import create_keyspace_simple, CQLENG_ALLOW_SCHEMA_MANAGEMENT
|
||||||
|
import cassandra
|
||||||
|
|
||||||
from tests.integration import get_server_versions, use_single_node, PROTOCOL_VERSION
|
from tests.integration import get_server_versions, use_single_node, PROTOCOL_VERSION
|
||||||
DEFAULT_KEYSPACE = 'cqlengine_test'
|
DEFAULT_KEYSPACE = 'cqlengine_test'
|
||||||
|
|
||||||
|
|
||||||
|
CQL_SKIP_EXECUTE = bool(os.getenv('CQL_SKIP_EXECUTE', False))
|
||||||
|
|
||||||
|
|
||||||
def setup_package():
|
def setup_package():
|
||||||
warnings.simplefilter('always') # for testing warnings, make sure all are let through
|
warnings.simplefilter('always') # for testing warnings, make sure all are let through
|
||||||
os.environ[CQLENG_ALLOW_SCHEMA_MANAGEMENT] = '1'
|
os.environ[CQLENG_ALLOW_SCHEMA_MANAGEMENT] = '1'
|
||||||
@@ -44,3 +52,57 @@ def setup_connection(keyspace_name):
|
|||||||
consistency=ConsistencyLevel.ONE,
|
consistency=ConsistencyLevel.ONE,
|
||||||
protocol_version=PROTOCOL_VERSION,
|
protocol_version=PROTOCOL_VERSION,
|
||||||
default_keyspace=keyspace_name)
|
default_keyspace=keyspace_name)
|
||||||
|
|
||||||
|
|
||||||
|
class StatementCounter(object):
|
||||||
|
"""
|
||||||
|
Simple python object used to hold a count of the number of times
|
||||||
|
the wrapped method has been invoked
|
||||||
|
"""
|
||||||
|
def __init__(self, patched_func):
|
||||||
|
self.func = patched_func
|
||||||
|
self.counter = 0
|
||||||
|
|
||||||
|
def wrapped_execute(self, *args, **kwargs):
|
||||||
|
self.counter += 1
|
||||||
|
return self.func(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_counter(self):
|
||||||
|
return self.counter
|
||||||
|
|
||||||
|
|
||||||
|
def execute_count(expected):
|
||||||
|
"""
|
||||||
|
A decorator used wrap cassandra.cqlengine.connection.execute. It counts the number of times this method is invoked
|
||||||
|
then compares it to the number expected. If they don't match it throws an assertion error.
|
||||||
|
This function can be disabled by running the test harness with the env variable CQL_SKIP_EXECUTE=1 set
|
||||||
|
"""
|
||||||
|
def innerCounter(fn):
|
||||||
|
def wrapped_function(*args, **kwargs):
|
||||||
|
# Create a counter monkey patch into cassandra.cqlengine.connection.execute
|
||||||
|
count = StatementCounter(cassandra.cqlengine.connection.execute)
|
||||||
|
original_function = cassandra.cqlengine.connection.execute
|
||||||
|
# Monkey patch in our StatementCounter wrapper
|
||||||
|
cassandra.cqlengine.connection.execute = count.wrapped_execute
|
||||||
|
# Invoked the underlying unit test
|
||||||
|
to_return = fn(*args, **kwargs)
|
||||||
|
# Get the count from our monkey patched counter
|
||||||
|
count.get_counter()
|
||||||
|
# DeMonkey Patch our code
|
||||||
|
cassandra.cqlengine.connection.execute = original_function
|
||||||
|
# Check to see if the count is what you expect
|
||||||
|
tc = unittest.TestCase("__init__")
|
||||||
|
tc.assertEquals(count.get_counter(), expected, "Expected number of cassandra.cqlengine.connection.execute calls doesn't match actual number invoked Expected: {0}, Invoked {1}".format(count.get_counter(), expected))
|
||||||
|
return to_return
|
||||||
|
# Name of the wrapped function must match the original or unittest will error out.
|
||||||
|
wrapped_function.__name__ = fn.__name__
|
||||||
|
wrapped_function.__doc__ = fn.__doc__
|
||||||
|
# Escape hatch
|
||||||
|
if(CQL_SKIP_EXECUTE):
|
||||||
|
return fn
|
||||||
|
else:
|
||||||
|
return wrapped_function
|
||||||
|
|
||||||
|
return innerCounter
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from cassandra.cqlengine.management import drop_table, sync_table
|
|||||||
from cassandra.cqlengine.models import Model
|
from cassandra.cqlengine.models import Model
|
||||||
from cassandra.cqlengine.query import BatchQuery, DMLQuery
|
from cassandra.cqlengine.query import BatchQuery, DMLQuery
|
||||||
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
||||||
|
from tests.integration.cqlengine import execute_count
|
||||||
from cassandra.cluster import Session
|
from cassandra.cluster import Session
|
||||||
|
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
for obj in TestMultiKeyModel.filter(partition=self.pkey):
|
for obj in TestMultiKeyModel.filter(partition=self.pkey):
|
||||||
obj.delete()
|
obj.delete()
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_insert_success_case(self):
|
def test_insert_success_case(self):
|
||||||
|
|
||||||
b = BatchQuery()
|
b = BatchQuery()
|
||||||
@@ -67,6 +69,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
|
|
||||||
TestMultiKeyModel.get(partition=self.pkey, cluster=2)
|
TestMultiKeyModel.get(partition=self.pkey, cluster=2)
|
||||||
|
|
||||||
|
@execute_count(4)
|
||||||
def test_update_success_case(self):
|
def test_update_success_case(self):
|
||||||
|
|
||||||
inst = TestMultiKeyModel.create(partition=self.pkey, cluster=2, count=3, text='4')
|
inst = TestMultiKeyModel.create(partition=self.pkey, cluster=2, count=3, text='4')
|
||||||
@@ -84,6 +87,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
inst3 = TestMultiKeyModel.get(partition=self.pkey, cluster=2)
|
inst3 = TestMultiKeyModel.get(partition=self.pkey, cluster=2)
|
||||||
self.assertEqual(inst3.count, 4)
|
self.assertEqual(inst3.count, 4)
|
||||||
|
|
||||||
|
@execute_count(4)
|
||||||
def test_delete_success_case(self):
|
def test_delete_success_case(self):
|
||||||
|
|
||||||
inst = TestMultiKeyModel.create(partition=self.pkey, cluster=2, count=3, text='4')
|
inst = TestMultiKeyModel.create(partition=self.pkey, cluster=2, count=3, text='4')
|
||||||
@@ -99,6 +103,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
with self.assertRaises(TestMultiKeyModel.DoesNotExist):
|
with self.assertRaises(TestMultiKeyModel.DoesNotExist):
|
||||||
TestMultiKeyModel.get(partition=self.pkey, cluster=2)
|
TestMultiKeyModel.get(partition=self.pkey, cluster=2)
|
||||||
|
|
||||||
|
@execute_count(11)
|
||||||
def test_context_manager(self):
|
def test_context_manager(self):
|
||||||
|
|
||||||
with BatchQuery() as b:
|
with BatchQuery() as b:
|
||||||
@@ -112,6 +117,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
for i in range(5):
|
for i in range(5):
|
||||||
TestMultiKeyModel.get(partition=self.pkey, cluster=i)
|
TestMultiKeyModel.get(partition=self.pkey, cluster=i)
|
||||||
|
|
||||||
|
@execute_count(9)
|
||||||
def test_bulk_delete_success_case(self):
|
def test_bulk_delete_success_case(self):
|
||||||
|
|
||||||
for i in range(1):
|
for i in range(1):
|
||||||
@@ -127,6 +133,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
for m in TestMultiKeyModel.all():
|
for m in TestMultiKeyModel.all():
|
||||||
m.delete()
|
m.delete()
|
||||||
|
|
||||||
|
@execute_count(0)
|
||||||
def test_none_success_case(self):
|
def test_none_success_case(self):
|
||||||
""" Tests that passing None into the batch call clears any batch object """
|
""" Tests that passing None into the batch call clears any batch object """
|
||||||
b = BatchQuery()
|
b = BatchQuery()
|
||||||
@@ -137,6 +144,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
q = q.batch(None)
|
q = q.batch(None)
|
||||||
self.assertIsNone(q._batch)
|
self.assertIsNone(q._batch)
|
||||||
|
|
||||||
|
@execute_count(0)
|
||||||
def test_dml_none_success_case(self):
|
def test_dml_none_success_case(self):
|
||||||
""" Tests that passing None into the batch call clears any batch object """
|
""" Tests that passing None into the batch call clears any batch object """
|
||||||
b = BatchQuery()
|
b = BatchQuery()
|
||||||
@@ -147,6 +155,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
q.batch(None)
|
q.batch(None)
|
||||||
self.assertIsNone(q._batch)
|
self.assertIsNone(q._batch)
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_batch_execute_on_exception_succeeds(self):
|
def test_batch_execute_on_exception_succeeds(self):
|
||||||
# makes sure if execute_on_exception == True we still apply the batch
|
# makes sure if execute_on_exception == True we still apply the batch
|
||||||
drop_table(BatchQueryLogModel)
|
drop_table(BatchQueryLogModel)
|
||||||
@@ -166,6 +175,7 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
# should be 1 because the batch should execute
|
# should be 1 because the batch should execute
|
||||||
self.assertEqual(1, len(obj))
|
self.assertEqual(1, len(obj))
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_batch_execute_on_exception_skips_if_not_specified(self):
|
def test_batch_execute_on_exception_skips_if_not_specified(self):
|
||||||
# makes sure if execute_on_exception == True we still apply the batch
|
# makes sure if execute_on_exception == True we still apply the batch
|
||||||
drop_table(BatchQueryLogModel)
|
drop_table(BatchQueryLogModel)
|
||||||
@@ -186,12 +196,14 @@ class BatchQueryTests(BaseCassEngTestCase):
|
|||||||
# should be 0 because the batch should not execute
|
# should be 0 because the batch should not execute
|
||||||
self.assertEqual(0, len(obj))
|
self.assertEqual(0, len(obj))
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_batch_execute_timeout(self):
|
def test_batch_execute_timeout(self):
|
||||||
with mock.patch.object(Session, 'execute') as mock_execute:
|
with mock.patch.object(Session, 'execute') as mock_execute:
|
||||||
with BatchQuery(timeout=1) as b:
|
with BatchQuery(timeout=1) as b:
|
||||||
BatchQueryLogModel.batch(b).create(k=2, v=2)
|
BatchQueryLogModel.batch(b).create(k=2, v=2)
|
||||||
self.assertEqual(mock_execute.call_args[-1]['timeout'], 1)
|
self.assertEqual(mock_execute.call_args[-1]['timeout'], 1)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_batch_execute_no_timeout(self):
|
def test_batch_execute_no_timeout(self):
|
||||||
with mock.patch.object(Session, 'execute') as mock_execute:
|
with mock.patch.object(Session, 'execute') as mock_execute:
|
||||||
with BatchQuery() as b:
|
with BatchQuery() as b:
|
||||||
|
|||||||
@@ -20,15 +20,17 @@ from tests.integration.cqlengine.base import BaseCassEngTestCase
|
|||||||
|
|
||||||
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, ModelException
|
from cassandra.cqlengine.models import Model
|
||||||
from cassandra.cqlengine import columns
|
from cassandra.cqlengine import columns
|
||||||
from cassandra.cqlengine import query
|
from tests.integration.cqlengine import execute_count
|
||||||
|
|
||||||
|
|
||||||
class DateTimeQueryTestModel(Model):
|
class DateTimeQueryTestModel(Model):
|
||||||
|
|
||||||
user = columns.Integer(primary_key=True)
|
user = columns.Integer(primary_key=True)
|
||||||
day = columns.DateTime(primary_key=True)
|
day = columns.DateTime(primary_key=True)
|
||||||
data = columns.Text()
|
data = columns.Text()
|
||||||
|
|
||||||
|
|
||||||
class TestDateTimeQueries(BaseCassEngTestCase):
|
class TestDateTimeQueries(BaseCassEngTestCase):
|
||||||
|
|
||||||
@@ -46,12 +48,12 @@ class TestDateTimeQueries(BaseCassEngTestCase):
|
|||||||
data=str(uuid4())
|
data=str(uuid4())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
super(TestDateTimeQueries, cls).tearDownClass()
|
super(TestDateTimeQueries, cls).tearDownClass()
|
||||||
drop_table(DateTimeQueryTestModel)
|
drop_table(DateTimeQueryTestModel)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_range_query(self):
|
def test_range_query(self):
|
||||||
""" Tests that loading from a range of dates works properly """
|
""" Tests that loading from a range of dates works properly """
|
||||||
start = datetime(*self.base_date.timetuple()[:3])
|
start = datetime(*self.base_date.timetuple()[:3])
|
||||||
@@ -60,6 +62,7 @@ class TestDateTimeQueries(BaseCassEngTestCase):
|
|||||||
results = DateTimeQueryTestModel.filter(user=0, day__gte=start, day__lt=end)
|
results = DateTimeQueryTestModel.filter(user=0, day__gte=start, day__lt=end)
|
||||||
assert len(results) == 3
|
assert len(results) == 3
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_datetime_precision(self):
|
def test_datetime_precision(self):
|
||||||
""" Tests that millisecond resolution is preserved when saving datetime objects """
|
""" Tests that millisecond resolution is preserved when saving datetime objects """
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from cassandra.cqlengine.query import ResultObject
|
|||||||
from cassandra.concurrent import execute_concurrent_with_args
|
from cassandra.concurrent import execute_concurrent_with_args
|
||||||
from cassandra.cqlengine import models
|
from cassandra.cqlengine import models
|
||||||
|
|
||||||
from tests.integration.cqlengine import setup_connection
|
from tests.integration.cqlengine import setup_connection, execute_count
|
||||||
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
||||||
from tests.integration.cqlengine.query.test_queryset import BaseQuerySetUsage
|
from tests.integration.cqlengine.query.test_queryset import BaseQuerySetUsage
|
||||||
|
|
||||||
@@ -134,6 +134,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
cls.keyspace = NamedKeyspace(ks)
|
cls.keyspace = NamedKeyspace(ks)
|
||||||
cls.table = cls.keyspace.table(tn)
|
cls.table = cls.keyspace.table(tn)
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_count(self):
|
def test_count(self):
|
||||||
""" Tests that adding filtering statements affects the count query as expected """
|
""" Tests that adding filtering statements affects the count query as expected """
|
||||||
assert self.table.objects.count() == 12
|
assert self.table.objects.count() == 12
|
||||||
@@ -141,6 +142,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
q = self.table.objects(test_id=0)
|
q = self.table.objects(test_id=0)
|
||||||
assert q.count() == 4
|
assert q.count() == 4
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_query_expression_count(self):
|
def test_query_expression_count(self):
|
||||||
""" Tests that adding query statements affects the count query as expected """
|
""" Tests that adding query statements affects the count query as expected """
|
||||||
assert self.table.objects.count() == 12
|
assert self.table.objects.count() == 12
|
||||||
@@ -148,6 +150,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
q = self.table.objects(self.table.column('test_id') == 0)
|
q = self.table.objects(self.table.column('test_id') == 0)
|
||||||
assert q.count() == 4
|
assert q.count() == 4
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_iteration(self):
|
def test_iteration(self):
|
||||||
""" Tests that iterating over a query set pulls back all of the expected results """
|
""" Tests that iterating over a query set pulls back all of the expected results """
|
||||||
q = self.table.objects(test_id=0)
|
q = self.table.objects(test_id=0)
|
||||||
@@ -181,6 +184,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
compare_set.remove(val)
|
compare_set.remove(val)
|
||||||
assert len(compare_set) == 0
|
assert len(compare_set) == 0
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_multiple_iterations_work_properly(self):
|
def test_multiple_iterations_work_properly(self):
|
||||||
""" Tests that iterating over a query set more than once works """
|
""" Tests that iterating over a query set more than once works """
|
||||||
# test with both the filtering method and the query method
|
# test with both the filtering method and the query method
|
||||||
@@ -201,6 +205,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
compare_set.remove(val)
|
compare_set.remove(val)
|
||||||
assert len(compare_set) == 0
|
assert len(compare_set) == 0
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_multiple_iterators_are_isolated(self):
|
def test_multiple_iterators_are_isolated(self):
|
||||||
"""
|
"""
|
||||||
tests that the use of one iterator does not affect the behavior of another
|
tests that the use of one iterator does not affect the behavior of another
|
||||||
@@ -214,6 +219,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
assert next(iter1).attempt_id == attempt_id
|
assert next(iter1).attempt_id == attempt_id
|
||||||
assert next(iter2).attempt_id == attempt_id
|
assert next(iter2).attempt_id == attempt_id
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_get_success_case(self):
|
def test_get_success_case(self):
|
||||||
"""
|
"""
|
||||||
Tests that the .get() method works on new and existing querysets
|
Tests that the .get() method works on new and existing querysets
|
||||||
@@ -235,6 +241,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
assert m.test_id == 0
|
assert m.test_id == 0
|
||||||
assert m.attempt_id == 0
|
assert m.attempt_id == 0
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_query_expression_get_success_case(self):
|
def test_query_expression_get_success_case(self):
|
||||||
"""
|
"""
|
||||||
Tests that the .get() method works on new and existing querysets
|
Tests that the .get() method works on new and existing querysets
|
||||||
@@ -256,6 +263,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
assert m.test_id == 0
|
assert m.test_id == 0
|
||||||
assert m.attempt_id == 0
|
assert m.attempt_id == 0
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_get_doesnotexist_exception(self):
|
def test_get_doesnotexist_exception(self):
|
||||||
"""
|
"""
|
||||||
Tests that get calls that don't return a result raises a DoesNotExist error
|
Tests that get calls that don't return a result raises a DoesNotExist error
|
||||||
@@ -263,6 +271,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
with self.assertRaises(self.table.DoesNotExist):
|
with self.assertRaises(self.table.DoesNotExist):
|
||||||
self.table.objects.get(test_id=100)
|
self.table.objects.get(test_id=100)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_get_multipleobjects_exception(self):
|
def test_get_multipleobjects_exception(self):
|
||||||
"""
|
"""
|
||||||
Tests that get calls that return multiple results raise a MultipleObjectsReturned error
|
Tests that get calls that return multiple results raise a MultipleObjectsReturned error
|
||||||
@@ -286,6 +295,7 @@ class TestNamedWithMV(BasicSharedKeyspaceUnitTestCase):
|
|||||||
super(TestNamedWithMV, cls).tearDownClass()
|
super(TestNamedWithMV, cls).tearDownClass()
|
||||||
|
|
||||||
@greaterthanorequalcass30
|
@greaterthanorequalcass30
|
||||||
|
@execute_count(5)
|
||||||
def test_named_table_with_mv(self):
|
def test_named_table_with_mv(self):
|
||||||
"""
|
"""
|
||||||
Test NamedTable access to materialized views
|
Test NamedTable access to materialized views
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from cassandra.cqlengine.operators import EqualsOperator
|
|||||||
from cassandra.cqlengine.statements import WhereClause
|
from cassandra.cqlengine.statements import WhereClause
|
||||||
from tests.integration.cqlengine import DEFAULT_KEYSPACE
|
from tests.integration.cqlengine import DEFAULT_KEYSPACE
|
||||||
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
||||||
|
from tests.integration.cqlengine import execute_count
|
||||||
|
|
||||||
|
|
||||||
class TestQuerySetOperation(BaseCassEngTestCase):
|
class TestQuerySetOperation(BaseCassEngTestCase):
|
||||||
@@ -71,6 +72,7 @@ class TestTokenFunction(BaseCassEngTestCase):
|
|||||||
super(TestTokenFunction, self).tearDown()
|
super(TestTokenFunction, self).tearDown()
|
||||||
drop_table(TokenTestModel)
|
drop_table(TokenTestModel)
|
||||||
|
|
||||||
|
@execute_count(14)
|
||||||
def test_token_function(self):
|
def test_token_function(self):
|
||||||
""" Tests that token functions work properly """
|
""" Tests that token functions work properly """
|
||||||
assert TokenTestModel.objects().count() == 0
|
assert TokenTestModel.objects().count() == 0
|
||||||
@@ -127,6 +129,7 @@ class TestTokenFunction(BaseCassEngTestCase):
|
|||||||
func = functions.Token('a')
|
func = functions.Token('a')
|
||||||
self.assertRaises(query.QueryException, TestModel.objects.filter, pk__token__gt=func)
|
self.assertRaises(query.QueryException, TestModel.objects.filter, pk__token__gt=func)
|
||||||
|
|
||||||
|
@execute_count(7)
|
||||||
def test_named_table_pk_token_function(self):
|
def test_named_table_pk_token_function(self):
|
||||||
"""
|
"""
|
||||||
Test to ensure that token function work with named tables.
|
Test to ensure that token function work with named tables.
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ from datetime import tzinfo
|
|||||||
from cassandra.cqlengine import statements
|
from cassandra.cqlengine import statements
|
||||||
from cassandra.cqlengine import operators
|
from cassandra.cqlengine import operators
|
||||||
from cassandra.util import uuid_from_time
|
from cassandra.util import uuid_from_time
|
||||||
|
|
||||||
from cassandra.cqlengine.connection import get_session
|
from cassandra.cqlengine.connection import get_session
|
||||||
from tests.integration import PROTOCOL_VERSION, CASSANDRA_VERSION, greaterthancass20, greaterthancass21
|
from tests.integration import PROTOCOL_VERSION, CASSANDRA_VERSION, greaterthancass20, greaterthancass21
|
||||||
|
from tests.integration.cqlengine import execute_count
|
||||||
|
|
||||||
|
|
||||||
class TzOffset(tzinfo):
|
class TzOffset(tzinfo):
|
||||||
@@ -105,6 +105,7 @@ class TestMultiClusteringModel(Model):
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerySetOperation(BaseCassEngTestCase):
|
class TestQuerySetOperation(BaseCassEngTestCase):
|
||||||
|
|
||||||
def test_query_filter_parsing(self):
|
def test_query_filter_parsing(self):
|
||||||
"""
|
"""
|
||||||
Tests the queryset filter method parses it's kwargs properly
|
Tests the queryset filter method parses it's kwargs properly
|
||||||
@@ -229,6 +230,7 @@ class TestQuerySetOperation(BaseCassEngTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class BaseQuerySetUsage(BaseCassEngTestCase):
|
class BaseQuerySetUsage(BaseCassEngTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(BaseQuerySetUsage, cls).setUpClass()
|
super(BaseQuerySetUsage, cls).setUpClass()
|
||||||
@@ -298,6 +300,8 @@ class BaseQuerySetUsage(BaseCassEngTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_count(self):
|
def test_count(self):
|
||||||
""" Tests that adding filtering statements affects the count query as expected """
|
""" Tests that adding filtering statements affects the count query as expected """
|
||||||
assert TestModel.objects.count() == 12
|
assert TestModel.objects.count() == 12
|
||||||
@@ -305,6 +309,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
q = TestModel.objects(test_id=0)
|
q = TestModel.objects(test_id=0)
|
||||||
assert q.count() == 4
|
assert q.count() == 4
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_query_expression_count(self):
|
def test_query_expression_count(self):
|
||||||
""" Tests that adding query statements affects the count query as expected """
|
""" Tests that adding query statements affects the count query as expected """
|
||||||
assert TestModel.objects.count() == 12
|
assert TestModel.objects.count() == 12
|
||||||
@@ -312,6 +317,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
q = TestModel.objects(TestModel.test_id == 0)
|
q = TestModel.objects(TestModel.test_id == 0)
|
||||||
assert q.count() == 4
|
assert q.count() == 4
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_iteration(self):
|
def test_iteration(self):
|
||||||
""" Tests that iterating over a query set pulls back all of the expected results """
|
""" Tests that iterating over a query set pulls back all of the expected results """
|
||||||
q = TestModel.objects(test_id=0)
|
q = TestModel.objects(test_id=0)
|
||||||
@@ -345,6 +351,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
compare_set.remove(val)
|
compare_set.remove(val)
|
||||||
assert len(compare_set) == 0
|
assert len(compare_set) == 0
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_multiple_iterations_work_properly(self):
|
def test_multiple_iterations_work_properly(self):
|
||||||
""" Tests that iterating over a query set more than once works """
|
""" Tests that iterating over a query set more than once works """
|
||||||
# test with both the filtering method and the query method
|
# test with both the filtering method and the query method
|
||||||
@@ -365,6 +372,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
compare_set.remove(val)
|
compare_set.remove(val)
|
||||||
assert len(compare_set) == 0
|
assert len(compare_set) == 0
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_multiple_iterators_are_isolated(self):
|
def test_multiple_iterators_are_isolated(self):
|
||||||
"""
|
"""
|
||||||
tests that the use of one iterator does not affect the behavior of another
|
tests that the use of one iterator does not affect the behavior of another
|
||||||
@@ -378,6 +386,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
assert next(iter1).attempt_id == attempt_id
|
assert next(iter1).attempt_id == attempt_id
|
||||||
assert next(iter2).attempt_id == attempt_id
|
assert next(iter2).attempt_id == attempt_id
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_get_success_case(self):
|
def test_get_success_case(self):
|
||||||
"""
|
"""
|
||||||
Tests that the .get() method works on new and existing querysets
|
Tests that the .get() method works on new and existing querysets
|
||||||
@@ -399,6 +408,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
assert m.test_id == 0
|
assert m.test_id == 0
|
||||||
assert m.attempt_id == 0
|
assert m.attempt_id == 0
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_query_expression_get_success_case(self):
|
def test_query_expression_get_success_case(self):
|
||||||
"""
|
"""
|
||||||
Tests that the .get() method works on new and existing querysets
|
Tests that the .get() method works on new and existing querysets
|
||||||
@@ -420,6 +430,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
assert m.test_id == 0
|
assert m.test_id == 0
|
||||||
assert m.attempt_id == 0
|
assert m.attempt_id == 0
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_get_doesnotexist_exception(self):
|
def test_get_doesnotexist_exception(self):
|
||||||
"""
|
"""
|
||||||
Tests that get calls that don't return a result raises a DoesNotExist error
|
Tests that get calls that don't return a result raises a DoesNotExist error
|
||||||
@@ -427,6 +438,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
with self.assertRaises(TestModel.DoesNotExist):
|
with self.assertRaises(TestModel.DoesNotExist):
|
||||||
TestModel.objects.get(test_id=100)
|
TestModel.objects.get(test_id=100)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_get_multipleobjects_exception(self):
|
def test_get_multipleobjects_exception(self):
|
||||||
"""
|
"""
|
||||||
Tests that get calls that return multiple results raise a MultipleObjectsReturned error
|
Tests that get calls that return multiple results raise a MultipleObjectsReturned error
|
||||||
@@ -438,7 +450,7 @@ class TestQuerySetCountSelectionAndIteration(BaseQuerySetUsage):
|
|||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@execute_count(4)
|
||||||
def test_non_quality_filtering():
|
def test_non_quality_filtering():
|
||||||
class NonEqualityFilteringModel(Model):
|
class NonEqualityFilteringModel(Model):
|
||||||
|
|
||||||
@@ -463,28 +475,34 @@ def test_non_quality_filtering():
|
|||||||
|
|
||||||
class TestQuerySetDistinct(BaseQuerySetUsage):
|
class TestQuerySetDistinct(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_distinct_without_parameter(self):
|
def test_distinct_without_parameter(self):
|
||||||
q = TestModel.objects.distinct()
|
q = TestModel.objects.distinct()
|
||||||
self.assertEqual(len(q), 3)
|
self.assertEqual(len(q), 3)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_distinct_with_parameter(self):
|
def test_distinct_with_parameter(self):
|
||||||
q = TestModel.objects.distinct(['test_id'])
|
q = TestModel.objects.distinct(['test_id'])
|
||||||
self.assertEqual(len(q), 3)
|
self.assertEqual(len(q), 3)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_distinct_with_filter(self):
|
def test_distinct_with_filter(self):
|
||||||
q = TestModel.objects.distinct(['test_id']).filter(test_id__in=[1, 2])
|
q = TestModel.objects.distinct(['test_id']).filter(test_id__in=[1, 2])
|
||||||
self.assertEqual(len(q), 2)
|
self.assertEqual(len(q), 2)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_distinct_with_non_partition(self):
|
def test_distinct_with_non_partition(self):
|
||||||
with self.assertRaises(InvalidRequest):
|
with self.assertRaises(InvalidRequest):
|
||||||
q = TestModel.objects.distinct(['description']).filter(test_id__in=[1, 2])
|
q = TestModel.objects.distinct(['description']).filter(test_id__in=[1, 2])
|
||||||
len(q)
|
len(q)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_zero_result(self):
|
def test_zero_result(self):
|
||||||
q = TestModel.objects.distinct(['test_id']).filter(test_id__in=[52])
|
q = TestModel.objects.distinct(['test_id']).filter(test_id__in=[52])
|
||||||
self.assertEqual(len(q), 0)
|
self.assertEqual(len(q), 0)
|
||||||
|
|
||||||
@greaterthancass21
|
@greaterthancass21
|
||||||
|
@execute_count(2)
|
||||||
def test_distinct_with_explicit_count(self):
|
def test_distinct_with_explicit_count(self):
|
||||||
q = TestModel.objects.distinct(['test_id'])
|
q = TestModel.objects.distinct(['test_id'])
|
||||||
self.assertEqual(q.count(), 3)
|
self.assertEqual(q.count(), 3)
|
||||||
@@ -494,7 +512,7 @@ class TestQuerySetDistinct(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerySetOrdering(BaseQuerySetUsage):
|
class TestQuerySetOrdering(BaseQuerySetUsage):
|
||||||
|
@execute_count(2)
|
||||||
def test_order_by_success_case(self):
|
def test_order_by_success_case(self):
|
||||||
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
expected_order = [0, 1, 2, 3]
|
expected_order = [0, 1, 2, 3]
|
||||||
@@ -523,6 +541,7 @@ class TestQuerySetOrdering(BaseQuerySetUsage):
|
|||||||
with self.assertRaises(query.QueryException):
|
with self.assertRaises(query.QueryException):
|
||||||
IndexedTestModel.objects(test_id=0).order_by('attempt_id')
|
IndexedTestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
|
|
||||||
|
@execute_count(8)
|
||||||
def test_ordering_on_multiple_clustering_columns(self):
|
def test_ordering_on_multiple_clustering_columns(self):
|
||||||
TestMultiClusteringModel.create(one=1, two=1, three=4)
|
TestMultiClusteringModel.create(one=1, two=1, three=4)
|
||||||
TestMultiClusteringModel.create(one=1, two=1, three=2)
|
TestMultiClusteringModel.create(one=1, two=1, three=2)
|
||||||
@@ -541,23 +560,28 @@ class TestQuerySetOrdering(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerySetSlicing(BaseQuerySetUsage):
|
class TestQuerySetSlicing(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_out_of_range_index_raises_error(self):
|
def test_out_of_range_index_raises_error(self):
|
||||||
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
q[10]
|
q[10]
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_array_indexing_works_properly(self):
|
def test_array_indexing_works_properly(self):
|
||||||
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
expected_order = [0, 1, 2, 3]
|
expected_order = [0, 1, 2, 3]
|
||||||
for i in range(len(q)):
|
for i in range(len(q)):
|
||||||
assert q[i].attempt_id == expected_order[i]
|
assert q[i].attempt_id == expected_order[i]
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_negative_indexing_works_properly(self):
|
def test_negative_indexing_works_properly(self):
|
||||||
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
expected_order = [0, 1, 2, 3]
|
expected_order = [0, 1, 2, 3]
|
||||||
assert q[-1].attempt_id == expected_order[-1]
|
assert q[-1].attempt_id == expected_order[-1]
|
||||||
assert q[-2].attempt_id == expected_order[-2]
|
assert q[-2].attempt_id == expected_order[-2]
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_slicing_works_properly(self):
|
def test_slicing_works_properly(self):
|
||||||
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
expected_order = [0, 1, 2, 3]
|
expected_order = [0, 1, 2, 3]
|
||||||
@@ -568,6 +592,7 @@ class TestQuerySetSlicing(BaseQuerySetUsage):
|
|||||||
for model, expect in zip(q[0:3:2], expected_order[0:3:2]):
|
for model, expect in zip(q[0:3:2], expected_order[0:3:2]):
|
||||||
self.assertEqual(model.attempt_id, expect)
|
self.assertEqual(model.attempt_id, expect)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_negative_slicing(self):
|
def test_negative_slicing(self):
|
||||||
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
q = TestModel.objects(test_id=0).order_by('attempt_id')
|
||||||
expected_order = [0, 1, 2, 3]
|
expected_order = [0, 1, 2, 3]
|
||||||
@@ -589,6 +614,7 @@ class TestQuerySetSlicing(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerySetValidation(BaseQuerySetUsage):
|
class TestQuerySetValidation(BaseQuerySetUsage):
|
||||||
|
|
||||||
def test_primary_key_or_index_must_be_specified(self):
|
def test_primary_key_or_index_must_be_specified(self):
|
||||||
"""
|
"""
|
||||||
Tests that queries that don't have an equals relation to a primary key or indexed field fail
|
Tests that queries that don't have an equals relation to a primary key or indexed field fail
|
||||||
@@ -606,6 +632,7 @@ class TestQuerySetValidation(BaseQuerySetUsage):
|
|||||||
list([i for i in q])
|
list([i for i in q])
|
||||||
|
|
||||||
@greaterthancass20
|
@greaterthancass20
|
||||||
|
@execute_count(7)
|
||||||
def test_indexed_field_can_be_queried(self):
|
def test_indexed_field_can_be_queried(self):
|
||||||
"""
|
"""
|
||||||
Tests that queries on an indexed field will work without any primary key relations specified
|
Tests that queries on an indexed field will work without any primary key relations specified
|
||||||
@@ -633,6 +660,8 @@ class TestQuerySetValidation(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerySetDelete(BaseQuerySetUsage):
|
class TestQuerySetDelete(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(9)
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
TestModel.objects.create(test_id=3, attempt_id=0, description='try9', expected_result=50, test_result=40)
|
TestModel.objects.create(test_id=3, attempt_id=0, description='try9', expected_result=50, test_result=40)
|
||||||
TestModel.objects.create(test_id=3, attempt_id=1, description='try10', expected_result=60, test_result=40)
|
TestModel.objects.create(test_id=3, attempt_id=1, description='try10', expected_result=60, test_result=40)
|
||||||
@@ -658,6 +687,7 @@ class TestQuerySetDelete(BaseQuerySetUsage):
|
|||||||
TestModel.objects(attempt_id=0).delete()
|
TestModel.objects(attempt_id=0).delete()
|
||||||
|
|
||||||
@unittest.skipIf(CASSANDRA_VERSION < '3.0', "range deletion was introduce in C* 3.0, currently running {0}".format(CASSANDRA_VERSION))
|
@unittest.skipIf(CASSANDRA_VERSION < '3.0', "range deletion was introduce in C* 3.0, currently running {0}".format(CASSANDRA_VERSION))
|
||||||
|
@execute_count(18)
|
||||||
def test_range_deletion(self):
|
def test_range_deletion(self):
|
||||||
"""
|
"""
|
||||||
Tests that range deletion work as expected
|
Tests that range deletion work as expected
|
||||||
@@ -697,6 +727,7 @@ class TestMinMaxTimeUUIDFunctions(BaseCassEngTestCase):
|
|||||||
super(TestMinMaxTimeUUIDFunctions, cls).tearDownClass()
|
super(TestMinMaxTimeUUIDFunctions, cls).tearDownClass()
|
||||||
drop_table(TimeUUIDQueryModel)
|
drop_table(TimeUUIDQueryModel)
|
||||||
|
|
||||||
|
@execute_count(7)
|
||||||
def test_tzaware_datetime_support(self):
|
def test_tzaware_datetime_support(self):
|
||||||
"""Test that using timezone aware datetime instances works with the
|
"""Test that using timezone aware datetime instances works with the
|
||||||
MinTimeUUID/MaxTimeUUID functions.
|
MinTimeUUID/MaxTimeUUID functions.
|
||||||
@@ -740,6 +771,7 @@ class TestMinMaxTimeUUIDFunctions(BaseCassEngTestCase):
|
|||||||
TimeUUIDQueryModel.partition == pk,
|
TimeUUIDQueryModel.partition == pk,
|
||||||
TimeUUIDQueryModel.time >= functions.MinTimeUUID(midpoint_helsinki))]
|
TimeUUIDQueryModel.time >= functions.MinTimeUUID(midpoint_helsinki))]
|
||||||
|
|
||||||
|
@execute_count(8)
|
||||||
def test_success_case(self):
|
def test_success_case(self):
|
||||||
""" Test that the min and max time uuid functions work as expected """
|
""" Test that the min and max time uuid functions work as expected """
|
||||||
pk = uuid4()
|
pk = uuid4()
|
||||||
@@ -790,11 +822,14 @@ class TestMinMaxTimeUUIDFunctions(BaseCassEngTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestInOperator(BaseQuerySetUsage):
|
class TestInOperator(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_kwarg_success_case(self):
|
def test_kwarg_success_case(self):
|
||||||
""" Tests the in operator works with the kwarg query method """
|
""" Tests the in operator works with the kwarg query method """
|
||||||
q = TestModel.filter(test_id__in=[0, 1])
|
q = TestModel.filter(test_id__in=[0, 1])
|
||||||
assert q.count() == 8
|
assert q.count() == 8
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_query_expression_success_case(self):
|
def test_query_expression_success_case(self):
|
||||||
""" Tests the in operator works with the query expression query method """
|
""" Tests the in operator works with the query expression query method """
|
||||||
q = TestModel.filter(TestModel.test_id.in_([0, 1]))
|
q = TestModel.filter(TestModel.test_id.in_([0, 1]))
|
||||||
@@ -803,6 +838,8 @@ class TestInOperator(BaseQuerySetUsage):
|
|||||||
|
|
||||||
@greaterthancass20
|
@greaterthancass20
|
||||||
class TestContainsOperator(BaseQuerySetUsage):
|
class TestContainsOperator(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(6)
|
||||||
def test_kwarg_success_case(self):
|
def test_kwarg_success_case(self):
|
||||||
""" Tests the CONTAINS operator works with the kwarg query method """
|
""" Tests the CONTAINS operator works with the kwarg query method """
|
||||||
q = IndexedCollectionsTestModel.filter(test_list__contains=1)
|
q = IndexedCollectionsTestModel.filter(test_list__contains=1)
|
||||||
@@ -833,6 +870,7 @@ class TestContainsOperator(BaseQuerySetUsage):
|
|||||||
q = IndexedCollectionsTestModel.filter(test_map_no_index__contains=1)
|
q = IndexedCollectionsTestModel.filter(test_map_no_index__contains=1)
|
||||||
self.assertEqual(q.count(), 0)
|
self.assertEqual(q.count(), 0)
|
||||||
|
|
||||||
|
@execute_count(6)
|
||||||
def test_query_expression_success_case(self):
|
def test_query_expression_success_case(self):
|
||||||
""" Tests the CONTAINS operator works with the query expression query method """
|
""" Tests the CONTAINS operator works with the query expression query method """
|
||||||
q = IndexedCollectionsTestModel.filter(IndexedCollectionsTestModel.test_list.contains_(1))
|
q = IndexedCollectionsTestModel.filter(IndexedCollectionsTestModel.test_list.contains_(1))
|
||||||
@@ -865,6 +903,8 @@ class TestContainsOperator(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class TestValuesList(BaseQuerySetUsage):
|
class TestValuesList(BaseQuerySetUsage):
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_values_list(self):
|
def test_values_list(self):
|
||||||
q = TestModel.objects.filter(test_id=0, attempt_id=1)
|
q = TestModel.objects.filter(test_id=0, attempt_id=1)
|
||||||
item = q.values_list('test_id', 'attempt_id', 'description', 'expected_result', 'test_result').first()
|
item = q.values_list('test_id', 'attempt_id', 'description', 'expected_result', 'test_result').first()
|
||||||
@@ -875,6 +915,7 @@ class TestValuesList(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class TestObjectsProperty(BaseQuerySetUsage):
|
class TestObjectsProperty(BaseQuerySetUsage):
|
||||||
|
@execute_count(1)
|
||||||
def test_objects_property_returns_fresh_queryset(self):
|
def test_objects_property_returns_fresh_queryset(self):
|
||||||
assert TestModel.objects._result_cache is None
|
assert TestModel.objects._result_cache is None
|
||||||
len(TestModel.objects) # evaluate queryset
|
len(TestModel.objects) # evaluate queryset
|
||||||
@@ -882,6 +923,7 @@ class TestObjectsProperty(BaseQuerySetUsage):
|
|||||||
|
|
||||||
|
|
||||||
class PageQueryTests(BaseCassEngTestCase):
|
class PageQueryTests(BaseCassEngTestCase):
|
||||||
|
@execute_count(3)
|
||||||
def test_paged_result_handling(self):
|
def test_paged_result_handling(self):
|
||||||
if PROTOCOL_VERSION < 2:
|
if PROTOCOL_VERSION < 2:
|
||||||
raise unittest.SkipTest("Paging requires native protocol 2+, currently using: {0}".format(PROTOCOL_VERSION))
|
raise unittest.SkipTest("Paging requires native protocol 2+, currently using: {0}".format(PROTOCOL_VERSION))
|
||||||
@@ -989,6 +1031,7 @@ class TestModelQueryWithDBField(BaseCassEngTestCase):
|
|||||||
for model in cls.model_list:
|
for model in cls.model_list:
|
||||||
drop_table(model)
|
drop_table(model)
|
||||||
|
|
||||||
|
@execute_count(33)
|
||||||
def test_basic_crud(self):
|
def test_basic_crud(self):
|
||||||
"""
|
"""
|
||||||
Tests creation update and delete of object model queries that are using db_field mappings.
|
Tests creation update and delete of object model queries that are using db_field mappings.
|
||||||
@@ -1025,6 +1068,7 @@ class TestModelQueryWithDBField(BaseCassEngTestCase):
|
|||||||
i = model.objects(k0=i.k0, k1=i.k1).first()
|
i = model.objects(k0=i.k0, k1=i.k1).first()
|
||||||
self.assertIsNone(i)
|
self.assertIsNone(i)
|
||||||
|
|
||||||
|
@execute_count(21)
|
||||||
def test_slice(self):
|
def test_slice(self):
|
||||||
"""
|
"""
|
||||||
Tests slice queries for object models that are using db_field mapping
|
Tests slice queries for object models that are using db_field mapping
|
||||||
@@ -1047,6 +1091,7 @@ class TestModelQueryWithDBField(BaseCassEngTestCase):
|
|||||||
self.assertEqual(model.objects(k0=i.k0, k1=i.k1, c0__lt=i.c0).count(), len(clustering_values[:-1]))
|
self.assertEqual(model.objects(k0=i.k0, k1=i.k1, c0__lt=i.c0).count(), len(clustering_values[:-1]))
|
||||||
self.assertEqual(model.objects(k0=i.k0, k1=i.k1, c0__gt=0).count(), len(clustering_values[1:]))
|
self.assertEqual(model.objects(k0=i.k0, k1=i.k1, c0__gt=0).count(), len(clustering_values[1:]))
|
||||||
|
|
||||||
|
@execute_count(15)
|
||||||
def test_order(self):
|
def test_order(self):
|
||||||
"""
|
"""
|
||||||
Tests order by queries for object models that are using db_field mapping
|
Tests order by queries for object models that are using db_field mapping
|
||||||
@@ -1066,6 +1111,7 @@ class TestModelQueryWithDBField(BaseCassEngTestCase):
|
|||||||
self.assertEqual(model.objects(k0=i.k0, k1=i.k1).order_by('c0').first().c0, clustering_values[0])
|
self.assertEqual(model.objects(k0=i.k0, k1=i.k1).order_by('c0').first().c0, clustering_values[0])
|
||||||
self.assertEqual(model.objects(k0=i.k0, k1=i.k1).order_by('-c0').first().c0, clustering_values[-1])
|
self.assertEqual(model.objects(k0=i.k0, k1=i.k1).order_by('-c0').first().c0, clustering_values[-1])
|
||||||
|
|
||||||
|
@execute_count(15)
|
||||||
def test_index(self):
|
def test_index(self):
|
||||||
"""
|
"""
|
||||||
Tests queries using index fields for object models using db_field mapping
|
Tests queries using index fields for object models using db_field mapping
|
||||||
@@ -1086,6 +1132,7 @@ class TestModelQueryWithDBField(BaseCassEngTestCase):
|
|||||||
self.assertEqual(model.objects(k0=i.k0, k1=i.k1).count(), len(clustering_values))
|
self.assertEqual(model.objects(k0=i.k0, k1=i.k1).count(), len(clustering_values))
|
||||||
self.assertEqual(model.objects(k0=i.k0, k1=i.k1, v1=0).count(), 1)
|
self.assertEqual(model.objects(k0=i.k0, k1=i.k1, v1=0).count(), 1)
|
||||||
|
|
||||||
|
@execute_count(1)
|
||||||
def test_db_field_names_used(self):
|
def test_db_field_names_used(self):
|
||||||
"""
|
"""
|
||||||
Tests to ensure that with generated cql update statements correctly utilize the db_field values.
|
Tests to ensure that with generated cql update statements correctly utilize the db_field values.
|
||||||
@@ -1145,6 +1192,7 @@ class TestModelQueryWithFetchSize(BaseCassEngTestCase):
|
|||||||
super(TestModelQueryWithFetchSize, cls).tearDownClass()
|
super(TestModelQueryWithFetchSize, cls).tearDownClass()
|
||||||
drop_table(TestModelSmall)
|
drop_table(TestModelSmall)
|
||||||
|
|
||||||
|
@execute_count(9)
|
||||||
def test_defaultFetchSize(self):
|
def test_defaultFetchSize(self):
|
||||||
with BatchQuery() as b:
|
with BatchQuery() as b:
|
||||||
for i in range(5100):
|
for i in range(5100):
|
||||||
@@ -1202,6 +1250,7 @@ class TestModelQueryWithDifferedFeld(BaseCassEngTestCase):
|
|||||||
super(TestModelQueryWithDifferedFeld, cls).tearDownClass()
|
super(TestModelQueryWithDifferedFeld, cls).tearDownClass()
|
||||||
drop_table(People)
|
drop_table(People)
|
||||||
|
|
||||||
|
@execute_count(8)
|
||||||
def test_defaultFetchSize(self):
|
def test_defaultFetchSize(self):
|
||||||
# Populate Table
|
# Populate Table
|
||||||
People.objects.create(last_name="Smith", first_name="John", birthday=datetime.now())
|
People.objects.create(last_name="Smith", first_name="John", birthday=datetime.now())
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from cassandra.cqlengine.management import sync_table, drop_table
|
|||||||
from cassandra.cqlengine import columns
|
from cassandra.cqlengine import columns
|
||||||
from tests.integration.cqlengine import is_prepend_reversed
|
from tests.integration.cqlengine import is_prepend_reversed
|
||||||
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
from tests.integration.cqlengine.base import BaseCassEngTestCase
|
||||||
|
from tests.integration.cqlengine import execute_count
|
||||||
|
|
||||||
|
|
||||||
class TestQueryUpdateModel(Model):
|
class TestQueryUpdateModel(Model):
|
||||||
@@ -45,6 +46,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
super(QueryUpdateTests, cls).tearDownClass()
|
super(QueryUpdateTests, cls).tearDownClass()
|
||||||
drop_table(TestQueryUpdateModel)
|
drop_table(TestQueryUpdateModel)
|
||||||
|
|
||||||
|
@execute_count(8)
|
||||||
def test_update_values(self):
|
def test_update_values(self):
|
||||||
""" tests calling udpate on a queryset """
|
""" tests calling udpate on a queryset """
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
@@ -65,6 +67,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
self.assertEqual(row.count, 6 if i == 3 else i)
|
self.assertEqual(row.count, 6 if i == 3 else i)
|
||||||
self.assertEqual(row.text, str(i))
|
self.assertEqual(row.text, str(i))
|
||||||
|
|
||||||
|
@execute_count(6)
|
||||||
def test_update_values_validation(self):
|
def test_update_values_validation(self):
|
||||||
""" tests calling udpate on models with values passed in """
|
""" tests calling udpate on models with values passed in """
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
@@ -91,6 +94,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
TestQueryUpdateModel.objects(partition=uuid4(), cluster=3).update(cluster=5000)
|
TestQueryUpdateModel.objects(partition=uuid4(), cluster=3).update(cluster=5000)
|
||||||
|
|
||||||
|
@execute_count(8)
|
||||||
def test_null_update_deletes_column(self):
|
def test_null_update_deletes_column(self):
|
||||||
""" setting a field to null in the update should issue a delete statement """
|
""" setting a field to null in the update should issue a delete statement """
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
@@ -111,6 +115,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
self.assertEqual(row.count, i)
|
self.assertEqual(row.count, i)
|
||||||
self.assertEqual(row.text, None if i == 3 else str(i))
|
self.assertEqual(row.text, None if i == 3 else str(i))
|
||||||
|
|
||||||
|
@execute_count(9)
|
||||||
def test_mixed_value_and_null_update(self):
|
def test_mixed_value_and_null_update(self):
|
||||||
""" tests that updating a columns value, and removing another works properly """
|
""" tests that updating a columns value, and removing another works properly """
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
@@ -131,9 +136,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
self.assertEqual(row.count, 6 if i == 3 else i)
|
self.assertEqual(row.count, 6 if i == 3 else i)
|
||||||
self.assertEqual(row.text, None if i == 3 else str(i))
|
self.assertEqual(row.text, None if i == 3 else str(i))
|
||||||
|
|
||||||
def test_counter_updates(self):
|
@execute_count(3)
|
||||||
pass
|
|
||||||
|
|
||||||
def test_set_add_updates(self):
|
def test_set_add_updates(self):
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
cluster = 1
|
cluster = 1
|
||||||
@@ -144,6 +147,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
||||||
self.assertEqual(obj.text_set, set(("foo", "bar")))
|
self.assertEqual(obj.text_set, set(("foo", "bar")))
|
||||||
|
|
||||||
|
@execute_count(2)
|
||||||
def test_set_add_updates_new_record(self):
|
def test_set_add_updates_new_record(self):
|
||||||
""" If the key doesn't exist yet, an update creates the record
|
""" If the key doesn't exist yet, an update creates the record
|
||||||
"""
|
"""
|
||||||
@@ -154,6 +158,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
||||||
self.assertEqual(obj.text_set, set(("bar",)))
|
self.assertEqual(obj.text_set, set(("bar",)))
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_set_remove_updates(self):
|
def test_set_remove_updates(self):
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
cluster = 1
|
cluster = 1
|
||||||
@@ -165,6 +170,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
||||||
self.assertEqual(obj.text_set, set(("baz",)))
|
self.assertEqual(obj.text_set, set(("baz",)))
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_set_remove_new_record(self):
|
def test_set_remove_new_record(self):
|
||||||
""" Removing something not in the set should silently do nothing
|
""" Removing something not in the set should silently do nothing
|
||||||
"""
|
"""
|
||||||
@@ -178,6 +184,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
||||||
self.assertEqual(obj.text_set, set(("foo",)))
|
self.assertEqual(obj.text_set, set(("foo",)))
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_list_append_updates(self):
|
def test_list_append_updates(self):
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
cluster = 1
|
cluster = 1
|
||||||
@@ -189,6 +196,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
||||||
self.assertEqual(obj.text_list, ["foo", "bar"])
|
self.assertEqual(obj.text_list, ["foo", "bar"])
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_list_prepend_updates(self):
|
def test_list_prepend_updates(self):
|
||||||
""" Prepend two things since order is reversed by default by CQL """
|
""" Prepend two things since order is reversed by default by CQL """
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
@@ -204,6 +212,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
expected = (prepended[::-1] if is_prepend_reversed() else prepended) + original
|
expected = (prepended[::-1] if is_prepend_reversed() else prepended) + original
|
||||||
self.assertEqual(obj.text_list, expected)
|
self.assertEqual(obj.text_list, expected)
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_map_update_updates(self):
|
def test_map_update_updates(self):
|
||||||
""" Merge a dictionary into existing value """
|
""" Merge a dictionary into existing value """
|
||||||
partition = uuid4()
|
partition = uuid4()
|
||||||
@@ -217,6 +226,7 @@ class QueryUpdateTests(BaseCassEngTestCase):
|
|||||||
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster)
|
||||||
self.assertEqual(obj.text_map, {"foo": '1', "bar": '3', "baz": '4'})
|
self.assertEqual(obj.text_map, {"foo": '1', "bar": '3', "baz": '4'})
|
||||||
|
|
||||||
|
@execute_count(3)
|
||||||
def test_map_update_none_deletes_key(self):
|
def test_map_update_none_deletes_key(self):
|
||||||
""" The CQL behavior is if you set a key in a map to null it deletes
|
""" The CQL behavior is if you set a key in a map to null it deletes
|
||||||
that key from the map. Test that this works with __update.
|
that key from the map. Test that this works with __update.
|
||||||
|
|||||||
Reference in New Issue
Block a user