Skip to content

Commit 866984c

Browse files
committed
tests: add coverage for variable-size VectorType Cython fallback and numpy large vector deserialization
Add test_vector_cython_deserializer_variable_size_subtype to verify that DesVectorType correctly raises ValueError for variable-size subtypes (e.g. UTF8Type) and that the pure Python path handles them. Add test_vector_numpy_large_deserialization to exercise the numpy deserialization path for vectors with >= 32 elements across all supported numeric types (float, double, int32, int64).
1 parent 1e7999e commit 866984c

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

tests/unit/test_types.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,91 @@ def test_vector_cython_deserializer(self):
595595
self.assertIn('serialized size', str(cm.exception))
596596

597597

598+
def test_vector_cython_deserializer_variable_size_subtype(self):
599+
"""
600+
Test that DesVectorType falls back gracefully for variable-size subtypes.
601+
Variable-size types (e.g. UTF8Type) are not supported by the Cython fast path
602+
and should raise ValueError from DesVectorType._deserialize_generic.
603+
The pure Python VectorType.deserialize handles these correctly.
604+
605+
@since 3.x
606+
@expected_result Cython deserializer raises ValueError for variable-size subtypes;
607+
pure Python path correctly deserializes them
608+
609+
@test_category data_types:vector
610+
"""
611+
try:
612+
from cassandra.deserializers import find_deserializer
613+
except ImportError:
614+
self.skipTest('Cython deserializers not available')
615+
616+
vt_text = VectorType.apply_parameters(['UTF8Type', 3], {})
617+
des_text = find_deserializer(vt_text)
618+
self.assertEqual(des_text.__class__.__name__, 'DesVectorType')
619+
620+
# Cython path should raise for variable-size subtypes
621+
data = vt_text.serialize(['abc', 'def', 'ghi'], 5)
622+
with self.assertRaises(ValueError) as cm:
623+
des_text.deserialize_bytes(data, 5)
624+
self.assertIn('variable-size subtype', str(cm.exception))
625+
626+
# Pure Python path should work correctly
627+
result = vt_text.deserialize(data, 5)
628+
self.assertEqual(result, ['abc', 'def', 'ghi'])
629+
630+
def test_vector_numpy_large_deserialization(self):
631+
"""
632+
Test that large vectors (>= 32 elements) use the numpy deserialization path
633+
and return correct results for all supported numeric types.
634+
635+
@since 3.x
636+
@expected_result Large vectors are correctly deserialized (via numpy when available)
637+
638+
@test_category data_types:vector
639+
"""
640+
import struct
641+
from cassandra.cqltypes import DoubleType
642+
643+
vector_size = 64 # >= 32 threshold for numpy path
644+
645+
# Float vector
646+
float_data = list(range(vector_size))
647+
float_values = [float(x) for x in float_data]
648+
vt_float = VectorType.apply_parameters(['FloatType', vector_size], {})
649+
packed = struct.pack('>%df' % vector_size, *float_values)
650+
result = vt_float.deserialize(packed, 5)
651+
self.assertEqual(len(result), vector_size)
652+
for i in range(vector_size):
653+
self.assertAlmostEqual(result[i], float_values[i], places=5)
654+
655+
# Double vector
656+
double_values = [float(x) * 1.1 for x in range(vector_size)]
657+
vt_double = VectorType.apply_parameters(['DoubleType', vector_size], {})
658+
packed = struct.pack('>%dd' % vector_size, *double_values)
659+
result = vt_double.deserialize(packed, 5)
660+
self.assertEqual(len(result), vector_size)
661+
for i in range(vector_size):
662+
self.assertAlmostEqual(result[i], double_values[i], places=10)
663+
664+
# Int32 vector
665+
int32_values = list(range(vector_size))
666+
vt_int32 = VectorType.apply_parameters(['Int32Type', vector_size], {})
667+
packed = struct.pack('>%di' % vector_size, *int32_values)
668+
result = vt_int32.deserialize(packed, 5)
669+
self.assertEqual(result, int32_values)
670+
671+
# Int64/Long vector
672+
int64_values = list(range(vector_size))
673+
vt_int64 = VectorType.apply_parameters(['LongType', vector_size], {})
674+
packed = struct.pack('>%dq' % vector_size, *int64_values)
675+
result = vt_int64.deserialize(packed, 5)
676+
self.assertEqual(result, int64_values)
677+
678+
# ShortType skipped: serial_size() returns None (pre-existing bug),
679+
# so VectorType.deserialize takes the variable-size path which fails.
680+
# ShortType struct.unpack works for small vectors via _vector_struct.
681+
682+
598683
ZERO = datetime.timedelta(0)
599684

600685

0 commit comments

Comments
 (0)