diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 8b8fc0e791..1b80e813ee 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -89,12 +89,11 @@ The test will start the appropriate Scylla clusters when necessary but if you d Specify a Protocol Version for Tests ------------------------------------ The protocol version defaults to: -- 4 for Scylla >= 3.0 and Scylla Enterprise > 2019. -- 3 for older versions of Scylla -- 5 for Cassandra >= 4.0, 4 for Cassandra >= 2.2, 3 for Cassandra >= 2.1, 2 for Cassandra >= 2.0 +- 4 for Scylla. +- 5 for Cassandra >= 4.0, 4 for Cassandra >= 2.2 You can overwrite it with the ``PROTOCOL_VERSION`` environment variable:: - PROTOCOL_VERSION=3 SCYLLA_VERSION="release:5.1" uv run pytest tests/integration/standard tests/integration/cqlengine/ + PROTOCOL_VERSION=4 SCYLLA_VERSION="release:5.1" uv run pytest tests/integration/standard tests/integration/cqlengine/ Seeing Test Logs in Real Time ----------------------------- diff --git a/cassandra/__init__.py b/cassandra/__init__.py index 88fbb11f88..d772814643 100644 --- a/cassandra/__init__.py +++ b/cassandra/__init__.py @@ -136,13 +136,6 @@ class ProtocolVersion(object): Defines native protocol versions supported by this driver. """ - V3 = 3 - """ - v3, supported in Cassandra 2.1-->3.x+; - added support for protocol-level client-side timestamps (see :attr:`.Session.use_client_timestamp`), - serial consistency levels for :class:`~.BatchStatement`, and an improved connection pool. - """ - V4 = 4 """ v4, supported in Cassandra 2.2-->3.x+; @@ -170,9 +163,9 @@ class ProtocolVersion(object): DSE private protocol v2, supported in DSE 6.0+ """ - SUPPORTED_VERSIONS = (V5, V4, V3) + SUPPORTED_VERSIONS = (V5, V4) """ - A tuple of all supported protocol versions for ScyllaDB, including future v5 version. + A tuple of all supported protocol versions for ScyllaDB. """ BETA_VERSIONS = (V6,) diff --git a/cassandra/cluster.py b/cassandra/cluster.py index 622b706330..c8b45f5ec8 100644 --- a/cassandra/cluster.py +++ b/cassandra/cluster.py @@ -717,11 +717,9 @@ def application_info(self) -> Optional[ApplicationInfoBase]: @property def auth_provider(self): """ - When :attr:`~.Cluster.protocol_version` is 2 or higher, this should - be an instance of a subclass of :class:`~cassandra.auth.AuthProvider`, + This should be an instance of a subclass of :class:`~cassandra.auth.AuthProvider`, such as :class:`~.PlainTextAuthProvider`. - When not using authentication, this should be left as :const:`None`. """ return self._auth_provider @@ -735,12 +733,7 @@ def auth_provider(self, value): try: self._auth_provider_callable = value.new_authenticator except AttributeError: - if self.protocol_version > 1: - raise TypeError("auth_provider must implement the cassandra.auth.AuthProvider " - "interface when protocol_version >= 2") - elif not callable(value): - raise TypeError("auth_provider must be callable when protocol_version == 1") - self._auth_provider_callable = value + raise TypeError("auth_provider must implement the cassandra.auth.AuthProvider interface") self._auth_provider = value @@ -1557,7 +1550,7 @@ def register_user_type(self, keyspace, user_type, klass): Example:: - cluster = Cluster(protocol_version=3) + cluster = Cluster(protocol_version=4) session = cluster.connect() session.set_keyspace('mykeyspace') session.execute("CREATE TYPE address (street text, zipcode int)") @@ -1582,11 +1575,6 @@ def __init__(self, street, zipcode): print(row.id, row.location.street, row.location.zipcode) """ - if self.protocol_version < 3: - log.warning("User Type serialization is only supported in native protocol version 3+ (%d in use). " - "CQL encoding for simple statements will still work, but named tuples will " - "be returned when reading type %s.%s.", self.protocol_version, keyspace, user_type) - self._user_types[keyspace][user_type] = klass for session in tuple(self.sessions): session.user_type_registered(keyspace, user_type, klass) @@ -2445,8 +2433,6 @@ def default_serial_consistency_level(self): The default :class:`~ConsistencyLevel` for serial phase of conditional updates executed through this session. This default may be overridden by setting the :attr:`~.Statement.serial_consistency_level` on individual statements. - - Only valid for ``protocol_version >= 2``. """ return self._default_serial_consistency_level @@ -2957,11 +2943,6 @@ def _create_response_future(self, query, parameters, trace, custom_payload, continuous_paging_options=continuous_paging_options, result_metadata_id=prepared_statement.result_metadata_id) elif isinstance(query, BatchStatement): - if self._protocol_version < 2: - raise UnsupportedOperation( - "BatchStatement execution is only supported with protocol version " - "2 or higher (supported in Cassandra 2.0 and higher). Consider " - "setting Cluster.protocol_version to 2 to support this operation.") statement_keyspace = query.keyspace if ProtocolVersion.uses_keyspace_flag(self._protocol_version) else None message = BatchMessage( query.batch_type, query._statements_and_parameters, cl, @@ -3100,7 +3081,7 @@ def prepare(self, query, custom_payload=None, keyspace=None): prepared_keyspace = keyspace if keyspace else None prepared_statement = PreparedStatement.from_message( response.query_id, response.bind_metadata, response.pk_indexes, self.cluster.metadata, query, prepared_keyspace, - self._protocol_version, response.column_metadata, response.result_metadata_id, response.is_lwt, self.cluster.column_encryption_policy) + response.column_metadata, response.result_metadata_id, response.is_lwt, self.cluster.column_encryption_policy) prepared_statement.custom_payload = future.custom_payload self.cluster.add_prepared(response.query_id, prepared_statement) @@ -4640,10 +4621,9 @@ def _set_result(self, host, connection, pool, response): self._custom_payload = getattr(response, 'custom_payload', None) if self._custom_payload and self.session.cluster.control_connection._tablets_routing_v1 and 'tablets-routing-v1' in self._custom_payload: - protocol = self.session.cluster.protocol_version info = self._custom_payload.get('tablets-routing-v1') ctype = types.lookup_casstype('TupleType(LongType, LongType, ListType(TupleType(UUIDType, Int32Type)))') - tablet_routing_info = ctype.from_binary(info, protocol) + tablet_routing_info = ctype.from_binary(info) first_token = tablet_routing_info[0] last_token = tablet_routing_info[1] tablet_replicas = tablet_routing_info[2] diff --git a/cassandra/connection.py b/cassandra/connection.py index 87f860f32b..d8570fde03 100644 --- a/cassandra/connection.py +++ b/cassandra/connection.py @@ -41,7 +41,7 @@ from cassandra import ConsistencyLevel, AuthenticationFailed, OperationTimedOut, ProtocolVersion from cassandra.marshal import int32_pack from cassandra.protocol import (ReadyMessage, AuthenticateMessage, OptionsMessage, - StartupMessage, ErrorMessage, CredentialsMessage, + StartupMessage, ErrorMessage, QueryMessage, ResultMessage, ProtocolHandler, InvalidRequestException, SupportedMessage, AuthResponseMessage, AuthChallengeMessage, @@ -1477,18 +1477,12 @@ def _handle_startup_response(self, startup_response, did_authenticate=False): if ProtocolVersion.has_checksumming_support(self.protocol_version): self._enable_checksumming() - if isinstance(self.authenticator, dict): - log.debug("Sending credentials-based auth response on %s", self) - cm = CredentialsMessage(creds=self.authenticator) - callback = partial(self._handle_startup_response, did_authenticate=True) - self.send_msg(cm, self.get_request_id(), cb=callback) - else: - log.debug("Sending SASL-based auth response on %s", self) - self.authenticator.server_authenticator_class = startup_response.authenticator - initial_response = self.authenticator.initial_response() - initial_response = "" if initial_response is None else initial_response - self.send_msg(AuthResponseMessage(initial_response), self.get_request_id(), - self._handle_auth_response) + log.debug("Sending SASL-based auth response on %s", self) + self.authenticator.server_authenticator_class = startup_response.authenticator + initial_response = self.authenticator.initial_response() + initial_response = "" if initial_response is None else initial_response + self.send_msg(AuthResponseMessage(initial_response), self.get_request_id(), + self._handle_auth_response) elif isinstance(startup_response, ErrorMessage): log.debug("Received ErrorMessage on new connection (%s) from %s: %s", id(self), self.endpoint, startup_response.summary_msg()) diff --git a/cassandra/cqlengine/models.py b/cassandra/cqlengine/models.py index bc00001666..7cdb5ddd3f 100644 --- a/cassandra/cqlengine/models.py +++ b/cassandra/cqlengine/models.py @@ -422,8 +422,8 @@ def __str__(self): ', '.join('{0}={1}'.format(k, getattr(self, k)) for k in self._primary_keys.keys())) @classmethod - def _routing_key_from_values(cls, pk_values, protocol_version): - return cls._key_serializer(pk_values, protocol_version) + def _routing_key_from_values(cls, pk_values): + return cls._key_serializer(pk_values) @classmethod def _discover_polymorphic_submodels(cls): @@ -948,10 +948,10 @@ def _transform_column(col_name, col_obj): key_cols = [c for c in partition_keys.values()] partition_key_index = dict((col.db_field_name, col._partition_key_index) for col in key_cols) key_cql_types = [c.cql_type for c in key_cols] - key_serializer = staticmethod(lambda parts, proto_version: [t.to_binary(p, proto_version) for t, p in zip(key_cql_types, parts)]) + key_serializer = staticmethod(lambda parts: [t.to_binary(p) for t, p in zip(key_cql_types, parts)]) else: partition_key_index = {} - key_serializer = staticmethod(lambda parts, proto_version: None) + key_serializer = staticmethod(lambda parts: None) # setup partition key shortcut if len(partition_keys) == 0: diff --git a/cassandra/cqlengine/query.py b/cassandra/cqlengine/query.py index afc7ceeef6..5eb4be9166 100644 --- a/cassandra/cqlengine/query.py +++ b/cassandra/cqlengine/query.py @@ -1523,7 +1523,7 @@ def _execute_statement(model, statement, consistency_level, timeout, connection= if model._partition_key_index: key_values = statement.partition_key_values(model._partition_key_index) if not any(v is None for v in key_values): - parts = model._routing_key_from_values(key_values, conn.get_cluster(connection).protocol_version) + parts = model._routing_key_from_values(key_values) s.routing_key = parts s.keyspace = model._get_keyspace() connection = connection or model._get_connection() diff --git a/cassandra/cqltypes.py b/cassandra/cqltypes.py index e36c48563c..7a9c8e9d88 100644 --- a/cassandra/cqltypes.py +++ b/cassandra/cqltypes.py @@ -291,7 +291,7 @@ def __repr__(self): return '<%s>' % (self.cql_parameterized_type()) @classmethod - def from_binary(cls, byts, protocol_version): + def from_binary(cls, byts): """ Deserialize a bytestring into a value. See the deserialize() method for more information. This method differs in that if None or the empty @@ -301,19 +301,19 @@ def from_binary(cls, byts, protocol_version): return None elif len(byts) == 0 and not cls.empty_binary_ok: return EMPTY if cls.support_empty_values else None - return cls.deserialize(byts, protocol_version) + return cls.deserialize(byts) @classmethod - def to_binary(cls, val, protocol_version): + def to_binary(cls, val): """ Serialize a value into a bytestring. See the serialize() method for more information. This method differs in that if None is passed in, the result is the empty string. """ - return b'' if val is None else cls.serialize(val, protocol_version) + return b'' if val is None else cls.serialize(val) @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): """ Given a bytestring, deserialize into a value according to the protocol for this type. Note that this does not create a new instance of this @@ -323,7 +323,7 @@ def deserialize(byts, protocol_version): return byts @staticmethod - def serialize(val, protocol_version): + def serialize(val): """ Given a value appropriate for this class, serialize it according to the protocol for this type and return the corresponding bytestring. @@ -416,7 +416,7 @@ class BytesType(_CassandraType): empty_binary_ok = True @staticmethod - def serialize(val, protocol_version): + def serialize(val): return bytes(val) @@ -424,13 +424,13 @@ class DecimalType(_CassandraType): typename = 'decimal' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): scale = int32_unpack(byts[:4]) unscaled = varint_unpack(byts[4:]) return Decimal('%de%d' % (unscaled, -scale)) @staticmethod - def serialize(dec, protocol_version): + def serialize(dec): try: sign, digits, exponent = dec.as_tuple() except AttributeError: @@ -450,11 +450,11 @@ class UUIDType(_CassandraType): typename = 'uuid' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return UUID(bytes=byts) @staticmethod - def serialize(uuid, protocol_version): + def serialize(uuid): try: return uuid.bytes except AttributeError: @@ -468,11 +468,11 @@ class BooleanType(_CassandraType): typename = 'boolean' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return bool(int8_unpack(byts)) @staticmethod - def serialize(truth, protocol_version): + def serialize(truth): return int8_pack(truth) @classmethod @@ -483,11 +483,11 @@ class ByteType(_CassandraType): typename = 'tinyint' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return int8_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return int8_pack(byts) @@ -496,11 +496,11 @@ class AsciiType(_CassandraType): empty_binary_ok = True @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return byts.decode('ascii') @staticmethod - def serialize(var, protocol_version): + def serialize(var): try: return var.encode('ascii') except UnicodeDecodeError: @@ -511,11 +511,11 @@ class FloatType(_CassandraType): typename = 'float' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return float_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return float_pack(byts) @classmethod @@ -526,11 +526,11 @@ class DoubleType(_CassandraType): typename = 'double' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return double_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return double_pack(byts) @classmethod @@ -541,11 +541,11 @@ class LongType(_CassandraType): typename = 'bigint' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return int64_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return int64_pack(byts) @classmethod @@ -556,11 +556,11 @@ class Int32Type(_CassandraType): typename = 'int' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return int32_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return int32_pack(byts) @classmethod @@ -571,11 +571,11 @@ class IntegerType(_CassandraType): typename = 'varint' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return varint_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return varint_pack(byts) @@ -583,7 +583,7 @@ class InetAddressType(_CassandraType): typename = 'inet' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): if len(byts) == 16: return util.inet_ntop(socket.AF_INET6, byts) else: @@ -592,7 +592,7 @@ def deserialize(byts, protocol_version): return socket.inet_ntoa(byts) @staticmethod - def serialize(addr, protocol_version): + def serialize(addr): try: if ':' in addr: return util.inet_pton(socket.AF_INET6, addr) @@ -641,12 +641,12 @@ def interpret_datestring(val): raise ValueError("can't interpret %r as a date" % (val,)) @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): timestamp = int64_unpack(byts) / 1000.0 return util.datetime_from_timestamp(timestamp) @staticmethod - def serialize(v, protocol_version): + def serialize(v): try: # v is datetime timestamp_seconds = calendar.timegm(v.utctimetuple()) @@ -677,11 +677,11 @@ def my_timestamp(self): return util.unix_time_from_uuid1(self.val) @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return UUID(bytes=byts) @staticmethod - def serialize(timeuuid, protocol_version): + def serialize(timeuuid): try: return timeuuid.bytes except AttributeError: @@ -701,12 +701,12 @@ class SimpleDateType(_CassandraType): EPOCH_OFFSET_DAYS = 2 ** 31 @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): days = uint32_unpack(byts) - SimpleDateType.EPOCH_OFFSET_DAYS return util.Date(days) @staticmethod - def serialize(val, protocol_version): + def serialize(val): try: days = val.days_from_epoch except AttributeError: @@ -723,11 +723,11 @@ class ShortType(_CassandraType): typename = 'smallint' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return int16_unpack(byts) @staticmethod - def serialize(byts, protocol_version): + def serialize(byts): return int16_pack(byts) class TimeType(_CassandraType): @@ -740,11 +740,11 @@ class TimeType(_CassandraType): # return 8 @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return util.Time(int64_unpack(byts)) @staticmethod - def serialize(val, protocol_version): + def serialize(val): try: nano = val.nanosecond_time except AttributeError: @@ -756,12 +756,12 @@ class DurationType(_CassandraType): typename = 'duration' @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): months, days, nanoseconds = vints_unpack(byts) return util.Duration(months, days, nanoseconds) @staticmethod - def serialize(duration, protocol_version): + def serialize(duration): try: m, d, n = duration.months, duration.days, duration.nanoseconds except AttributeError: @@ -774,11 +774,11 @@ class UTF8Type(_CassandraType): empty_binary_ok = True @staticmethod - def deserialize(byts, protocol_version): + def deserialize(byts): return byts.decode('utf8') @staticmethod - def serialize(ustr, protocol_version): + def serialize(ustr): try: return ustr.encode('utf-8') except UnicodeDecodeError: @@ -794,29 +794,28 @@ class _ParameterizedType(_CassandraType): num_subtypes = 'UNKNOWN' @classmethod - def deserialize(cls, byts, protocol_version): + def deserialize(cls, byts): if not cls.subtypes: raise NotImplementedError("can't deserialize unparameterized %s" % cls.typename) - return cls.deserialize_safe(byts, protocol_version) + return cls.deserialize_safe(byts) @classmethod - def serialize(cls, val, protocol_version): + def serialize(cls, val): if not cls.subtypes: raise NotImplementedError("can't serialize unparameterized %s" % cls.typename) - return cls.serialize_safe(val, protocol_version) + return cls.serialize_safe(val) class _SimpleParameterizedType(_ParameterizedType): @classmethod - def deserialize_safe(cls, byts, protocol_version): + def deserialize_safe(cls, byts): subtype, = cls.subtypes length = 4 numelements = int32_unpack(byts[:length]) p = length result = [] - inner_proto = max(3, protocol_version) for _ in range(numelements): itemlen = int32_unpack(byts[p:p + length]) p += length @@ -825,23 +824,22 @@ def deserialize_safe(cls, byts, protocol_version): else: item = byts[p:p + itemlen] p += itemlen - result.append(subtype.from_binary(item, inner_proto)) + result.append(subtype.from_binary(item)) return cls.adapter(result) @classmethod - def serialize_safe(cls, items, protocol_version): + def serialize_safe(cls, items): if isinstance(items, str): raise TypeError("Received a string for a type that expects a sequence") subtype, = cls.subtypes buf = io.BytesIO() buf.write(int32_pack(len(items))) - inner_proto = max(3, protocol_version) for item in items: if item is None: buf.write(int32_pack(-1)) else: - itembytes = subtype.to_binary(item, inner_proto) + itembytes = subtype.to_binary(item) buf.write(int32_pack(len(itembytes))) buf.write(itembytes) return buf.getvalue() @@ -864,13 +862,12 @@ class MapType(_ParameterizedType): num_subtypes = 2 @classmethod - def deserialize_safe(cls, byts, protocol_version): + def deserialize_safe(cls, byts): key_type, value_type = cls.subtypes length = 4 numelements = int32_unpack(byts[:length]) p = length - themap = util.OrderedMapSerializedKey(key_type, protocol_version) - inner_proto = max(3, protocol_version) + themap = util.OrderedMapSerializedKey(key_type) for _ in range(numelements): key_len = int32_unpack(byts[p:p + length]) p += length @@ -880,7 +877,7 @@ def deserialize_safe(cls, byts, protocol_version): else: keybytes = byts[p:p + key_len] p += key_len - key = key_type.from_binary(keybytes, inner_proto) + key = key_type.from_binary(keybytes) val_len = int32_unpack(byts[p:p + length]) p += length @@ -889,13 +886,13 @@ def deserialize_safe(cls, byts, protocol_version): else: valbytes = byts[p:p + val_len] p += val_len - val = value_type.from_binary(valbytes, inner_proto) + val = value_type.from_binary(valbytes) themap._insert_unchecked(key, keybytes, val) return themap @classmethod - def serialize_safe(cls, themap, protocol_version): + def serialize_safe(cls, themap): key_type, value_type = cls.subtypes buf = io.BytesIO() buf.write(int32_pack(len(themap))) @@ -903,16 +900,15 @@ def serialize_safe(cls, themap, protocol_version): items = themap.items() except AttributeError: raise TypeError("Got a non-map object for a map value") - inner_proto = max(3, protocol_version) for key, val in items: if key is not None: - keybytes = key_type.to_binary(key, inner_proto) + keybytes = key_type.to_binary(key) buf.write(int32_pack(len(keybytes))) buf.write(keybytes) else: buf.write(int32_pack(-1)) if val is not None: - valbytes = value_type.to_binary(val, inner_proto) + valbytes = value_type.to_binary(val) buf.write(int32_pack(len(valbytes))) buf.write(valbytes) else: @@ -924,8 +920,7 @@ class TupleType(_ParameterizedType): typename = 'tuple' @classmethod - def deserialize_safe(cls, byts, protocol_version): - proto_version = max(3, protocol_version) + def deserialize_safe(cls, byts): p = 0 values = [] for col_type in cls.subtypes: @@ -940,7 +935,7 @@ def deserialize_safe(cls, byts, protocol_version): item = None # collections inside UDTs are always encoded with at least the # version 3 format - values.append(col_type.from_binary(item, proto_version)) + values.append(col_type.from_binary(item)) if len(values) < len(cls.subtypes): nones = [None] * (len(cls.subtypes) - len(values)) @@ -949,16 +944,15 @@ def deserialize_safe(cls, byts, protocol_version): return tuple(values) @classmethod - def serialize_safe(cls, val, protocol_version): + def serialize_safe(cls, val): if len(val) > len(cls.subtypes): raise ValueError("Expected %d items in a tuple, but got %d: %s" % (len(cls.subtypes), len(val), val)) - proto_version = max(3, protocol_version) buf = io.BytesIO() for item, subtype in zip(val, cls.subtypes): if item is not None: - packed_item = subtype.to_binary(item, proto_version) + packed_item = subtype.to_binary(item) buf.write(int32_pack(len(packed_item))) buf.write(packed_item) else: @@ -1012,8 +1006,8 @@ def cql_parameterized_type(cls): return "frozen<%s>" % (cls.typename,) @classmethod - def deserialize_safe(cls, byts, protocol_version): - values = super(UserType, cls).deserialize_safe(byts, protocol_version) + def deserialize_safe(cls, byts): + values = super(UserType, cls).deserialize_safe(byts) if cls.mapped_class: return cls.mapped_class(**dict(zip(cls.fieldnames, values))) elif cls.tuple_type: @@ -1022,8 +1016,7 @@ def deserialize_safe(cls, byts, protocol_version): return tuple(values) @classmethod - def serialize_safe(cls, val, protocol_version): - proto_version = max(3, protocol_version) + def serialize_safe(cls, val): buf = io.BytesIO() for i, (fieldname, subtype) in enumerate(zip(cls.fieldnames, cls.subtypes)): # first treat as a tuple, else by custom type @@ -1035,7 +1028,7 @@ def serialize_safe(cls, val, protocol_version): log.warning(f"field {fieldname} is part of the UDT {cls.typename} but is not present in the value {val}") if item is not None: - packed_item = subtype.to_binary(item, proto_version) + packed_item = subtype.to_binary(item) buf.write(int32_pack(len(packed_item))) buf.write(packed_item) else: @@ -1085,7 +1078,7 @@ def cql_parameterized_type(cls): return "'%s'" % (typestring,) @classmethod - def deserialize_safe(cls, byts, protocol_version): + def deserialize_safe(cls, byts): result = [] for subtype in cls.subtypes: if not byts: @@ -1097,7 +1090,7 @@ def deserialize_safe(cls, byts, protocol_version): # skip element length, element, and the EOC (one byte) byts = byts[2 + element_length + 1:] - result.append(subtype.from_binary(element, protocol_version)) + result.append(subtype.from_binary(element)) return tuple(result) @@ -1125,14 +1118,14 @@ class ReversedType(_ParameterizedType): num_subtypes = 1 @classmethod - def deserialize_safe(cls, byts, protocol_version): + def deserialize_safe(cls, byts): subtype, = cls.subtypes - return subtype.from_binary(byts, protocol_version) + return subtype.from_binary(byts) @classmethod - def serialize_safe(cls, val, protocol_version): + def serialize_safe(cls, val): subtype, = cls.subtypes - return subtype.to_binary(val, protocol_version) + return subtype.to_binary(val) class FrozenType(_ParameterizedType): @@ -1140,14 +1133,14 @@ class FrozenType(_ParameterizedType): num_subtypes = 1 @classmethod - def deserialize_safe(cls, byts, protocol_version): + def deserialize_safe(cls, byts): subtype, = cls.subtypes - return subtype.from_binary(byts, protocol_version) + return subtype.from_binary(byts) @classmethod - def serialize_safe(cls, val, protocol_version): + def serialize_safe(cls, val): subtype, = cls.subtypes - return subtype.to_binary(val, protocol_version) + return subtype.to_binary(val) def is_counter_type(t): @@ -1182,11 +1175,11 @@ class PointType(CassandraType): _type = struct.pack('[[]] type_ = int8_unpack(byts[0:1]) @@ -1376,7 +1369,7 @@ def deserialize(cls, byts, protocol_version): raise ValueError('Could not deserialize %r' % (byts,)) @classmethod - def serialize(cls, v, protocol_version): + def serialize(cls, v): buf = io.BytesIO() bound_kind, bounds = None, () @@ -1444,7 +1437,7 @@ def apply_parameters(cls, params, names): return type('%s(%s)' % (cls.cass_parameterized_type_with([]), vsize), (cls,), {'vector_size': vsize, 'subtype': subtype}) @classmethod - def deserialize(cls, byts, protocol_version): + def deserialize(cls, byts): serialized_size = cls.subtype.serial_size() if serialized_size is not None: expected_byte_size = serialized_size * cls.vector_size @@ -1453,7 +1446,7 @@ def deserialize(cls, byts, protocol_version): "Expected vector of type {0} and dimension {1} to have serialized size {2}; observed serialized size of {3} instead"\ .format(cls.subtype.typename, cls.vector_size, expected_byte_size, len(byts))) indexes = (serialized_size * x for x in range(0, cls.vector_size)) - return [cls.subtype.deserialize(byts[idx:idx + serialized_size], protocol_version) for idx in indexes] + return [cls.subtype.deserialize(byts[idx:idx + serialized_size]) for idx in indexes] idx = 0 rv = [] @@ -1461,7 +1454,7 @@ def deserialize(cls, byts, protocol_version): try: size, bytes_read = uvint_unpack(byts[idx:]) idx += bytes_read - rv.append(cls.subtype.deserialize(byts[idx:idx + size], protocol_version)) + rv.append(cls.subtype.deserialize(byts[idx:idx + size])) idx += size except: raise ValueError("Error reading additional data during vector deserialization after successfully adding {} elements"\ @@ -1473,7 +1466,7 @@ def deserialize(cls, byts, protocol_version): return rv @classmethod - def serialize(cls, v, protocol_version): + def serialize(cls, v): v_length = len(v) if cls.vector_size != v_length: raise ValueError( @@ -1483,7 +1476,7 @@ def serialize(cls, v, protocol_version): serialized_size = cls.subtype.serial_size() buf = io.BytesIO() for item in v: - item_bytes = cls.subtype.serialize(item, protocol_version) + item_bytes = cls.subtype.serialize(item) if serialized_size is None: buf.write(uvint_pack(len(item_bytes))) buf.write(item_bytes) diff --git a/cassandra/deserializers.pxd b/cassandra/deserializers.pxd index 7b307226ad..ff2c45167f 100644 --- a/cassandra/deserializers.pxd +++ b/cassandra/deserializers.pxd @@ -26,18 +26,17 @@ cdef class Deserializer: # paragraph 6) cdef bint empty_binary_ok - cdef deserialize(self, Buffer *buf, int protocol_version) - # cdef deserialize(self, CString byts, protocol_version) + cdef deserialize(self, Buffer *buf) + # cdef deserialize(self, CString byts) cdef inline object from_binary(Deserializer deserializer, - Buffer *buf, - int protocol_version): + Buffer *buf): if buf.size < 0: return None elif buf.size == 0 and not deserializer.empty_binary_ok: return _ret_empty(deserializer, buf.size) else: - return deserializer.deserialize(buf, protocol_version) + return deserializer.deserialize(buf) cdef _ret_empty(Deserializer deserializer, Py_ssize_t buf_size) diff --git a/cassandra/deserializers.pyx b/cassandra/deserializers.pyx index 97d249d02f..fd84b2a1d6 100644 --- a/cassandra/deserializers.pyx +++ b/cassandra/deserializers.pyx @@ -36,12 +36,12 @@ cdef class Deserializer: self.cqltype = cqltype self.empty_binary_ok = cqltype.empty_binary_ok - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): raise NotImplementedError cdef class DesBytesType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): if buf.size == 0: return b"" return to_bytes(buf) @@ -50,14 +50,14 @@ cdef class DesBytesType(Deserializer): # It is switched in by simply overwriting DesBytesType: # deserializers.DesBytesType = deserializers.DesBytesTypeByteArray cdef class DesBytesTypeByteArray(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): if buf.size == 0: return bytearray() return bytearray(buf.ptr[:buf.size]) # TODO: Use libmpdec: http://www.bytereef.org/mpdecimal/index.html cdef class DesDecimalType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): cdef Buffer varint_buf slice_buffer(buf, &varint_buf, 4, buf.size - 4) @@ -68,56 +68,56 @@ cdef class DesDecimalType(Deserializer): cdef class DesUUIDType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return UUID(bytes=to_bytes(buf)) cdef class DesBooleanType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): if unpack_num[int8_t](buf): return True return False cdef class DesByteType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return unpack_num[int8_t](buf) cdef class DesAsciiType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): if buf.size == 0: return "" return to_bytes(buf).decode('ascii') cdef class DesFloatType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return unpack_num[float](buf) cdef class DesDoubleType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return unpack_num[double](buf) cdef class DesLongType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return unpack_num[int64_t](buf) cdef class DesInt32Type(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return unpack_num[int32_t](buf) cdef class DesIntegerType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return varint_unpack(buf) cdef class DesInetAddressType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): cdef bytes byts = to_bytes(buf) # TODO: optimize inet_ntop, inet_ntoa @@ -134,7 +134,7 @@ cdef class DesCounterColumnType(DesLongType): cdef class DesDateType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): cdef double timestamp = unpack_num[int64_t](buf) / 1000.0 return datetime_from_timestamp(timestamp) @@ -144,7 +144,7 @@ cdef class TimestampType(DesDateType): cdef class TimeUUIDType(DesDateType): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return UUID(bytes=to_bytes(buf)) @@ -154,23 +154,23 @@ cdef class TimeUUIDType(DesDateType): EPOCH_OFFSET_DAYS = 2 ** 31 cdef class DesSimpleDateType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): days = unpack_num[uint32_t](buf) - EPOCH_OFFSET_DAYS return util.Date(days) cdef class DesShortType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return unpack_num[int16_t](buf) cdef class DesTimeType(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): return util.Time(unpack_num[int64_t](buf)) cdef class DesUTF8Type(Deserializer): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): if buf.size == 0: return "" cdef val = to_bytes(buf) @@ -207,19 +207,19 @@ cdef class _DesSingleParamType(_DesParameterizedType): # List and set deserialization cdef class DesListType(_DesSingleParamType): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): result = _deserialize_list_or_set( - buf, protocol_version, self.deserializer) + buf, self.deserializer) return result cdef class DesSetType(DesListType): - cdef deserialize(self, Buffer *buf, int protocol_version): - return util.sortedset(DesListType.deserialize(self, buf, protocol_version)) + cdef deserialize(self, Buffer *buf): + return util.sortedset(DesListType.deserialize(self, buf)) -cdef list _deserialize_list_or_set(Buffer *buf, int protocol_version, +cdef list _deserialize_list_or_set(Buffer *buf, Deserializer deserializer): """ Deserialize a list or set. @@ -233,10 +233,9 @@ cdef list _deserialize_list_or_set(Buffer *buf, int protocol_version, _unpack_len(buf, 0, &numelements) offset = sizeof(int32_t) - protocol_version = max(3, protocol_version) for _ in range(numelements): subelem(buf, &elem_buf, &offset) - result.append(from_binary(deserializer, &elem_buf, protocol_version)) + result.append(from_binary(deserializer, &elem_buf)) return result @@ -277,18 +276,18 @@ cdef class DesMapType(_DesParameterizedType): self.key_deserializer = self.deserializers[0] self.val_deserializer = self.deserializers[1] - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): key_type, val_type = self.cqltype.subtypes result = _deserialize_map( - buf, protocol_version, + buf, self.key_deserializer, self.val_deserializer, key_type, val_type) return result -cdef _deserialize_map(Buffer *buf, int protocol_version, +cdef _deserialize_map(Buffer *buf, Deserializer key_deserializer, Deserializer val_deserializer, key_type, val_type): cdef Buffer key_buf, val_buf @@ -300,13 +299,12 @@ cdef _deserialize_map(Buffer *buf, int protocol_version, _unpack_len(buf, 0, &numelements) offset = sizeof(int32_t) - themap = util.OrderedMapSerializedKey(key_type, protocol_version) - protocol_version = max(3, protocol_version) + themap = util.OrderedMapSerializedKey(key_type) for _ in range(numelements): subelem(buf, &key_buf, &offset) subelem(buf, &val_buf, &offset) - key = from_binary(key_deserializer, &key_buf, protocol_version) - val = from_binary(val_deserializer, &val_buf, protocol_version) + key = from_binary(key_deserializer, &key_buf) + val = from_binary(val_deserializer, &val_buf) themap._insert_unchecked(key, to_bytes(&key_buf), val) return themap @@ -317,7 +315,7 @@ cdef class DesTupleType(_DesParameterizedType): # TODO: Use TupleRowParser to parse these tuples - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): cdef Py_ssize_t i, p cdef int32_t itemlen cdef tuple res = tuple_new(self.subtypes_len) @@ -325,10 +323,6 @@ cdef class DesTupleType(_DesParameterizedType): cdef Buffer itemlen_buf cdef Deserializer deserializer - # collections inside UDTs are always encoded with at least the - # version 3 format - protocol_version = max(3, protocol_version) - p = 0 values = [] for i in range(self.subtypes_len): @@ -342,7 +336,7 @@ cdef class DesTupleType(_DesParameterizedType): p += itemlen deserializer = self.deserializers[i] - item = from_binary(deserializer, &item_buf, protocol_version) + item = from_binary(deserializer, &item_buf) tuple_set(res, i, item) @@ -350,9 +344,9 @@ cdef class DesTupleType(_DesParameterizedType): cdef class DesUserType(DesTupleType): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): typ = self.cqltype - values = DesTupleType.deserialize(self, buf, protocol_version) + values = DesTupleType.deserialize(self, buf) if typ.mapped_class: return typ.mapped_class(**dict(zip(typ.fieldnames, values))) elif typ.tuple_type: @@ -362,7 +356,7 @@ cdef class DesUserType(DesTupleType): cdef class DesCompositeType(_DesParameterizedType): - cdef deserialize(self, Buffer *buf, int protocol_version): + cdef deserialize(self, Buffer *buf): cdef Py_ssize_t i, idx, start cdef Buffer elem_buf cdef int16_t element_length @@ -387,7 +381,7 @@ cdef class DesCompositeType(_DesParameterizedType): slice_buffer(buf, &elem_buf, 2, element_length) deserializer = self.deserializers[i] - item = from_binary(deserializer, &elem_buf, protocol_version) + item = from_binary(deserializer, &elem_buf) tuple_set(res, i, item) # skip element length, element, and the EOC (one byte) @@ -401,13 +395,13 @@ DesDynamicCompositeType = DesCompositeType cdef class DesReversedType(_DesSingleParamType): - cdef deserialize(self, Buffer *buf, int protocol_version): - return from_binary(self.deserializer, buf, protocol_version) + cdef deserialize(self, Buffer *buf): + return from_binary(self.deserializer, buf) cdef class DesFrozenType(_DesSingleParamType): - cdef deserialize(self, Buffer *buf, int protocol_version): - return from_binary(self.deserializer, buf, protocol_version) + cdef deserialize(self, Buffer *buf): + return from_binary(self.deserializer, buf) #-------------------------------------------------------------------------- @@ -431,8 +425,8 @@ cdef class GenericDeserializer(Deserializer): Wrap a generic datatype for deserialization """ - cdef deserialize(self, Buffer *buf, int protocol_version): - return self.cqltype.deserialize(to_bytes(buf), protocol_version) + cdef deserialize(self, Buffer *buf): + return self.cqltype.deserialize(to_bytes(buf)) def __repr__(self): return "GenericDeserializer(%s)" % (self.cqltype,) diff --git a/cassandra/metadata.py b/cassandra/metadata.py index b85308449e..8716b688f6 100644 --- a/cassandra/metadata.py +++ b/cassandra/metadata.py @@ -3495,7 +3495,7 @@ def group_keys_by_replica(session, keyspace, table, keys): distance = cluster._default_load_balancing_policy.distance for key in keys: - serialized_key = [serializer.serialize(pk, cluster.protocol_version) + serialized_key = [serializer.serialize(pk) for serializer, pk in zip(serializers, key)] if len(serialized_key) == 1: routing_key = serialized_key[0] diff --git a/cassandra/numpy_parser.pyx b/cassandra/numpy_parser.pyx index 0ad34f66e2..8687305ae8 100644 --- a/cassandra/numpy_parser.pyx +++ b/cassandra/numpy_parser.pyx @@ -156,7 +156,7 @@ cdef inline int unpack_row( if arr.is_object: deserializer = desc.deserializers[i] - val = from_binary(deserializer, &buf, desc.protocol_version) + val = from_binary(deserializer, &buf) Py_INCREF(val) ( arr.buf_ptr)[0] = val elif buf.size >= 0: diff --git a/cassandra/obj_parser.pyx b/cassandra/obj_parser.pyx index cf43771dd7..7155c50c64 100644 --- a/cassandra/obj_parser.pyx +++ b/cassandra/obj_parser.pyx @@ -81,9 +81,9 @@ cdef class TupleRowParser(RowParser): decrypted_bytes = ce_policy.decrypt(coldesc, to_bytes(&buf)) PyBytes_AsStringAndSize(decrypted_bytes, &newbuf.ptr, &newbuf.size) deserializer = find_deserializer(ce_policy.column_type(coldesc)) - val = from_binary(deserializer, &newbuf, desc.protocol_version) + val = from_binary(deserializer, &newbuf) else: - val = from_binary(deserializer, &buf, desc.protocol_version) + val = from_binary(deserializer, &buf) except Exception as e: raise DriverException('Failed decoding result column "%s" of type %s: %s' % (desc.colnames[i], desc.coltypes[i].cql_parameterized_type(), diff --git a/cassandra/parsing.pxd b/cassandra/parsing.pxd index 27dc368b07..8fcee2c45e 100644 --- a/cassandra/parsing.pxd +++ b/cassandra/parsing.pxd @@ -21,7 +21,6 @@ cdef class ParseDesc: cdef public object column_encryption_policy cdef public list coldescs cdef Deserializer[::1] deserializers - cdef public int protocol_version cdef Py_ssize_t rowsize cdef class ColumnParser: diff --git a/cassandra/parsing.pyx b/cassandra/parsing.pyx index 954767d227..c67f18fd88 100644 --- a/cassandra/parsing.pyx +++ b/cassandra/parsing.pyx @@ -19,13 +19,12 @@ Module containing the definitions and declarations (parsing.pxd) for parsers. cdef class ParseDesc: """Description of what structure to parse""" - def __init__(self, colnames, coltypes, column_encryption_policy, coldescs, deserializers, protocol_version): + def __init__(self, colnames, coltypes, column_encryption_policy, coldescs, deserializers): self.colnames = colnames self.coltypes = coltypes self.column_encryption_policy = column_encryption_policy self.coldescs = coldescs self.deserializers = deserializers - self.protocol_version = protocol_version self.rowsize = len(colnames) diff --git a/cassandra/protocol.py b/cassandra/protocol.py index f37633a756..4c484fa7c3 100644 --- a/cassandra/protocol.py +++ b/cassandra/protocol.py @@ -449,25 +449,6 @@ def recv_body(cls, f, *args): return cls(authenticator=authname) -class CredentialsMessage(_MessageType): - opcode = 0x04 - name = 'CREDENTIALS' - - def __init__(self, creds): - self.creds = creds - - def send_body(self, f, protocol_version): - if protocol_version > 1: - raise UnsupportedOperation( - "Credentials-based authentication is not supported with " - "protocol version 2 or higher. Use the SASL authentication " - "mechanism instead.") - write_short(f, len(self.creds)) - for credkey, credval in self.creds.items(): - write_string(f, credkey) - write_string(f, credval) - - class AuthChallengeMessage(_MessageType): opcode = 0x0E name = 'AUTH_CHALLENGE' @@ -695,7 +676,7 @@ def recv(self, f, protocol_version, protocol_features, user_type_map, result_met if self.kind == RESULT_KIND_VOID: return elif self.kind == RESULT_KIND_ROWS: - self.recv_results_rows(f, protocol_version, user_type_map, result_metadata, column_encryption_policy) + self.recv_results_rows(f, user_type_map, result_metadata, column_encryption_policy) elif self.kind == RESULT_KIND_SET_KEYSPACE: self.new_keyspace = read_string(f) elif self.kind == RESULT_KIND_PREPARED: @@ -712,7 +693,7 @@ def recv_body(cls, f, protocol_version, protocol_features, user_type_map, result msg.recv(f, protocol_version, protocol_features, user_type_map, result_metadata, column_encryption_policy) return msg - def recv_results_rows(self, f, protocol_version, user_type_map, result_metadata, column_encryption_policy): + def recv_results_rows(self, f, user_type_map, result_metadata, column_encryption_policy): self.recv_results_metadata(f, user_type_map) column_metadata = self.column_metadata or result_metadata rowcount = read_int(f) @@ -725,7 +706,7 @@ def decode_val(val, col_md, col_desc): uses_ce = column_encryption_policy and column_encryption_policy.contains_column(col_desc) col_type = column_encryption_policy.column_type(col_desc) if uses_ce else col_md[3] raw_bytes = column_encryption_policy.decrypt(col_desc, val) if uses_ce else val - return col_type.from_binary(raw_bytes, protocol_version) + return col_type.from_binary(raw_bytes) def decode_row(row): return tuple(decode_val(val, col_md, col_desc) for val, col_md, col_desc in zip(row, column_metadata, col_descs)) @@ -748,7 +729,7 @@ def recv_results_prepared(self, f, protocol_version, protocol_features, user_typ self.result_metadata_id = read_binary_string(f) else: self.result_metadata_id = None - self.recv_prepared_metadata(f, protocol_version, protocol_features, user_type_map) + self.recv_prepared_metadata(f, protocol_features, user_type_map) def recv_results_metadata(self, f, user_type_map): flags = read_int(f) @@ -786,14 +767,13 @@ def recv_results_metadata(self, f, user_type_map): self.column_metadata = column_metadata - def recv_prepared_metadata(self, f, protocol_version, protocol_features, user_type_map): + def recv_prepared_metadata(self, f, protocol_features, user_type_map): flags = read_int(f) self.is_lwt = protocol_features.lwt_info.get_lwt_flag(flags) if protocol_features.lwt_info is not None else False colcount = read_int(f) pk_indexes = None - if protocol_version >= 4: - num_pk_indexes = read_int(f) - pk_indexes = [read_short(f) for _ in range(num_pk_indexes)] + num_pk_indexes = read_int(f) + pk_indexes = [read_short(f) for _ in range(num_pk_indexes)] glob_tblspec = bool(flags & self._FLAGS_GLOBAL_TABLES_SPEC) if glob_tblspec: @@ -1086,8 +1066,6 @@ def encode_message(cls, msg, stream_id, protocol_version, compressor, allow_beta """ flags = 0 if msg.custom_payload: - if protocol_version < 4: - raise UnsupportedOperation("Custom key/value payloads can only be used with protocol version 4 or higher") flags |= CUSTOM_PAYLOAD_FLAG if msg.tracing: diff --git a/cassandra/query.py b/cassandra/query.py index 6c6878fdb4..85dbdd2a52 100644 --- a/cassandra/query.py +++ b/cassandra/query.py @@ -377,9 +377,6 @@ def is_lwt(self): conditional update. Serial reads should use the regular :attr:`consistency_level`. - Serial consistency levels may only be used against Cassandra 2.0+ - and the :attr:`~.Cluster.protocol_version` must be set to 2 or higher. - See :doc:`/lwt` for a discussion on how to work with results returned from conditional statements. @@ -448,7 +445,6 @@ class PreparedStatement(object): custom_payload = None fetch_size = FETCH_SIZE_UNSET keyspace = None # change to prepared_keyspace in major release - protocol_version = None query_id = None query_string = None result_metadata = None @@ -460,14 +456,13 @@ class PreparedStatement(object): _is_lwt = False def __init__(self, column_metadata, query_id, routing_key_indexes, query, - keyspace, protocol_version, result_metadata, result_metadata_id, + keyspace, result_metadata, result_metadata_id, is_lwt=False, column_encryption_policy=None): self.column_metadata = column_metadata self.query_id = query_id self.routing_key_indexes = routing_key_indexes self.query_string = query self.keyspace = keyspace - self.protocol_version = protocol_version self.result_metadata = result_metadata self.result_metadata_id = result_metadata_id self.column_encryption_policy = column_encryption_policy @@ -476,11 +471,11 @@ def __init__(self, column_metadata, query_id, routing_key_indexes, query, @classmethod def from_message(cls, query_id, column_metadata, pk_indexes, cluster_metadata, - query, prepared_keyspace, protocol_version, result_metadata, + query, prepared_keyspace, result_metadata, result_metadata_id, is_lwt, column_encryption_policy=None): if not column_metadata: return PreparedStatement(column_metadata, query_id, None, - query, prepared_keyspace, protocol_version, result_metadata, + query, prepared_keyspace, result_metadata, result_metadata_id, is_lwt, column_encryption_policy) if pk_indexes: @@ -506,7 +501,7 @@ def from_message(cls, query_id, column_metadata, pk_indexes, cluster_metadata, pass # statement; just leave routing_key_indexes as None return PreparedStatement(column_metadata, query_id, routing_key_indexes, - query, prepared_keyspace, protocol_version, result_metadata, + query, prepared_keyspace, result_metadata, result_metadata_id, is_lwt, column_encryption_policy) def bind(self, values): @@ -586,7 +581,7 @@ def bind(self, values): .. versionchanged:: 2.6.0 :data:`~.UNSET_VALUE` was introduced. These can be bound as positional parameters - in a sequence, or by name in a dict. Additionally, when using protocol v4+: + in a sequence, or by name in a dict. Additionally: * short sequences will be extended to match bind parameters with UNSET_VALUE * names may be omitted from a dict with UNSET_VALUE implied. @@ -597,7 +592,6 @@ def bind(self, values): """ if values is None: values = () - proto_version = self.prepared_statement.protocol_version col_meta = self.prepared_statement.column_metadata ce_policy = self.prepared_statement.column_encryption_policy @@ -611,12 +605,7 @@ def bind(self, values): try: values.append(values_dict[col.name]) except KeyError: - if proto_version >= 4: - values.append(UNSET_VALUE) - else: - raise KeyError( - 'Column name `%s` not found in bound dict.' % - (col.name)) + values.append(UNSET_VALUE) value_len = len(values) col_meta_len = len(col_meta) @@ -626,30 +615,19 @@ def bind(self, values): "Too many arguments provided to bind() (got %d, expected %d)" % (len(values), len(col_meta))) - # this is fail-fast for clarity pre-v4. When v4 can be assumed, - # the error will be better reported when UNSET_VALUE is implicitly added. - if proto_version < 4 and self.prepared_statement.routing_key_indexes and \ - value_len < len(self.prepared_statement.routing_key_indexes): - raise ValueError( - "Too few arguments provided to bind() (got %d, required %d for routing key)" % - (value_len, len(self.prepared_statement.routing_key_indexes))) - self.raw_values = values self.values = [] for value, col_spec in zip(values, col_meta): if value is None: self.values.append(None) elif value is UNSET_VALUE: - if proto_version >= 4: - self._append_unset_value() - else: - raise ValueError("Attempt to bind UNSET_VALUE while using unsuitable protocol version (%d < 4)" % proto_version) + self._append_unset_value() else: try: col_desc = ColDesc(col_spec.keyspace_name, col_spec.table_name, col_spec.name) uses_ce = ce_policy and ce_policy.contains_column(col_desc) col_type = ce_policy.column_type(col_desc) if uses_ce else col_spec.type - col_bytes = col_type.serialize(value, proto_version) + col_bytes = col_type.serialize(value) if uses_ce: col_bytes = ce_policy.encrypt(col_desc, col_bytes) self.values.append(col_bytes) @@ -659,11 +637,10 @@ def bind(self, values): 'Expected: %s, Got: %s; (%s)' % (col_spec.name, col_spec.type, actual_type, exc)) raise TypeError(message) - if proto_version >= 4: - diff = col_meta_len - len(self.values) - if diff: - for _ in range(diff): - self._append_unset_value() + diff = col_meta_len - len(self.values) + if diff: + for _ in range(diff): + self._append_unset_value() return self diff --git a/cassandra/row_parser.pyx b/cassandra/row_parser.pyx index 88277a4593..80a66c3291 100644 --- a/cassandra/row_parser.pyx +++ b/cassandra/row_parser.pyx @@ -20,7 +20,7 @@ from cassandra.deserializers import make_deserializers include "ioutils.pyx" def make_recv_results_rows(ColumnParser colparser): - def recv_results_rows(self, f, int protocol_version, user_type_map, result_metadata, column_encryption_policy): + def recv_results_rows(self, f, user_type_map, result_metadata, column_encryption_policy): """ Parse protocol data given as a BytesIO f into a set of columns (e.g. list of tuples) This is used as the recv_results_rows method of (Fast)ResultMessage @@ -34,7 +34,7 @@ def make_recv_results_rows(ColumnParser colparser): desc = ParseDesc(self.column_names, self.column_types, column_encryption_policy, [ColDesc(md[0], md[1], md[2]) for md in column_metadata], - make_deserializers(self.column_types), protocol_version) + make_deserializers(self.column_types)) reader = BytesIOReader(f.read()) try: self.parsed_rows = colparser.parse_rows(reader, desc) diff --git a/cassandra/util.py b/cassandra/util.py index 12886d05ab..5cef7f61af 100644 --- a/cassandra/util.py +++ b/cassandra/util.py @@ -767,17 +767,16 @@ def _serialize_key(self, key): class OrderedMapSerializedKey(OrderedMap): - def __init__(self, cass_type, protocol_version): + def __init__(self, cass_type): super(OrderedMapSerializedKey, self).__init__() self.cass_key_type = cass_type - self.protocol_version = protocol_version def _insert_unchecked(self, key, flat_key, value): self._items.append((key, value)) self._index[flat_key] = len(self._items) - 1 def _serialize_key(self, key): - return self.cass_key_type.serialize(key, self.protocol_version) + return self.cass_key_type.serialize(key) @total_ordering diff --git a/docs/cqlengine/models.rst b/docs/cqlengine/models.rst index 719513f4a9..ab7f4e93f5 100644 --- a/docs/cqlengine/models.rst +++ b/docs/cqlengine/models.rst @@ -215,4 +215,4 @@ Upon declaration, types are automatically registered with the driver, so query r class*. ***Note**: UDTs were not added to the native protocol until v3. When setting up the cqlengine connection, be sure to specify -``protocol_version=3``. If using an earlier version, UDT queries will still work, but the returned type will be a namedtuple. +``protocol_version=4`` (the minimum supported version). UDT queries will return instances of your ``UserType`` class. diff --git a/docs/object-mapper.rst b/docs/object-mapper.rst index 5eb78f57b6..0aef1eed50 100644 --- a/docs/object-mapper.rst +++ b/docs/object-mapper.rst @@ -65,7 +65,7 @@ Getting Started #next, setup the connection to your cassandra server(s)... # see http://datastax.github.io/python-driver/api/cassandra/cluster.html for options # the list of hosts will be passed to create a Cluster() instance - connection.setup(['127.0.0.1'], "cqlengine", protocol_version=3) + connection.setup(['127.0.0.1'], "cqlengine", protocol_version=4) #...and create your CQL table >>> sync_table(ExampleModel) diff --git a/docs/security.rst b/docs/security.rst index 5c8645e685..633402f9a8 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -24,7 +24,7 @@ For example, suppose Cassandra is setup with its default from cassandra.auth import PlainTextAuthProvider auth_provider = PlainTextAuthProvider(username='cassandra', password='cassandra') - cluster = Cluster(auth_provider=auth_provider, protocol_version=2) + cluster = Cluster(auth_provider=auth_provider) diff --git a/docs/user-defined-types.rst b/docs/user-defined-types.rst index 32c03e37e8..8cbd5c4b7c 100644 --- a/docs/user-defined-types.rst +++ b/docs/user-defined-types.rst @@ -21,7 +21,7 @@ Map a Class to a UDT .. code-block:: python - cluster = Cluster(protocol_version=3) + cluster = Cluster(protocol_version=4) session = cluster.connect() session.set_keyspace('mykeyspace') session.execute("CREATE TYPE address (street text, zipcode int)") @@ -50,7 +50,7 @@ Map a dict to a UDT .. code-block:: python - cluster = Cluster(protocol_version=3) + cluster = Cluster(protocol_version=4) session = cluster.connect() session.set_keyspace('mykeyspace') session.execute("CREATE TYPE address (street text, zipcode int)") @@ -80,7 +80,7 @@ for the UDT: .. code-block:: python - cluster = Cluster(protocol_version=3) + cluster = Cluster(protocol_version=4) session = cluster.connect() session.set_keyspace('mykeyspace') session.execute("CREATE TYPE address (street text, zipcode int)") diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index b4eab35875..7527fb64ad 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -163,49 +163,22 @@ def cmd_line_args_to_dict(env_var): def get_default_protocol(): if CASSANDRA_VERSION >= Version('4.0-a'): return ProtocolVersion.V5 - if CASSANDRA_VERSION >= Version('3.10'): - return 4 - if CASSANDRA_VERSION >= Version('2.2'): - return 4 - elif CASSANDRA_VERSION >= Version('2.1'): - return 3 else: - raise Exception("Running tests with an unsupported Cassandra version: {0}".format(CASSANDRA_VERSION)) + return 4 def get_scylla_default_protocol(): - if len(CASSANDRA_VERSION.release) == 4: - # An enterprise, i.e. 2021.1.6 - if CASSANDRA_VERSION > Version('2019'): - return 4 - return 3 - if CASSANDRA_VERSION >= Version('3.0'): - return 4 - return 3 + return 4 def get_supported_protocol_versions(): """ - 2.1 -> 3 - 2.2 -> 4, 3 - 3.X -> 4, 3 - 3.10(C*) -> 5(beta),4,3 - 4.0(C*) -> 6(beta),5,4,3 -` """ + Returns supported protocol versions (v4 minimum). + """ if CASSANDRA_VERSION >= Version('4.0-beta5'): - return (3, 4, 5) - if CASSANDRA_VERSION >= Version('4.0-a'): - return (3, 4, 5) - elif CASSANDRA_VERSION >= Version('3.10'): - return (3, 4) - elif CASSANDRA_VERSION >= Version('3.0'): - return (3, 4) - elif CASSANDRA_VERSION >= Version('2.2'): - return (3, 4) - elif CASSANDRA_VERSION >= Version('2.1'): - return (3) + return (4, 5) else: - return (3,) + return (4,) def get_unsupported_lower_protocol(): @@ -213,34 +186,22 @@ def get_unsupported_lower_protocol(): This is used to determine the lowest protocol version that is NOT supported by the version of C* running """ - if SCYLLA_VERSION is not None: - return 2 - if CASSANDRA_VERSION >= Version('3.0'): - return 2 - else: - return None + return 3 def get_unsupported_upper_protocol(): """ This is used to determine the highest protocol version that is NOT - supported by the version of C* running + supported by the version of C* running. Since protocol v4 is the minimum + supported, this returns v5 or higher for older Cassandra versions. """ if SCYLLA_VERSION is not None: return 5 if CASSANDRA_VERSION >= Version('4.0-a'): return ProtocolVersion.DSE_V1 - if CASSANDRA_VERSION >= Version('3.10'): - return 5 - if CASSANDRA_VERSION >= Version('2.2'): - return 5 - elif CASSANDRA_VERSION >= Version('2.1'): - return 4 - elif CASSANDRA_VERSION >= Version('2.0'): - return 3 else: - return 2 + return 5 default_protocol_version = get_scylla_default_protocol() if SCYLLA_VERSION else get_default_protocol() @@ -267,11 +228,6 @@ def xfail_scylla_version(filter: Callable[[Version], bool], reason: str, *args, return pytest.mark.xfail(filter(current_version), reason=reason, *args, **kwargs) local = local_decorator_creator() -notprotocolv1 = unittest.skipUnless(PROTOCOL_VERSION > 1, 'Protocol v1 not supported') -greaterthanprotocolv3 = unittest.skipUnless(PROTOCOL_VERSION >= 4, 'Protocol versions less than 4 are not supported') - -greaterthancass20 = unittest.skipUnless(CASSANDRA_VERSION >= Version('2.1'), 'Cassandra version 2.1 or greater required') -greaterthancass21 = unittest.skipUnless(CASSANDRA_VERSION >= Version('2.2'), 'Cassandra version 2.2 or greater required') greaterthanorequalcass30 = unittest.skipUnless(CASSANDRA_VERSION >= Version('3.0'), 'Cassandra version 3.0 or greater required') greaterthanorequalcass31 = unittest.skipUnless(CASSANDRA_VERSION >= Version('3.1'), 'Cassandra version 3.1 or greater required') greaterthanorequalcass36 = unittest.skipUnless(CASSANDRA_VERSION >= Version('3.6'), 'Cassandra version 3.6 or greater required') @@ -281,7 +237,6 @@ def xfail_scylla_version(filter: Callable[[Version], bool], reason: str, *args, greaterthanorequalcass50 = unittest.skipUnless(CASSANDRA_VERSION >= Version('5.0-beta'), 'Cassandra version 5.0 or greater required') lessthanorequalcass40 = unittest.skipUnless(CASSANDRA_VERSION <= Version('4.0'), 'Cassandra version less or equal to 4.0 required') lessthancass40 = unittest.skipUnless(CASSANDRA_VERSION < Version('4.0'), 'Cassandra version less than 4.0 required') -lessthancass30 = unittest.skipUnless(CASSANDRA_VERSION < Version('3.0'), 'Cassandra version less then 3.0 required') # pytest.mark.xfail instead of unittest.expectedFailure because # 1. unittest doesn't skip setUpClass when used on class and we need it sometimes @@ -295,15 +250,15 @@ def xfail_scylla_version(filter: Callable[[Version], bool], reason: str, *args, reason='Scylla does not support UDFs written in Java') requires_composite_type = pytest.mark.skipif(SCYLLA_VERSION is not None, reason='Scylla does not support composite types') -requires_custom_payload = pytest.mark.skipif(SCYLLA_VERSION is not None or PROTOCOL_VERSION < 4, - reason='Scylla does not support custom payloads. Cassandra requires native protocol v4.0+') +requires_custom_payload = pytest.mark.skipif(SCYLLA_VERSION is not None, + reason='Scylla does not support custom payloads') xfail_scylla = lambda reason, *args, **kwargs: pytest.mark.xfail(SCYLLA_VERSION is not None, reason=reason, *args, **kwargs) incorrect_test = lambda reason='This test seems to be incorrect and should be fixed', *args, **kwargs: pytest.mark.xfail(reason=reason, *args, **kwargs) pypy = unittest.skipUnless(platform.python_implementation() == "PyPy", "Test is skipped unless it's on PyPy") requiresmallclockgranularity = unittest.skipIf("Windows" in platform.system() or "asyncore" in EVENT_LOOP_MANAGER, "This test is not suitible for environments with large clock granularity") -requiressimulacron = unittest.skipIf(SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"), "Simulacron jar hasn't been specified or C* version is 2.0") +requiressimulacron = unittest.skipIf(SIMULACRON_JAR is None, "Simulacron jar hasn't been specified") requirescompactstorage = xfail_scylla_version(lambda v: v >= Version('2025.1.0'), reason="ScyllaDB deprecated compact storage", raises=InvalidRequest) libevtest = unittest.skipUnless(EVENT_LOOP_MANAGER=="libev", "Test timing designed for libev loop") @@ -507,9 +462,8 @@ def use_cluster(cluster_name, nodes, ipformat=None, start=True, workloads=None, if 'graph' in workloads: jvm_args += ['-Xms1500M', '-Xmx1500M'] - else: - if PROTOCOL_VERSION >= 4 and not SCYLLA_VERSION: - jvm_args = [" -Dcassandra.custom_query_handler_class=org.apache.cassandra.cql3.CustomPayloadMirroringQueryHandler"] + elif not SCYLLA_VERSION: + jvm_args = [" -Dcassandra.custom_query_handler_class=org.apache.cassandra.cql3.CustomPayloadMirroringQueryHandler"] if len(workloads) > 0: for node in CCM_CLUSTER.nodes.values(): node.set_workloads(workloads) diff --git a/tests/integration/cqlengine/columns/test_container_columns.py b/tests/integration/cqlengine/columns/test_container_columns.py index 6fb2754877..95523dc1f3 100644 --- a/tests/integration/cqlengine/columns/test_container_columns.py +++ b/tests/integration/cqlengine/columns/test_container_columns.py @@ -18,7 +18,6 @@ import sys import traceback from uuid import uuid4 -from packaging.version import Version from cassandra import WriteTimeout, OperationTimedOut import cassandra.cqlengine.columns as columns @@ -29,7 +28,6 @@ from tests.integration import CASSANDRA_IP from tests.integration.cqlengine import is_prepend_reversed from tests.integration.cqlengine.base import BaseCassEngTestCase -from tests.integration import greaterthancass20, CASSANDRA_VERSION import pytest log = logging.getLogger(__name__) @@ -570,15 +568,12 @@ class TestTupleModel(Model): mixed_tuple = columns.Tuple(columns.Text, columns.Integer, columns.Text, required=False) -@greaterthancass20 class TestTupleColumn(BaseCassEngTestCase): @classmethod def setUpClass(cls): - # Skip annotations don't seem to skip class level teradown and setup methods - if CASSANDRA_VERSION >= Version('2.1'): - drop_table(TestTupleModel) - sync_table(TestTupleModel) + drop_table(TestTupleModel) + sync_table(TestTupleModel) @classmethod def tearDownClass(cls): @@ -774,15 +769,12 @@ class TestNestedModel(Model): set_tuple = columns.Set(columns.Tuple(columns.Integer, columns.Integer), required=False) -@greaterthancass20 class TestNestedType(BaseCassEngTestCase): @classmethod def setUpClass(cls): - # Skip annotations don't seem to skip class level teradown and setup methods - if CASSANDRA_VERSION >= Version('2.1'): - drop_table(TestNestedModel) - sync_table(TestNestedModel) + drop_table(TestNestedModel) + sync_table(TestNestedModel) @classmethod def tearDownClass(cls): diff --git a/tests/integration/cqlengine/columns/test_static_column.py b/tests/integration/cqlengine/columns/test_static_column.py index e5d63c29bb..3e45f7dea5 100644 --- a/tests/integration/cqlengine/columns/test_static_column.py +++ b/tests/integration/cqlengine/columns/test_static_column.py @@ -21,11 +21,9 @@ from cassandra.cqlengine.models import Model from tests.integration.cqlengine.base import BaseCassEngTestCase -from tests.integration import PROTOCOL_VERSION -# TODO: is this really a protocol limitation, or is it just C* version? -# good enough proxy for now -STATIC_SUPPORTED = PROTOCOL_VERSION >= 2 +# Static columns are supported for all currently supported protocol versions (v4+) +STATIC_SUPPORTED = True class TestStaticModel(Model): __test__ = False diff --git a/tests/integration/cqlengine/columns/test_validation.py b/tests/integration/cqlengine/columns/test_validation.py index ebffc0666c..ae5beed4c0 100644 --- a/tests/integration/cqlengine/columns/test_validation.py +++ b/tests/integration/cqlengine/columns/test_validation.py @@ -31,7 +31,7 @@ from cassandra.cqlengine.usertype import UserType from cassandra import util -from tests.integration import PROTOCOL_VERSION, CASSANDRA_VERSION, greaterthanorequalcass30, greaterthanorequalcass3_11 +from tests.integration import CASSANDRA_VERSION, greaterthanorequalcass30, greaterthanorequalcass3_11 from tests.integration.cqlengine.base import BaseCassEngTestCase import pytest @@ -193,7 +193,7 @@ def test_varint_io(self): class DataType(): @classmethod def setUpClass(cls): - if PROTOCOL_VERSION < 4 or CASSANDRA_VERSION < Version("3.0"): + if CASSANDRA_VERSION < Version("3.0"): return class DataTypeTest(Model): @@ -205,16 +205,15 @@ class DataTypeTest(Model): @classmethod def tearDownClass(cls): - if PROTOCOL_VERSION < 4 or CASSANDRA_VERSION < Version("3.0"): + if CASSANDRA_VERSION < Version("3.0"): return drop_table(cls.model_class) def setUp(self): - if PROTOCOL_VERSION < 4 or CASSANDRA_VERSION < Version("3.0"): - raise unittest.SkipTest("Protocol v4 datatypes " - "require native protocol 4+ and C* version >=3.0, " - "currently using protocol {0} and C* version {1}". - format(PROTOCOL_VERSION, CASSANDRA_VERSION)) + if CASSANDRA_VERSION < Version("3.0"): + raise unittest.SkipTest("Cassandra version >=3.0 required, " + "currently using C* version {0}". + format(CASSANDRA_VERSION)) def _check_value_is_correct_in_db(self, value): """ @@ -385,7 +384,7 @@ class UserModel(Model): class TestUDT(DataType, BaseCassEngTestCase): @classmethod def setUpClass(cls): - if PROTOCOL_VERSION < 4 or CASSANDRA_VERSION < Version("3.0"): + if CASSANDRA_VERSION < Version("3.0"): return cls.db_klass, cls.python_klass = UserDefinedType, User diff --git a/tests/integration/cqlengine/columns/test_value_io.py b/tests/integration/cqlengine/columns/test_value_io.py index 758ca714a6..7c17e80023 100644 --- a/tests/integration/cqlengine/columns/test_value_io.py +++ b/tests/integration/cqlengine/columns/test_value_io.py @@ -24,7 +24,6 @@ from cassandra.util import Date, Time -from tests.integration import PROTOCOL_VERSION from tests.integration.cqlengine.base import BaseCassEngTestCase @@ -198,25 +197,11 @@ def comparator_converter(self, val): class ProtocolV4Test(BaseColumnIOTest): + pass - @classmethod - def setUpClass(cls): - if PROTOCOL_VERSION >= 4: - super(ProtocolV4Test, cls).setUpClass() - - @classmethod - def tearDownClass(cls): - if PROTOCOL_VERSION >= 4: - super(ProtocolV4Test, cls).tearDownClass() class TestDate(ProtocolV4Test): - def setUp(self): - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol v4 datatypes require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) - - super(TestDate, self).setUp() - column = columns.Date now = Date(datetime.now().date()) @@ -226,12 +211,6 @@ def setUp(self): class TestTime(ProtocolV4Test): - def setUp(self): - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol v4 datatypes require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) - - super(TestTime, self).setUp() - column = columns.Time pkey_val = Time(time(2, 12, 7, 48)) @@ -240,12 +219,6 @@ def setUp(self): class TestSmallInt(ProtocolV4Test): - def setUp(self): - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol v4 datatypes require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) - - super(TestSmallInt, self).setUp() - column = columns.SmallInt pkey_val = 16768 @@ -254,12 +227,6 @@ def setUp(self): class TestTinyInt(ProtocolV4Test): - def setUp(self): - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol v4 datatypes require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) - - super(TestTinyInt, self).setUp() - column = columns.TinyInt pkey_val = 1 diff --git a/tests/integration/cqlengine/connections/test_connection.py b/tests/integration/cqlengine/connections/test_connection.py index 78d5133e63..9160d43fce 100644 --- a/tests/integration/cqlengine/connections/test_connection.py +++ b/tests/integration/cqlengine/connections/test_connection.py @@ -23,7 +23,7 @@ from cassandra.policies import RoundRobinPolicy from cassandra.query import dict_factory -from tests.integration import CASSANDRA_IP, PROTOCOL_VERSION, execute_with_long_wait_retry, local, TestCluster +from tests.integration import CASSANDRA_IP, execute_with_long_wait_retry, local, TestCluster from tests.integration.cqlengine.base import BaseCassEngTestCase from tests.integration.cqlengine import DEFAULT_KEYSPACE, setup_connection diff --git a/tests/integration/cqlengine/management/test_management.py b/tests/integration/cqlengine/management/test_management.py index 1332680cef..08cae93e69 100644 --- a/tests/integration/cqlengine/management/test_management.py +++ b/tests/integration/cqlengine/management/test_management.py @@ -23,7 +23,7 @@ from cassandra.cqlengine.models import Model from cassandra.cqlengine import columns -from tests.integration import PROTOCOL_VERSION, greaterthancass20, requires_collection_indexes, \ +from tests.integration import requires_collection_indexes, \ MockLoggingHandler, CASSANDRA_VERSION, SCYLLA_VERSION, xfail_scylla from tests.integration.cqlengine.base import BaseCassEngTestCase from tests.integration.cqlengine.query.test_queryset import TestModel @@ -369,11 +369,10 @@ def test_sync_warnings(self): sync_table(BaseInconsistent) sync_table(ChangedInconsistent) assert 'differing from the model type' in mock_handler.messages.get('warning')[0] - if CASSANDRA_VERSION >= Version('2.1'): - sync_type(DEFAULT_KEYSPACE, BaseInconsistentType) - mock_handler.reset() - sync_type(DEFAULT_KEYSPACE, ChangedInconsistentType) - assert 'differing from the model user type' in mock_handler.messages.get('warning')[0] + sync_type(DEFAULT_KEYSPACE, BaseInconsistentType) + mock_handler.reset() + sync_type(DEFAULT_KEYSPACE, ChangedInconsistentType) + assert 'differing from the model user type' in mock_handler.messages.get('warning')[0] class TestIndexSetModel(Model): @@ -432,7 +431,6 @@ def test_sync_index_case_sensitive(self): table_meta = management._get_table_metadata(IndexCaseSensitiveModel) assert management._get_index_name_by_column(table_meta, 'second_key') is not None - @greaterthancass20 @requires_collection_indexes @xfail_scylla("scylladb/scylladb#22019 - Scylla incorrectly reports target as keys(%s) for sets") def test_sync_indexed_set(self): @@ -464,9 +462,6 @@ def test_failure(self): class StaticColumnTests(BaseCassEngTestCase): def test_static_columns(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest("Native protocol 2+ required, currently using: {0}".format(PROTOCOL_VERSION)) - class StaticModel(Model): id = columns.Integer(primary_key=True) c = columns.Integer(primary_key=True) diff --git a/tests/integration/cqlengine/model/test_model_io.py b/tests/integration/cqlengine/model/test_model_io.py index f55815310a..a1ce2d6984 100644 --- a/tests/integration/cqlengine/model/test_model_io.py +++ b/tests/integration/cqlengine/model/test_model_io.py @@ -30,7 +30,7 @@ from cassandra.cqlengine.statements import SelectStatement, DeleteStatement, WhereClause from cassandra.cqlengine.operators import EqualsOperator -from tests.integration import PROTOCOL_VERSION, greaterthanorequalcass3_10 +from tests.integration import greaterthanorequalcass3_10 from tests.integration.cqlengine.base import BaseCassEngTestCase from tests.integration.cqlengine import DEFAULT_KEYSPACE from tests.util import assertSetEqual @@ -248,9 +248,6 @@ def test_can_insert_model_with_all_protocol_v4_column_types(self): @test_category data_types:primitive """ - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol v4 datatypes require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) - class v4DatatypesModel(Model): id = columns.Integer(primary_key=True) a = columns.Date() @@ -672,25 +669,15 @@ class TestQuerying(BaseCassEngTestCase): @classmethod def setUpClass(cls): - if PROTOCOL_VERSION < 4: - return - super(TestQuerying, cls).setUpClass() drop_table(TestQueryModel) sync_table(TestQueryModel) @classmethod def tearDownClass(cls): - if PROTOCOL_VERSION < 4: - return - super(TestQuerying, cls).tearDownClass() drop_table(TestQueryModel) - def setUp(self): - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Date query tests require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) - def test_query_with_date(self): uid = uuid4() day = date(2013, 11, 26) @@ -770,7 +757,7 @@ def test_routing_key_is_ignored(self): """.format(DEFAULT_KEYSPACE)) bound = prepared.bind((1, 2)) - mrk = BasicModelNoRouting._routing_key_from_values([1], self.session.cluster.protocol_version) + mrk = BasicModelNoRouting._routing_key_from_values([1]) simple = SimpleStatement("") simple.routing_key = mrk assert bound.routing_key != simple.routing_key @@ -802,7 +789,7 @@ def test_routing_key_generation_basic(self): """.format(DEFAULT_KEYSPACE)) bound = prepared.bind((1, 2)) - mrk = BasicModel._routing_key_from_values([1], self.session.cluster.protocol_version) + mrk = BasicModel._routing_key_from_values([1]) simple = SimpleStatement("") simple.routing_key = mrk assert bound.routing_key == simple.routing_key @@ -823,7 +810,7 @@ def test_routing_key_generation_multi(self): 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) + mrk = BasicModelMulti._routing_key_from_values([1, 2]) simple = SimpleStatement("") simple.routing_key = mrk assert bound.routing_key == simple.routing_key @@ -849,7 +836,7 @@ def test_routing_key_generation_complex(self): 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) + mrk = ComplexModelRouting._routing_key_from_values([partition, cluster, text, float]) simple = SimpleStatement("") simple.routing_key = mrk assert bound.routing_key == simple.routing_key diff --git a/tests/integration/cqlengine/model/test_udts.py b/tests/integration/cqlengine/model/test_udts.py index 80f1b9693f..4580bf0da2 100644 --- a/tests/integration/cqlengine/model/test_udts.py +++ b/tests/integration/cqlengine/model/test_udts.py @@ -25,7 +25,6 @@ from cassandra.cqlengine import ValidationError from cassandra.util import Date, Time -from tests.integration import PROTOCOL_VERSION from tests.integration.cqlengine.base import BaseCassEngTestCase from tests.integration.cqlengine import DEFAULT_KEYSPACE import pytest @@ -65,10 +64,6 @@ class AllDatatypesModel(Model): class UserDefinedTypeTests(BaseCassEngTestCase): - def setUp(self): - if PROTOCOL_VERSION < 3: - raise unittest.SkipTest("UDTs require native protocol 3+, currently using: {0}".format(PROTOCOL_VERSION)) - def test_can_create_udts(self): class User(UserType): age = columns.Integer() @@ -302,8 +297,6 @@ def test_can_insert_udts_protocol_v4_datatypes(self): @test_category data_types:udt """ - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol v4 datatypes in UDTs require native protocol 4+, currently using: {0}".format(PROTOCOL_VERSION)) class Allv4Datatypes(UserType): a = columns.Date() diff --git a/tests/integration/cqlengine/model/test_updates.py b/tests/integration/cqlengine/model/test_updates.py index c64df8fdcc..d8ebfa56fe 100644 --- a/tests/integration/cqlengine/model/test_updates.py +++ b/tests/integration/cqlengine/model/test_updates.py @@ -17,7 +17,6 @@ from cassandra.cqlengine import ValidationError -from tests.integration import greaterthancass21 from tests.integration.cqlengine.base import BaseCassEngTestCase from cassandra.cqlengine.models import Model from cassandra.cqlengine import columns @@ -178,7 +177,6 @@ class ModelWithDefaultCollection(Model): udt = columns.UserDefinedType(UDT) udt_default = columns.UserDefinedType(UDT, default=UDT(age=1, mf={2: 2})) -@greaterthancass21 class ModelWithDefaultTests(BaseCassEngTestCase): @classmethod diff --git a/tests/integration/cqlengine/query/test_queryset.py b/tests/integration/cqlengine/query/test_queryset.py index 34b4ab5964..06927c4059 100644 --- a/tests/integration/cqlengine/query/test_queryset.py +++ b/tests/integration/cqlengine/query/test_queryset.py @@ -17,7 +17,6 @@ from datetime import datetime from uuid import uuid4 -from packaging.version import Version import uuid from cassandra.cluster import Session @@ -38,8 +37,7 @@ from cassandra.cqlengine import operators from cassandra.util import uuid_from_time from cassandra.cqlengine.connection import get_session -from tests.integration import PROTOCOL_VERSION, CASSANDRA_VERSION, greaterthancass20, greaterthancass21, \ - greaterthanorequalcass30, TestCluster, requires_collection_indexes +from tests.integration import greaterthanorequalcass30, TestCluster, requires_collection_indexes from tests.integration.cqlengine import execute_count, DEFAULT_KEYSPACE import pytest @@ -362,22 +360,21 @@ def setUpClass(cls): IndexedTestModel.objects.create(test_id=11, attempt_id=3, description='try12', expected_result=75, test_result=45) - if CASSANDRA_VERSION >= Version('2.1'): - drop_table(IndexedCollectionsTestModel) - sync_table(IndexedCollectionsTestModel) - IndexedCollectionsTestModel.objects.create(test_id=12, attempt_id=3, description='list12', expected_result=75, - test_result=45, test_list=[1, 2, 42], test_set=set([1, 2, 3]), - test_map={'1': 1, '2': 2, '3': 3}) - IndexedCollectionsTestModel.objects.create(test_id=13, attempt_id=3, description='list13', expected_result=75, - test_result=45, test_list=[3, 4, 5], test_set=set([4, 5, 42]), - test_map={'1': 5, '2': 6, '3': 7}) - IndexedCollectionsTestModel.objects.create(test_id=14, attempt_id=3, description='list14', expected_result=75, - test_result=45, test_list=[1, 2, 3], test_set=set([1, 2, 3]), - test_map={'1': 1, '2': 2, '3': 42}) - - IndexedCollectionsTestModel.objects.create(test_id=15, attempt_id=4, description='list14', expected_result=75, - test_result=45, test_list_no_index=[1, 2, 3], test_set_no_index=set([1, 2, 3]), - test_map_no_index={'1': 1, '2': 2, '3': 42}) + drop_table(IndexedCollectionsTestModel) + sync_table(IndexedCollectionsTestModel) + IndexedCollectionsTestModel.objects.create(test_id=12, attempt_id=3, description='list12', expected_result=75, + test_result=45, test_list=[1, 2, 42], test_set=set([1, 2, 3]), + test_map={'1': 1, '2': 2, '3': 3}) + IndexedCollectionsTestModel.objects.create(test_id=13, attempt_id=3, description='list13', expected_result=75, + test_result=45, test_list=[3, 4, 5], test_set=set([4, 5, 42]), + test_map={'1': 5, '2': 6, '3': 7}) + IndexedCollectionsTestModel.objects.create(test_id=14, attempt_id=3, description='list14', expected_result=75, + test_result=45, test_list=[1, 2, 3], test_set=set([1, 2, 3]), + test_map={'1': 1, '2': 2, '3': 42}) + + IndexedCollectionsTestModel.objects.create(test_id=15, attempt_id=4, description='list14', expected_result=75, + test_result=45, test_list_no_index=[1, 2, 3], test_set_no_index=set([1, 2, 3]), + test_map_no_index={'1': 1, '2': 2, '3': 42}) @classmethod def tearDownClass(cls): @@ -590,7 +587,6 @@ def test_zero_result(self): q = TestModel.objects.distinct(['test_id']).filter(test_id__in=[52]) assert len(q) == 0 - @greaterthancass21 @execute_count(2) def test_distinct_with_explicit_count(self): q = TestModel.objects.distinct(['test_id']) @@ -723,7 +719,6 @@ def test_primary_key_or_index_must_have_equal_relation_filter(self): q = TestModel.objects(test_id__gt=0) list([i for i in q]) - @greaterthancass20 @execute_count(7) def test_indexed_field_can_be_queried(self): """ @@ -1005,7 +1000,6 @@ class bool_model2(Model): assert len(list(bool_model2.objects(k__in=(True, False)))) == 2 -@greaterthancass20 @requires_collection_indexes class TestContainsOperator(BaseQuerySetUsage): @@ -1097,9 +1091,6 @@ def test_objects_property_returns_fresh_queryset(self): class PageQueryTests(BaseCassEngTestCase): @execute_count(3) def test_paged_result_handling(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest("Paging requires native protocol 2+, currently using: {0}".format(PROTOCOL_VERSION)) - # addresses #225 class PagingTest(Model): id = columns.Integer(primary_key=True) diff --git a/tests/integration/cqlengine/query/test_updates.py b/tests/integration/cqlengine/query/test_updates.py index cedde0cd7b..bd29395d23 100644 --- a/tests/integration/cqlengine/query/test_updates.py +++ b/tests/integration/cqlengine/query/test_updates.py @@ -22,7 +22,6 @@ from tests.integration.cqlengine import is_prepend_reversed from tests.integration.cqlengine.base import BaseCassEngTestCase, TestQueryUpdateModel from tests.integration.cqlengine import execute_count -from tests.integration import greaterthancass20 import pytest @@ -234,7 +233,6 @@ def test_map_update_none_deletes_key(self): obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster) assert obj.text_map == {"foo": '1'} - @greaterthancass20 @execute_count(5) def test_map_update_remove(self): """ diff --git a/tests/integration/cqlengine/test_ifexists.py b/tests/integration/cqlengine/test_ifexists.py index 6c2ff437ab..6313aa3000 100644 --- a/tests/integration/cqlengine/test_ifexists.py +++ b/tests/integration/cqlengine/test_ifexists.py @@ -21,7 +21,6 @@ from cassandra.cqlengine.query import BatchQuery, BatchType, LWTException, IfExistsWithCounterColumn from tests.integration.cqlengine.base import BaseCassEngTestCase -from tests.integration import PROTOCOL_VERSION import pytest @@ -78,7 +77,6 @@ def tearDownClass(cls): class IfExistsUpdateTests(BaseIfExistsTest): - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_update_if_exists(self): """ Tests that update with if_exists work as expected @@ -116,7 +114,6 @@ def test_update_if_exists(self): assert assertion.value.existing.get('[applied]') == False - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_batch_update_if_exists_success(self): """ Tests that batch update with if_exists work as expected @@ -150,7 +147,6 @@ def test_batch_update_if_exists_success(self): assert tm.count == 8 assert tm.text == '111111111' - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_batch_mixed_update_if_exists_success(self): """ Tests that batch update with with one bad query will still fail with LWTException @@ -172,7 +168,6 @@ def test_batch_mixed_update_if_exists_success(self): assert assertion.value.existing.get('[applied]') == False - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_delete_if_exists(self): """ Tests that delete with if_exists work, and throw proper LWT exception when they are are not applied @@ -203,7 +198,6 @@ def test_delete_if_exists(self): assert assertion.value.existing.get('[applied]') == False - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_batch_delete_if_exists_success(self): """ Tests that batch deletes with if_exists work, and throw proper LWTException when they are are not applied @@ -232,7 +226,6 @@ def test_batch_delete_if_exists_success(self): assert assertion.value.existing.get('[applied]') == False - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_batch_delete_mixed(self): """ Tests that batch deletes with multiple queries and throw proper LWTException when they are are not all applicable diff --git a/tests/integration/cqlengine/test_ifnotexists.py b/tests/integration/cqlengine/test_ifnotexists.py index 6a1dd9d4bc..4159a3f00c 100644 --- a/tests/integration/cqlengine/test_ifnotexists.py +++ b/tests/integration/cqlengine/test_ifnotexists.py @@ -21,7 +21,6 @@ from cassandra.cqlengine.query import BatchQuery, LWTException, IfNotExistsWithCounterColumn from tests.integration.cqlengine.base import BaseCassEngTestCase -from tests.integration import PROTOCOL_VERSION import pytest class TestIfNotExistsModel(Model): @@ -73,7 +72,6 @@ def tearDownClass(cls): class IfNotExistsInsertTests(BaseIfNotExistsTest): - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_insert_if_not_exists(self): """ tests that insertion with if_not_exists work as expected """ @@ -101,7 +99,6 @@ def test_insert_if_not_exists(self): assert tm.count == 8 assert tm.text == '123456789' - @unittest.skipUnless(PROTOCOL_VERSION >= 2, "only runs against the cql3 protocol v2.0") def test_batch_insert_if_not_exists(self): """ tests that batch insertion with if_not_exists work as expected """ diff --git a/tests/integration/cqlengine/test_lwt_conditional.py b/tests/integration/cqlengine/test_lwt_conditional.py index f8d9d01035..634d482749 100644 --- a/tests/integration/cqlengine/test_lwt_conditional.py +++ b/tests/integration/cqlengine/test_lwt_conditional.py @@ -22,7 +22,6 @@ from cassandra.cqlengine.statements import ConditionalClause from tests.integration.cqlengine.base import BaseCassEngTestCase -from tests.integration import greaterthancass20 import pytest @@ -43,7 +42,6 @@ class TestUpdateModel(Model): text = columns.Text(required=False, index=True) -@greaterthancass20 class TestConditional(BaseCassEngTestCase): @classmethod diff --git a/tests/integration/cqlengine/test_ttl.py b/tests/integration/cqlengine/test_ttl.py index df1afb6bf0..9fa5895566 100644 --- a/tests/integration/cqlengine/test_ttl.py +++ b/tests/integration/cqlengine/test_ttl.py @@ -15,8 +15,6 @@ import unittest -from packaging.version import Version - from cassandra import InvalidRequest from cassandra.cqlengine.management import sync_table, drop_table from tests.integration.cqlengine.base import BaseCassEngTestCase @@ -25,7 +23,6 @@ from cassandra.cqlengine import columns from unittest import mock from cassandra.cqlengine.connection import get_session -from tests.integration import CASSANDRA_VERSION, greaterthancass20 class TestTTLModel(Model): @@ -62,17 +59,15 @@ class BaseDefaultTTLTest(BaseCassEngTestCase): @classmethod def setUpClass(cls): - if CASSANDRA_VERSION >= Version('2.0'): - super(BaseDefaultTTLTest, cls).setUpClass() - sync_table(TestDefaultTTLModel) - sync_table(TestTTLModel) + super(BaseDefaultTTLTest, cls).setUpClass() + sync_table(TestDefaultTTLModel) + sync_table(TestTTLModel) @classmethod def tearDownClass(cls): - if CASSANDRA_VERSION >= Version('2.0'): - super(BaseDefaultTTLTest, cls).tearDownClass() - drop_table(TestDefaultTTLModel) - drop_table(TestTTLModel) + super(BaseDefaultTTLTest, cls).tearDownClass() + drop_table(TestDefaultTTLModel) + drop_table(TestTTLModel) class TTLQueryTests(BaseTTLTest): diff --git a/tests/integration/datatype_utils.py b/tests/integration/datatype_utils.py index 1f7fb50a05..9191f2de8d 100644 --- a/tests/integration/datatype_utils.py +++ b/tests/integration/datatype_utils.py @@ -52,12 +52,10 @@ def update_datatypes(): _cass_version, _cql_version = get_server_versions() - if _cass_version >= (2, 1, 0): - COLLECTION_TYPES.add('tuple') + COLLECTION_TYPES.add('tuple') - if _cass_version >= (2, 2, 0): - PRIMITIVE_DATATYPES.update(['date', 'time', 'smallint', 'tinyint']) - PRIMITIVE_DATATYPES_KEYS.update(['date', 'time', 'smallint', 'tinyint']) + PRIMITIVE_DATATYPES.update(['date', 'time', 'smallint', 'tinyint']) + PRIMITIVE_DATATYPES_KEYS.update(['date', 'time', 'smallint', 'tinyint']) if _cass_version >= (3, 10): PRIMITIVE_DATATYPES.add('duration') diff --git a/tests/integration/long/test_failure_types.py b/tests/integration/long/test_failure_types.py index beb10f02c0..0c3d90eb92 100644 --- a/tests/integration/long/test_failure_types.py +++ b/tests/integration/long/test_failure_types.py @@ -28,7 +28,7 @@ from cassandra.concurrent import execute_concurrent_with_args from cassandra.query import SimpleStatement from tests.integration import ( - use_singledc, PROTOCOL_VERSION, get_cluster, setup_keyspace, remove_cluster, + use_singledc, get_cluster, setup_keyspace, remove_cluster, get_node, start_cluster_wait_for_up, requiresmallclockgranularity, local, CASSANDRA_VERSION, TestCluster) @@ -43,23 +43,19 @@ @local def setup_module(): """ - We need some custom setup for this module. All unit tests in this module - require protocol >=4. We won't bother going through the setup required unless that is the - protocol version we are using. + We need some custom setup for this module. """ - # If we aren't at protocol v 4 or greater don't waste time setting anything up, all tests will be skipped - if PROTOCOL_VERSION >= 4: - use_singledc(start=False) - ccm_cluster = get_cluster() - ccm_cluster.stop() - config_options = { - 'tombstone_failure_threshold': 2000, - 'tombstone_warn_threshold': 1000, - } - ccm_cluster.set_configuration_options(config_options) - start_cluster_wait_for_up(ccm_cluster) - setup_keyspace() + use_singledc(start=False) + ccm_cluster = get_cluster() + ccm_cluster.stop() + config_options = { + 'tombstone_failure_threshold': 2000, + 'tombstone_warn_threshold': 1000, + } + ccm_cluster.set_configuration_options(config_options) + start_cluster_wait_for_up(ccm_cluster) + setup_keyspace() def teardown_module(): @@ -67,20 +63,12 @@ def teardown_module(): The rest of the tests don't need custom tombstones remove the cluster so as to not interfere with other tests. """ - if PROTOCOL_VERSION >= 4: - remove_cluster() + remove_cluster() class ClientExceptionTests(unittest.TestCase): def setUp(self): - """ - Test is skipped if run with native protocol version <4 - """ - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest( - "Native protocol 4,0+ is required for custom payloads, currently using %r" - % (PROTOCOL_VERSION,)) self.cluster = TestCluster() self.session = self.cluster.connect() self.nodes_currently_failing = [] diff --git a/tests/integration/long/test_large_data.py b/tests/integration/long/test_large_data.py index 0a1b368bf0..c6ddaea709 100644 --- a/tests/integration/long/test_large_data.py +++ b/tests/integration/long/test_large_data.py @@ -21,7 +21,7 @@ from cassandra.cluster import ExecutionProfile, EXEC_PROFILE_DEFAULT from cassandra.query import dict_factory from cassandra.query import SimpleStatement -from tests.integration import use_singledc, PROTOCOL_VERSION, TestCluster +from tests.integration import use_singledc, TestCluster from tests.integration.long.utils import create_schema import unittest diff --git a/tests/integration/long/test_loadbalancingpolicies.py b/tests/integration/long/test_loadbalancingpolicies.py index fd8edde14c..619e729b47 100644 --- a/tests/integration/long/test_loadbalancingpolicies.py +++ b/tests/integration/long/test_loadbalancingpolicies.py @@ -633,7 +633,7 @@ def test_token_aware_with_transient_replication(self): query = session.prepare("SELECT * FROM test_tr.users WHERE id = ?") for i in range(100): f = session.execute_async(query, (i,), trace=True) - full_dc1_replicas = [h for h in cluster.metadata.get_replicas('test_tr', cqltypes.Int32Type.serialize(i, cluster.protocol_version)) + full_dc1_replicas = [h for h in cluster.metadata.get_replicas('test_tr', cqltypes.Int32Type.serialize(i)) if h.datacenter == 'dc1'] assert len(full_dc1_replicas) == 2 diff --git a/tests/integration/simulacron/__init__.py b/tests/integration/simulacron/__init__.py index b75b67c540..6536e91c4a 100644 --- a/tests/integration/simulacron/__init__.py +++ b/tests/integration/simulacron/__init__.py @@ -13,7 +13,7 @@ # limitations under the License import unittest -from tests.integration import CASSANDRA_VERSION, SIMULACRON_JAR, PROTOCOL_VERSION +from tests.integration import SIMULACRON_JAR, PROTOCOL_VERSION from tests.integration.simulacron.utils import ( clear_queries, start_and_prime_singledc, @@ -23,8 +23,6 @@ from cassandra.cluster import Cluster -from packaging.version import Version - PROTOCOL_VERSION = min(4, PROTOCOL_VERSION) @@ -45,7 +43,7 @@ class SimulacronCluster(SimulacronBase): @classmethod def setUpClass(cls): - if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"): + if SIMULACRON_JAR is None: return start_and_prime_singledc() @@ -55,7 +53,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"): + if SIMULACRON_JAR is None: return if cls.cluster: diff --git a/tests/integration/simulacron/test_policies.py b/tests/integration/simulacron/test_policies.py index 3f94a41222..96653b9e45 100644 --- a/tests/integration/simulacron/test_policies.py +++ b/tests/integration/simulacron/test_policies.py @@ -19,14 +19,12 @@ from cassandra.policies import ConstantSpeculativeExecutionPolicy, RoundRobinPolicy, RetryPolicy, WriteType from cassandra.protocol import OverloadedErrorMessage, IsBootstrappingErrorMessage, TruncateError, ServerError -from tests.integration import greaterthancass21, requiressimulacron, SIMULACRON_JAR, \ - CASSANDRA_VERSION +from tests.integration import requiressimulacron, SIMULACRON_JAR from tests.integration.simulacron import PROTOCOL_VERSION from tests.integration.simulacron.utils import start_and_prime_singledc, prime_query, \ stop_simulacron, NO_THEN, clear_queries from itertools import count -from packaging.version import Version import pytest @@ -48,7 +46,7 @@ class SpecExecTest(unittest.TestCase): @classmethod def setUpClass(cls): - if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"): + if SIMULACRON_JAR is None: return start_and_prime_singledc() @@ -73,7 +71,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"): + if SIMULACRON_JAR is None: return cls.cluster.shutdown() @@ -82,7 +80,6 @@ def tearDownClass(cls): def tearDown(self): clear_queries() - @greaterthancass21 def test_speculative_execution(self): """ Test to ensure that speculative execution honors LBP, and that they retry appropriately. @@ -254,13 +251,13 @@ def reset_counters(self): class RetryPolicyTests(unittest.TestCase): @classmethod def setUpClass(cls): - if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"): + if SIMULACRON_JAR is None: return start_and_prime_singledc() @classmethod def tearDownClass(cls): - if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"): + if SIMULACRON_JAR is None: return stop_simulacron() diff --git a/tests/integration/standard/test_authentication.py b/tests/integration/standard/test_authentication.py index eb8019bf65..a3ff97e1c7 100644 --- a/tests/integration/standard/test_authentication.py +++ b/tests/integration/standard/test_authentication.py @@ -19,7 +19,7 @@ from cassandra.cluster import NoHostAvailable from cassandra.auth import PlainTextAuthProvider, SASLClient, SaslAuthProvider -from tests.integration import use_singledc, get_cluster, remove_cluster, PROTOCOL_VERSION, \ +from tests.integration import use_singledc, get_cluster, remove_cluster, \ CASSANDRA_IP, CASSANDRA_VERSION, USE_CASS_EXTERNAL, start_cluster_wait_for_up, TestCluster from tests.integration.util import assert_quiescent_pool_state @@ -62,19 +62,12 @@ class AuthenticationTests(unittest.TestCase): """ def get_authentication_provider(self, username, password): """ - Return correct authentication provider based on protocol version. - There is a difference in the semantics of authentication provider argument with protocol versions 1 and 2 - For protocol version 2 and higher it should be a PlainTextAuthProvider object. - For protocol version 1 it should be a function taking hostname as an argument and returning a dictionary - containing username and password. + Return correct authentication provider. :param username: authentication username :param password: authentication password :return: authentication object suitable for Cluster.connect() """ - if PROTOCOL_VERSION < 2: - return lambda hostname: dict(username=username, password=password) - else: - return PlainTextAuthProvider(username=username, password=password) + return PlainTextAuthProvider(username=username, password=password) def cluster_as(self, usr, pwd): # test we can connect at least once with creds @@ -161,8 +154,6 @@ class SaslAuthenticatorTests(AuthenticationTests): Test SaslAuthProvider as PlainText """ def setUp(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest('Sasl authentication not available for protocol v1') if SASLClient is None: raise unittest.SkipTest('pure-sasl is not installed') diff --git a/tests/integration/standard/test_client_warnings.py b/tests/integration/standard/test_client_warnings.py index 781b5b7860..83572af2df 100644 --- a/tests/integration/standard/test_client_warnings.py +++ b/tests/integration/standard/test_client_warnings.py @@ -17,7 +17,7 @@ from cassandra.query import BatchStatement -from tests.integration import (use_singledc, PROTOCOL_VERSION, local, TestCluster, +from tests.integration import (use_singledc, local, TestCluster, requires_custom_payload, xfail_scylla) from tests.util import assertRegex, assertDictEqual @@ -30,9 +30,6 @@ class ClientWarningTests(unittest.TestCase): @classmethod def setUpClass(cls): - if PROTOCOL_VERSION < 4: - return - cls.cluster = TestCluster() cls.session = cls.cluster.connect() @@ -47,17 +44,8 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - if PROTOCOL_VERSION < 4: - return - cls.cluster.shutdown() - def setUp(self): - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest( - "Native protocol 4,0+ is required for client warnings, currently using %r" - % (PROTOCOL_VERSION,)) - def test_warning_basic(self): """ Test to validate that client warnings can be surfaced diff --git a/tests/integration/standard/test_cluster.py b/tests/integration/standard/test_cluster.py index 1208edb9d2..f02b48008c 100644 --- a/tests/integration/standard/test_cluster.py +++ b/tests/integration/standard/test_cluster.py @@ -260,27 +260,9 @@ def test_protocol_negotiation(self): if CASSANDRA_VERSION >= Version('4.0-beta5'): assert updated_protocol_version == cassandra.ProtocolVersion.V5 assert updated_cluster_version == cassandra.ProtocolVersion.V5 - elif CASSANDRA_VERSION >= Version('4.0-a'): - assert updated_protocol_version == cassandra.ProtocolVersion.V4 - assert updated_cluster_version == cassandra.ProtocolVersion.V4 - elif CASSANDRA_VERSION >= Version('3.11'): - assert updated_protocol_version == cassandra.ProtocolVersion.V4 - assert updated_cluster_version == cassandra.ProtocolVersion.V4 - elif CASSANDRA_VERSION >= Version('3.0'): + else: assert updated_protocol_version == cassandra.ProtocolVersion.V4 assert updated_cluster_version == cassandra.ProtocolVersion.V4 - elif CASSANDRA_VERSION >= Version('2.2'): - assert updated_protocol_version == 4 - assert updated_cluster_version == 4 - elif CASSANDRA_VERSION >= Version('2.1'): - assert updated_protocol_version == 3 - assert updated_cluster_version == 3 - elif CASSANDRA_VERSION >= Version('2.0'): - assert updated_protocol_version == 2 - assert updated_cluster_version == 2 - else: - assert updated_protocol_version == 1 - assert updated_cluster_version == 1 cluster.shutdown() @@ -376,19 +358,19 @@ def test_auth_provider_is_callable(self): Ensure that auth_providers are always callable """ with pytest.raises(TypeError): - Cluster(auth_provider=1, protocol_version=1) - c = TestCluster(protocol_version=1) + Cluster(auth_provider=1, protocol_version=4) + c = TestCluster(protocol_version=4) with pytest.raises(TypeError): setattr(c, 'auth_provider', 1) - def test_v2_auth_provider(self): + def test_auth_provider(self): """ - Check for v2 auth_provider compliance + Check for auth_provider compliance """ bad_auth_provider = lambda x: {'username': 'foo', 'password': 'bar'} with pytest.raises(TypeError): - Cluster(auth_provider=bad_auth_provider, protocol_version=2) - c = TestCluster(protocol_version=2) + Cluster(auth_provider=bad_auth_provider, protocol_version=4) + c = TestCluster(protocol_version=4) with pytest.raises(TypeError): setattr(c, 'auth_provider', bad_auth_provider) @@ -462,10 +444,6 @@ def test_refresh_schema_type(self): if get_server_versions()[0] < (2, 1, 0): raise unittest.SkipTest('UDTs were introduced in Cassandra 2.1') - if PROTOCOL_VERSION < 3: - raise unittest.SkipTest('UDTs are not specified in change events for protocol v2') - # We may want to refresh types on keyspace change events in that case(?) - cluster = TestCluster() session = cluster.connect() @@ -1093,21 +1071,21 @@ def test_stale_connections_after_shutdown(self): Originates from https://github.com/scylladb/python-driver/issues/120 """ for _ in range(10): - with TestCluster(protocol_version=3) as cluster: + with TestCluster() as cluster: cluster.connect().execute("SELECT * FROM system_schema.keyspaces") time.sleep(1) - with TestCluster(protocol_version=3) as cluster: + with TestCluster() as cluster: session = cluster.connect() for _ in range(5): session.execute("SELECT * FROM system_schema.keyspaces") for _ in range(10): - with TestCluster(protocol_version=3) as cluster: + with TestCluster() as cluster: cluster.connect().execute("SELECT * FROM system_schema.keyspaces") for _ in range(10): - with TestCluster(protocol_version=3) as cluster: + with TestCluster() as cluster: cluster.connect() result = subprocess.run(["lsof -nP | awk '$3 ~ \":9042\" {print $0}' | grep ''"], shell=True, capture_output=True) diff --git a/tests/integration/standard/test_concurrent.py b/tests/integration/standard/test_concurrent.py index 5e6b1ffd59..5d464b9b23 100644 --- a/tests/integration/standard/test_concurrent.py +++ b/tests/integration/standard/test_concurrent.py @@ -22,7 +22,7 @@ from cassandra.policies import HostDistance from cassandra.query import dict_factory, tuple_factory, SimpleStatement -from tests.integration import use_singledc, PROTOCOL_VERSION, TestCluster +from tests.integration import use_singledc, TestCluster import unittest import pytest @@ -178,11 +178,6 @@ def test_execute_concurrent_with_args_generator(self): next(results) def test_execute_concurrent_paged_result(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2+ is required for Paging, currently testing against %r" - % (PROTOCOL_VERSION,)) - num_statements = 201 statement = SimpleStatement( "INSERT INTO test3rf.test (k, v) VALUES (%s, %s)", @@ -221,11 +216,6 @@ def test_execute_concurrent_paged_result_generator(self): @test_category paging """ - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2+ is required for Paging, currently testing against %r" - % (PROTOCOL_VERSION,)) - num_statements = 201 statement = SimpleStatement( "INSERT INTO test3rf.test (k, v) VALUES (%s, %s)", diff --git a/tests/integration/standard/test_connection.py b/tests/integration/standard/test_connection.py index 630e5e6ba0..a21feb5db8 100644 --- a/tests/integration/standard/test_connection.py +++ b/tests/integration/standard/test_connection.py @@ -31,7 +31,7 @@ from tests import is_monkey_patched from tests.integration import use_singledc, get_node, CASSANDRA_IP, local, \ - requiresmallclockgranularity, greaterthancass20, TestCluster + requiresmallclockgranularity, TestCluster try: import cassandra.io.asyncorereactor @@ -125,7 +125,6 @@ def tearDown(self): self.cluster.shutdown() @local - @greaterthancass20 def test_heart_beat_timeout(self): # Setup a host listener to ensure the nodes don't go down test_listener = TestHostListener() diff --git a/tests/integration/standard/test_control_connection.py b/tests/integration/standard/test_control_connection.py index 2788a1d837..52d3f08cc4 100644 --- a/tests/integration/standard/test_control_connection.py +++ b/tests/integration/standard/test_control_connection.py @@ -23,7 +23,7 @@ from cassandra.protocol import ConfigurationException -from tests.integration import use_singledc, PROTOCOL_VERSION, TestCluster, greaterthanorequalcass40, \ +from tests.integration import use_singledc, TestCluster, greaterthanorequalcass40, \ xfail_scylla_version_lt from tests.integration.datatype_utils import update_datatypes @@ -35,10 +35,6 @@ def setup_module(): class ControlConnectionTests(unittest.TestCase): def setUp(self): - if PROTOCOL_VERSION < 3: - raise unittest.SkipTest( - "Native protocol 3,0+ is required for UDTs using %r" - % (PROTOCOL_VERSION,)) self.cluster = TestCluster() def tearDown(self): diff --git a/tests/integration/standard/test_custom_payload.py b/tests/integration/standard/test_custom_payload.py index fc58081070..2179c4225d 100644 --- a/tests/integration/standard/test_custom_payload.py +++ b/tests/integration/standard/test_custom_payload.py @@ -17,7 +17,7 @@ from cassandra.query import (SimpleStatement, BatchStatement, BatchType) -from tests.integration import (use_singledc, PROTOCOL_VERSION, local, TestCluster, +from tests.integration import (use_singledc, local, TestCluster, requires_custom_payload) import pytest diff --git a/tests/integration/standard/test_custom_protocol_handler.py b/tests/integration/standard/test_custom_protocol_handler.py index 239f7e7336..1273f834ad 100644 --- a/tests/integration/standard/test_custom_protocol_handler.py +++ b/tests/integration/standard/test_custom_protocol_handler.py @@ -203,7 +203,7 @@ class CustomResultMessageRaw(ResultMessage): my_type_codes[0xc] = UUIDType type_codes = my_type_codes - def recv_results_rows(self, f, protocol_version, user_type_map, result_metadata, column_encryption_policy): + def recv_results_rows(self, f, user_type_map, result_metadata, column_encryption_policy): self.recv_results_metadata(f, user_type_map) column_metadata = self.column_metadata or result_metadata rowcount = read_int(f) @@ -232,7 +232,7 @@ class CustomResultMessageTracked(ResultMessage): type_codes = my_type_codes checked_rev_row_set = set() - def recv_results_rows(self, f, protocol_version, user_type_map, result_metadata, column_encryption_policy): + def recv_results_rows(self, f, user_type_map, result_metadata, column_encryption_policy): self.recv_results_metadata(f, user_type_map) column_metadata = self.column_metadata or result_metadata rowcount = read_int(f) @@ -241,7 +241,7 @@ def recv_results_rows(self, f, protocol_version, user_type_map, result_metadata, self.column_types = [c[3] for c in column_metadata] self.checked_rev_row_set.update(self.column_types) self.parsed_rows = [ - tuple(ctype.from_binary(val, protocol_version) + tuple(ctype.from_binary(val) for ctype, val in zip(self.column_types, row)) for row in rows] diff --git a/tests/integration/standard/test_cython_protocol_handlers.py b/tests/integration/standard/test_cython_protocol_handlers.py index f44d613c64..6033b84ad9 100644 --- a/tests/integration/standard/test_cython_protocol_handlers.py +++ b/tests/integration/standard/test_cython_protocol_handlers.py @@ -12,8 +12,8 @@ from cassandra.protocol import ProtocolHandler, LazyProtocolHandler, NumpyProtocolHandler from cassandra.query import tuple_factory from tests import VERIFY_CYTHON -from tests.integration import use_singledc, notprotocolv1, \ - drop_keyspace_shutdown_cluster, BasicSharedKeyspaceUnitTestCase, greaterthancass21, TestCluster +from tests.integration import use_singledc, \ + drop_keyspace_shutdown_cluster, BasicSharedKeyspaceUnitTestCase, TestCluster from tests.integration.datatype_utils import update_datatypes from tests.integration.standard.utils import ( create_table_with_all_types, get_all_primitive_params, get_primitive_datatypes) @@ -78,7 +78,6 @@ def test_cython_lazy_results_paged(self): cluster.shutdown() - @notprotocolv1 @numpytest def test_numpy_parser(self): """ @@ -89,7 +88,6 @@ def test_numpy_parser(self): assert not result.has_more_pages self._verify_numpy_page(result[0]) - @notprotocolv1 @numpytest def test_numpy_results_paged(self): """ @@ -251,7 +249,6 @@ def setUpClass(cls): def tearDownClass(cls): drop_keyspace_shutdown_cluster("test_wide_table", cls.session, cls.cluster) - @notprotocolv1 @numpytest def test_numpy_wide_table_paging(self): """ @@ -287,7 +284,6 @@ def test_numpy_wide_table_paging(self): cluster.shutdown() - @notprotocolv1 @numpytest def test_numpy_wide_table_no_fetch_size(self): """ @@ -328,7 +324,6 @@ def setUpClass(cls): cls.common_setup(1, execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=tuple_factory)}) @numpytest - @greaterthancass21 def test_null_types(self): """ Test to validate that the numpy protocol handler can deal with null values. diff --git a/tests/integration/standard/test_metadata.py b/tests/integration/standard/test_metadata.py index c30e369d83..b5f98792f4 100644 --- a/tests/integration/standard/test_metadata.py +++ b/tests/integration/standard/test_metadata.py @@ -36,12 +36,12 @@ from cassandra.protocol import QueryMessage, ProtocolHandler from cassandra.util import SortedSet -from tests.integration import (get_cluster, use_singledc, PROTOCOL_VERSION, execute_until_pass, +from tests.integration import (get_cluster, use_singledc, execute_until_pass, BasicSegregatedKeyspaceUnitTestCase, BasicSharedKeyspaceUnitTestCase, BasicExistingKeyspaceUnitTestCase, drop_keyspace_shutdown_cluster, CASSANDRA_VERSION, - greaterthanorequalcass30, lessthancass30, local, - get_supported_protocol_versions, greaterthancass20, - greaterthancass21, greaterthanorequalcass40, + greaterthanorequalcass30, local, + get_supported_protocol_versions, + greaterthanorequalcass40, lessthancass40, TestCluster, requires_java_udf, requires_composite_type, requires_collection_indexes, SCYLLA_VERSION, xfail_scylla, xfail_scylla_version_lt, @@ -385,28 +385,6 @@ def test_composite_in_compound_primary_key_compact(self): self.check_create_statement(tablemeta, create_statement) - @lessthancass30 - def test_cql_compatibility(self): - - # having more than one non-PK column is okay if there aren't any - # clustering columns - create_statement = self.make_create_statement(["a"], [], ["b", "c", "d"]) - self.session.execute(create_statement) - tablemeta = self.get_table_metadata() - - assert [u'a'] == [c.name for c in tablemeta.partition_key] - assert [] == tablemeta.clustering_key - assert [u'a', u'b', u'c', u'd'] == sorted(tablemeta.columns.keys()) - - assert tablemeta.is_cql_compatible - - # It will be cql compatible after CASSANDRA-10857 - # since compact storage is being dropped - tablemeta.clustering_key = ["foo", "bar"] - tablemeta.columns["foo"] = None - tablemeta.columns["bar"] = None - assert tablemeta.is_cql_compatible - def test_compound_primary_keys_ordering(self): create_statement = self.make_create_statement(["a"], ["b"], ["c"]) create_statement += " WITH CLUSTERING ORDER BY (b DESC)" @@ -508,7 +486,6 @@ def test_indexes(self): assert 'CREATE INDEX d_index' in statement assert 'CREATE INDEX e_index' in statement - @greaterthancass21 @requires_collection_indexes @xfail_scylla('scylladb/scylladb#22013 - scylla does not show full index in system_schema.indexes') def test_collection_indexes(self): @@ -529,16 +506,15 @@ def test_collection_indexes(self): target = ' (b)' if CASSANDRA_VERSION < Version("3.0") else 'values(b))' # explicit values in C* 3+ assert target in tablemeta.export_as_string() - # test full indexes on frozen collections, if available - if CASSANDRA_VERSION >= Version("2.1.3"): - self.session.execute("DROP TABLE %s.%s" % (self.keyspace_name, self.function_table_name)) - self.session.execute("CREATE TABLE %s.%s (a int PRIMARY KEY, b frozen>)" - % (self.keyspace_name, self.function_table_name)) - self.session.execute("CREATE INDEX index3 ON %s.%s (full(b))" - % (self.keyspace_name, self.function_table_name)) + # test full indexes on frozen collections + self.session.execute("DROP TABLE %s.%s" % (self.keyspace_name, self.function_table_name)) + self.session.execute("CREATE TABLE %s.%s (a int PRIMARY KEY, b frozen>)" + % (self.keyspace_name, self.function_table_name)) + self.session.execute("CREATE INDEX index3 ON %s.%s (full(b))" + % (self.keyspace_name, self.function_table_name)) - tablemeta = self.get_table_metadata() - assert '(full(b))' in tablemeta.export_as_string() + tablemeta = self.get_table_metadata() + assert '(full(b))' in tablemeta.export_as_string() def test_compression_disabled(self): create_statement = self.make_create_statement(["a"], ["b"], ["c"]) @@ -623,34 +599,32 @@ def test_refresh_schema_metadata(self): cluster2.refresh_schema_metadata() assert "c" in cluster2.metadata.keyspaces[self.keyspace_name].tables[table_name].columns - if PROTOCOL_VERSION >= 3: - # UDT metadata modification - self.session.execute("CREATE TYPE {0}.user (age int, name text)".format(self.keyspace_name)) - assert cluster2.metadata.keyspaces[self.keyspace_name].user_types == {} - cluster2.refresh_schema_metadata() - assert "user" in cluster2.metadata.keyspaces[self.keyspace_name].user_types + # UDT metadata modification + self.session.execute("CREATE TYPE {0}.user (age int, name text)".format(self.keyspace_name)) + assert cluster2.metadata.keyspaces[self.keyspace_name].user_types == {} + cluster2.refresh_schema_metadata() + assert "user" in cluster2.metadata.keyspaces[self.keyspace_name].user_types - if PROTOCOL_VERSION >= 4: - # UDF metadata modification - self.session.execute("""CREATE FUNCTION {0}.sum_int(key int, val int) - RETURNS NULL ON NULL INPUT - RETURNS int - LANGUAGE java AS 'return key+val;';""".format(self.keyspace_name)) + # UDF metadata modification + self.session.execute("""CREATE FUNCTION {0}.sum_int(key int, val int) + RETURNS NULL ON NULL INPUT + RETURNS int + LANGUAGE java AS 'return key+val;';""".format(self.keyspace_name)) - assert cluster2.metadata.keyspaces[self.keyspace_name].functions == {} - cluster2.refresh_schema_metadata() - assert "sum_int(int,int)" in cluster2.metadata.keyspaces[self.keyspace_name].functions + assert cluster2.metadata.keyspaces[self.keyspace_name].functions == {} + cluster2.refresh_schema_metadata() + assert "sum_int(int,int)" in cluster2.metadata.keyspaces[self.keyspace_name].functions - # UDA metadata modification - self.session.execute("""CREATE AGGREGATE {0}.sum_agg(int) - SFUNC sum_int - STYPE int - INITCOND 0""" - .format(self.keyspace_name)) + # UDA metadata modification + self.session.execute("""CREATE AGGREGATE {0}.sum_agg(int) + SFUNC sum_int + STYPE int + INITCOND 0""" + .format(self.keyspace_name)) - assert cluster2.metadata.keyspaces[self.keyspace_name].aggregates == {} - cluster2.refresh_schema_metadata() - assert "sum_agg(int)" in cluster2.metadata.keyspaces[self.keyspace_name].aggregates + assert cluster2.metadata.keyspaces[self.keyspace_name].aggregates == {} + cluster2.refresh_schema_metadata() + assert "sum_agg(int)" in cluster2.metadata.keyspaces[self.keyspace_name].aggregates # Cluster metadata modification self.session.execute("DROP KEYSPACE new_keyspace") @@ -799,9 +773,6 @@ def test_refresh_user_type_metadata(self): @test_category metadata """ - if PROTOCOL_VERSION < 3: - raise unittest.SkipTest("Protocol 3+ is required for UDTs, currently testing against {0}".format(PROTOCOL_VERSION)) - cluster2 = TestCluster(schema_event_refresh_window=-1) cluster2.connect() @@ -814,41 +785,6 @@ def test_refresh_user_type_metadata(self): cluster2.shutdown() - @greaterthancass20 - def test_refresh_user_type_metadata_proto_2(self): - """ - Test to insure that protocol v1/v2 surface UDT metadata changes - - @since 3.7.0 - @jira_ticket PYTHON-106 - @expected_result UDT metadata in the keyspace should be updated regardless of protocol version - - @test_category metadata - """ - supported_versions = get_supported_protocol_versions() - if 2 not in supported_versions: # 1 and 2 were dropped in the same version - raise unittest.SkipTest("Protocol versions 1 and 2 are not supported in Cassandra version ".format(CASSANDRA_VERSION)) - - for protocol_version in (1, 2): - cluster = TestCluster() - session = cluster.connect() - assert cluster.metadata.keyspaces[self.keyspace_name].user_types == {} - - session.execute("CREATE TYPE {0}.user (age int, name text)".format(self.keyspace_name)) - assert "user" in cluster.metadata.keyspaces[self.keyspace_name].user_types - assert "age" in cluster.metadata.keyspaces[self.keyspace_name].user_types["user"].field_names - assert "name" in cluster.metadata.keyspaces[self.keyspace_name].user_types["user"].field_names - - session.execute("ALTER TYPE {0}.user ADD flag boolean".format(self.keyspace_name)) - assert "flag" in cluster.metadata.keyspaces[self.keyspace_name].user_types["user"].field_names - - session.execute("ALTER TYPE {0}.user RENAME flag TO something".format(self.keyspace_name)) - assert "something" in cluster.metadata.keyspaces[self.keyspace_name].user_types["user"].field_names - - session.execute("DROP TYPE {0}.user".format(self.keyspace_name)) - assert cluster.metadata.keyspaces[self.keyspace_name].user_types == {} - cluster.shutdown() - @requires_java_udf def test_refresh_user_function_metadata(self): """ @@ -868,9 +804,6 @@ def test_refresh_user_function_metadata(self): @test_category metadata """ - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol 4+ is required for UDFs, currently testing against {0}".format(PROTOCOL_VERSION)) - cluster2 = TestCluster(schema_event_refresh_window=-1) cluster2.connect() @@ -905,9 +838,6 @@ def test_refresh_user_aggregate_metadata(self): @test_category metadata """ - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Protocol 4+ is required for UDAs, currently testing against {0}".format(PROTOCOL_VERSION)) - cluster2 = TestCluster(schema_event_refresh_window=-1) cluster2.connect() @@ -1119,17 +1049,11 @@ def test_export_keyspace_schema(self): assert isinstance(keyspace_metadata.as_cql_query(), str) cluster.shutdown() - @greaterthancass20 def test_export_keyspace_schema_udts(self): """ Test udt exports """ - if PROTOCOL_VERSION < 3: - raise unittest.SkipTest( - "Protocol 3.0+ is required for UDT change events, currently testing against %r" - % (PROTOCOL_VERSION,)) - if sys.version_info[0:2] != (2, 7): raise unittest.SkipTest('This test compares static strings generated from dict items, which may change orders. Test with 2.7.') @@ -1195,7 +1119,6 @@ def test_export_keyspace_schema_udts(self): cluster.shutdown() - @greaterthancass21 @xfail_scylla_version_lt(reason='scylladb/scylladb#10707 - Column name in CREATE INDEX is not quoted', oss_scylla_version="5.2", ent_scylla_version="2023.1.1") def test_case_sensitivity(self): @@ -1522,34 +1445,24 @@ class FunctionTest(unittest.TestCase): Base functionality for Function and Aggregate metadata test classes """ - def setUp(self): - """ - Tests are skipped if run with native protocol version < 4 - """ - - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Function metadata requires native protocol version 4+") - @property def function_name(self): return self._testMethodName.lower() @classmethod def setup_class(cls): - if PROTOCOL_VERSION >= 4: - cls.cluster = TestCluster() - cls.keyspace_name = cls.__name__.lower() - cls.session = cls.cluster.connect() - cls.session.execute("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}" % cls.keyspace_name) - cls.session.set_keyspace(cls.keyspace_name) - cls.keyspace_function_meta = cls.cluster.metadata.keyspaces[cls.keyspace_name].functions - cls.keyspace_aggregate_meta = cls.cluster.metadata.keyspaces[cls.keyspace_name].aggregates + cls.cluster = TestCluster() + cls.keyspace_name = cls.__name__.lower() + cls.session = cls.cluster.connect() + cls.session.execute("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}" % cls.keyspace_name) + cls.session.set_keyspace(cls.keyspace_name) + cls.keyspace_function_meta = cls.cluster.metadata.keyspaces[cls.keyspace_name].functions + cls.keyspace_aggregate_meta = cls.cluster.metadata.keyspaces[cls.keyspace_name].aggregates @classmethod def teardown_class(cls): - if PROTOCOL_VERSION >= 4: - cls.session.execute("DROP KEYSPACE IF EXISTS %s" % cls.keyspace_name) - cls.cluster.shutdown() + cls.session.execute("DROP KEYSPACE IF EXISTS %s" % cls.keyspace_name) + cls.cluster.shutdown() class Verified(object): @@ -1749,34 +1662,33 @@ class AggregateMetadata(FunctionTest): @classmethod def setup_class(cls): - if PROTOCOL_VERSION >= 4: - super(AggregateMetadata, cls).setup_class() - - cls.session.execute("""CREATE OR REPLACE FUNCTION sum_int(s int, i int) - RETURNS NULL ON NULL INPUT - RETURNS int - LANGUAGE java AS 'return s + i;';""") - cls.session.execute("""CREATE OR REPLACE FUNCTION sum_int_two(s int, i int, j int) - RETURNS NULL ON NULL INPUT - RETURNS int - LANGUAGE java AS 'return s + i + j;';""") - cls.session.execute("""CREATE OR REPLACE FUNCTION "List_As_String"(l list) - RETURNS NULL ON NULL INPUT - RETURNS int - LANGUAGE java AS 'return l.size();';""") - cls.session.execute("""CREATE OR REPLACE FUNCTION extend_list(s list, i int) - CALLED ON NULL INPUT - RETURNS list - LANGUAGE java AS 'if (i != null) s.add(i.toString()); return s;';""") - cls.session.execute("""CREATE OR REPLACE FUNCTION update_map(s map, i int) - RETURNS NULL ON NULL INPUT - RETURNS map - LANGUAGE java AS 's.put(new Integer(i), new Integer(i)); return s;';""") - cls.session.execute("""CREATE TABLE IF NOT EXISTS t - (k int PRIMARY KEY, v int)""") - for x in range(4): - cls.session.execute("INSERT INTO t (k,v) VALUES (%s, %s)", (x, x)) - cls.session.execute("INSERT INTO t (k) VALUES (%s)", (4,)) + super(AggregateMetadata, cls).setup_class() + + cls.session.execute("""CREATE OR REPLACE FUNCTION sum_int(s int, i int) + RETURNS NULL ON NULL INPUT + RETURNS int + LANGUAGE java AS 'return s + i;';""") + cls.session.execute("""CREATE OR REPLACE FUNCTION sum_int_two(s int, i int, j int) + RETURNS NULL ON NULL INPUT + RETURNS int + LANGUAGE java AS 'return s + i + j;';""") + cls.session.execute("""CREATE OR REPLACE FUNCTION "List_As_String"(l list) + RETURNS NULL ON NULL INPUT + RETURNS int + LANGUAGE java AS 'return l.size();';""") + cls.session.execute("""CREATE OR REPLACE FUNCTION extend_list(s list, i int) + CALLED ON NULL INPUT + RETURNS list + LANGUAGE java AS 'if (i != null) s.add(i.toString()); return s;';""") + cls.session.execute("""CREATE OR REPLACE FUNCTION update_map(s map, i int) + RETURNS NULL ON NULL INPUT + RETURNS map + LANGUAGE java AS 's.put(new Integer(i), new Integer(i)); return s;';""") + cls.session.execute("""CREATE TABLE IF NOT EXISTS t + (k int PRIMARY KEY, v int)""") + for x in range(4): + cls.session.execute("INSERT INTO t (k,v) VALUES (%s, %s)", (x, x)) + cls.session.execute("INSERT INTO t (k) VALUES (%s)", (4,)) def make_aggregate_kwargs(self, state_func, state_type, final_func=None, init_cond=None): return {'keyspace': self.keyspace_name, @@ -1821,7 +1733,7 @@ def test_init_cond(self): """ # This is required until the java driver bundled with C* is updated to support v4 - c = TestCluster(protocol_version=3) + c = TestCluster() s = c.connect(self.keyspace_name) encoder = Encoder() @@ -2048,7 +1960,6 @@ def test_bad_index(self): assert m._exc_info[0] is self.BadMetaException assert "/*\nWarning:" in m.export_as_string() - @greaterthancass20 def test_bad_user_type(self): self.session.execute('CREATE TYPE %s (i int, d double)' % self.function_name) with patch.object(self.parser_class, '_build_user_type', side_effect=self.BadMetaException): @@ -2057,7 +1968,6 @@ def test_bad_user_type(self): assert m._exc_info[0] is self.BadMetaException assert "/*\nWarning:" in m.export_as_string() - @greaterthancass21 @requires_java_udf def test_bad_user_function(self): self.session.execute("""CREATE FUNCTION IF NOT EXISTS %s (key int, val int) @@ -2076,7 +1986,6 @@ def test_bad_user_function(self): assert m._exc_info[0] is self.BadMetaException assert "/*\nWarning:" in m.export_as_string() - @greaterthancass21 @requires_java_udf def test_bad_user_aggregate(self): self.session.execute("""CREATE FUNCTION IF NOT EXISTS sum_int (key int, val int) @@ -2390,59 +2299,6 @@ def test_base_table_column_addition_mv(self): mv_alltime_fouls_comumn = self.cluster.metadata.keyspaces[self.keyspace_name].views["alltimehigh"].columns['fouls'] assert mv_alltime_fouls_comumn.cql_type == 'int' - @lessthancass30 - def test_base_table_type_alter_mv(self): - """ - test to ensure that materialized view metadata is properly updated when a type in the base table - is updated. - - test_create_view_metadata tests that materialized views metadata is properly updated when the type of base table - column is changed. - - Support for alter type was removed in CASSANDRA-12443 - - @since 3.0.0 - @jira_ticket CASSANDRA-10424 - @expected_result Materialized view metadata should be updated correctly - - @test_category metadata - """ - create_table = """CREATE TABLE {0}.scores( - user TEXT, - game TEXT, - year INT, - month INT, - day INT, - score TEXT, - PRIMARY KEY (user, game, year, month, day) - )""".format(self.keyspace_name) - - self.session.execute(create_table) - - create_mv = """CREATE MATERIALIZED VIEW {0}.monthlyhigh AS - SELECT game, year, month, score, user, day FROM {0}.scores - WHERE game IS NOT NULL AND year IS NOT NULL AND month IS NOT NULL AND score IS NOT NULL AND user IS NOT NULL AND day IS NOT NULL - PRIMARY KEY ((game, year, month), score, user, day) - WITH CLUSTERING ORDER BY (score DESC, user ASC, day ASC)""".format(self.keyspace_name) - - self.session.execute(create_mv) - assert len(self.cluster.metadata.keyspaces[self.keyspace_name].views) == 1 - alter_scores = """ALTER TABLE {0}.scores ALTER score TYPE blob""".format((self.keyspace_name)) - self.session.execute(alter_scores) - assert len(self.cluster.metadata.keyspaces[self.keyspace_name].views) == 1 - - score_column = self.cluster.metadata.keyspaces[self.keyspace_name].tables['scores'].columns['score'] - assert score_column.cql_type == 'blob' - - # until CASSANDRA-9920+CASSANDRA-10500 MV updates are only available later with an async event - for i in range(10): - score_mv_column = self.cluster.metadata.keyspaces[self.keyspace_name].views["monthlyhigh"].columns['score'] - if "blob" == score_mv_column.cql_type: - break - time.sleep(.2) - - assert score_mv_column.cql_type == 'blob' - def test_metadata_with_quoted_identifiers(self): """ test to ensure that materialized view metadata is properly constructed when quoted identifiers are used diff --git a/tests/integration/standard/test_prepared_statements.py b/tests/integration/standard/test_prepared_statements.py index 3f63b881ef..c825b1c6bc 100644 --- a/tests/integration/standard/test_prepared_statements.py +++ b/tests/integration/standard/test_prepared_statements.py @@ -199,23 +199,14 @@ def test_imprecise_bind_values_dicts(self): prepared.bind({'k': 1, 'v': 2, 'v2': 3}) # right number, but one does not belong - if PROTOCOL_VERSION < 4: - # pre v4, the driver bails with key error when 'v' is found missing - with pytest.raises(KeyError): - prepared.bind({'k': 1, 'v2': 3}) - else: - # post v4, the driver uses UNSET_VALUE for 'v' and 'v2' is ignored - prepared.bind({'k': 1, 'v2': 3}) + # the driver uses UNSET_VALUE for 'v' and 'v2' is ignored + prepared.bind({'k': 1, 'v2': 3}) # also catch too few variables with dicts assert isinstance(prepared, PreparedStatement) - if PROTOCOL_VERSION < 4: - with pytest.raises(KeyError): - prepared.bind({}) - else: - # post v4, the driver attempts to use UNSET_VALUE for unspecified keys - with pytest.raises(ValueError): - prepared.bind({}) + # the driver attempts to use UNSET_VALUE for unspecified keys + with pytest.raises(ValueError): + prepared.bind({}) def test_none_values(self): """ @@ -255,8 +246,6 @@ def test_unset_values(self): @test_category prepared_statements:binding """ - if PROTOCOL_VERSION < 4: - raise unittest.SkipTest("Binding UNSET values is not supported in protocol version < 4") # table with at least two values so one can be used as a marker self.session.execute("CREATE TABLE IF NOT EXISTS test1rf.test_unset_values (k int PRIMARY KEY, v0 int, v1 int)") diff --git a/tests/integration/standard/test_query.py b/tests/integration/standard/test_query.py index 9cebc22b05..acf32f4a31 100644 --- a/tests/integration/standard/test_query.py +++ b/tests/integration/standard/test_query.py @@ -24,8 +24,8 @@ BatchStatement, BatchType, dict_factory, TraceUnavailable) from cassandra.cluster import NoHostAvailable, ExecutionProfile, EXEC_PROFILE_DEFAULT, Cluster from cassandra.policies import HostDistance, RoundRobinPolicy, WhiteListRoundRobinPolicy -from tests.integration import use_singledc, PROTOCOL_VERSION, BasicSharedKeyspaceUnitTestCase, \ - greaterthanprotocolv3, MockLoggingHandler, get_supported_protocol_versions, local, get_cluster, setup_keyspace, \ +from tests.integration import use_singledc, BasicSharedKeyspaceUnitTestCase, \ + MockLoggingHandler, get_supported_protocol_versions, local, get_cluster, setup_keyspace, \ USE_CASS_EXTERNAL, greaterthanorequalcass40, TestCluster, xfail_scylla from tests import notwindows from tests.integration import greaterthanorequalcass30, get_node @@ -136,7 +136,6 @@ def test_trace_ignores_row_factory(self): str(event) @local - @greaterthanprotocolv3 def test_client_ip_in_trace(self): """ Test to validate that client trace contains client ip information. @@ -492,10 +491,7 @@ def test_prepared_metadata_generation(self): session = cluster.connect() select_statement = session.prepare("SELECT * FROM system.local WHERE key='local'") - if proto_version == 1: - assert select_statement.result_metadata == None - else: - assert select_statement.result_metadata != None + assert select_statement.result_metadata != None future = session.execute_async(select_statement) results = future.result() if base_line is None: @@ -659,11 +655,6 @@ def test_prepared_statement(self): class BatchStatementTests(BasicSharedKeyspaceUnitTestCase): def setUp(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2.0+ is required for BATCH operations, currently testing against %r" - % (PROTOCOL_VERSION,)) - self.cluster = TestCluster() self.session = self.cluster.connect(wait_for_all_pools=True) @@ -793,11 +784,6 @@ def test_too_many_statements(self): class SerialConsistencyTests(unittest.TestCase): def setUp(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2.0+ is required for Serial Consistency, currently testing against %r" - % (PROTOCOL_VERSION,)) - self.cluster = TestCluster() self.session = self.cluster.connect() @@ -880,15 +866,6 @@ def test_bad_consistency_level(self): class LightweightTransactionTests(unittest.TestCase): def setUp(self): - """ - Test is skipped if run with cql version < 2 - - """ - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2.0+ is required for Lightweight transactions, currently testing against %r" - % (PROTOCOL_VERSION,)) - serial_profile = ExecutionProfile(consistency_level=ConsistencyLevel.SERIAL) self.cluster = TestCluster(execution_profiles={'serial': serial_profile}) self.session = self.cluster.connect() @@ -1072,10 +1049,6 @@ class BatchStatementDefaultRoutingKeyTests(unittest.TestCase): # Test for PYTHON-126: BatchStatement.add() should set the routing key of the first added prepared statement def setUp(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2.0+ is required for BATCH operations, currently testing against %r" - % (PROTOCOL_VERSION,)) self.cluster = TestCluster() self.session = self.cluster.connect() query = """ diff --git a/tests/integration/standard/test_query_paging.py b/tests/integration/standard/test_query_paging.py index e0c67cd309..6694c0c284 100644 --- a/tests/integration/standard/test_query_paging.py +++ b/tests/integration/standard/test_query_paging.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from tests.integration import use_singledc, PROTOCOL_VERSION, TestCluster +from tests.integration import use_singledc, TestCluster import logging log = logging.getLogger(__name__) @@ -38,11 +38,6 @@ def setup_module(): class QueryPagingTests(unittest.TestCase): def setUp(self): - if PROTOCOL_VERSION < 2: - raise unittest.SkipTest( - "Protocol 2.0+ is required for Paging state, currently testing against %r" - % (PROTOCOL_VERSION,)) - self.cluster = TestCluster( execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(consistency_level=ConsistencyLevel.LOCAL_QUORUM)} ) diff --git a/tests/integration/standard/test_row_factories.py b/tests/integration/standard/test_row_factories.py index 187f35704a..198b518d2c 100644 --- a/tests/integration/standard/test_row_factories.py +++ b/tests/integration/standard/test_row_factories.py @@ -201,9 +201,6 @@ def test_can_select_using_alias(self): """ can SELECT "" AS aliases """ - if self._cass_version < (2, 0, 0): - raise unittest.SkipTest("Alias in SELECT not supported before 2.0") - try: self.session.execute('SELECT key, "626972746864617465" AS my_col from test1rf.table_num_col') except ValueError as e: diff --git a/tests/integration/standard/test_single_interface.py b/tests/integration/standard/test_single_interface.py index 5fd9ef45d3..22776f4232 100644 --- a/tests/integration/standard/test_single_interface.py +++ b/tests/integration/standard/test_single_interface.py @@ -19,7 +19,7 @@ from cassandra.query import SimpleStatement from packaging.version import Version -from tests.integration import use_singledc, PROTOCOL_VERSION, \ +from tests.integration import use_singledc, \ remove_cluster, greaterthanorequalcass40, \ CASSANDRA_VERSION, TestCluster, DEFAULT_SINGLE_INTERFACE_PORT diff --git a/tests/integration/standard/test_types.py b/tests/integration/standard/test_types.py index ad69fbada9..bdcced3870 100644 --- a/tests/integration/standard/test_types.py +++ b/tests/integration/standard/test_types.py @@ -38,8 +38,8 @@ from tests.unit.cython.utils import cythontest from tests.util import assertEqual -from tests.integration import use_singledc, execute_until_pass, notprotocolv1, \ - BasicSharedKeyspaceUnitTestCase, greaterthancass21, lessthancass30, \ +from tests.integration import use_singledc, execute_until_pass, \ + BasicSharedKeyspaceUnitTestCase, \ greaterthanorequalcass3_10, TestCluster, requires_composite_type, greaterthanorequalcass50 from tests.integration.datatype_utils import update_datatypes, PRIMITIVE_DATATYPES, COLLECTION_TYPES, PRIMITIVE_DATATYPES_KEYS, \ get_sample, get_all_samples, get_collection_sample @@ -430,9 +430,6 @@ def test_can_insert_tuples(self): Basic test of tuple functionality """ - if self.cass_version < (2, 1, 0): - raise unittest.SkipTest("The tuple type was introduced in Cassandra 2.1") - c = TestCluster() s = c.connect(self.keyspace_name) @@ -483,9 +480,6 @@ def test_can_insert_tuples_with_varying_lengths(self): as expected. """ - if self.cass_version < (2, 1, 0): - raise unittest.SkipTest("The tuple type was introduced in Cassandra 2.1") - c = TestCluster( execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=dict_factory)} ) @@ -523,9 +517,6 @@ def test_can_insert_tuples_all_primitive_datatypes(self): Ensure tuple subtypes are appropriately handled. """ - if self.cass_version < (2, 1, 0): - raise unittest.SkipTest("The tuple type was introduced in Cassandra 2.1") - c = TestCluster() s = c.connect(self.keyspace_name) s.encoder.mapping[tuple] = s.encoder.cql_encode_tuple @@ -551,9 +542,6 @@ def test_can_insert_tuples_all_collection_datatypes(self): Ensure tuple subtypes are appropriately handled for maps, sets, and lists. """ - if self.cass_version < (2, 1, 0): - raise unittest.SkipTest("The tuple type was introduced in Cassandra 2.1") - c = TestCluster( execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=dict_factory)} ) @@ -650,9 +638,6 @@ def test_can_insert_nested_tuples(self): Ensure nested are appropriately handled. """ - if self.cass_version < (2, 1, 0): - raise unittest.SkipTest("The tuple type was introduced in Cassandra 2.1") - c = TestCluster( execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=dict_factory)} ) @@ -690,9 +675,6 @@ def test_can_insert_tuples_with_nulls(self): Test tuples with null and empty string fields. """ - if self.cass_version < (2, 1, 0): - raise unittest.SkipTest("The tuple type was introduced in Cassandra 2.1") - s = self.session s.execute("CREATE TABLE tuples_nulls (k int PRIMARY KEY, t frozen>)") @@ -792,7 +774,6 @@ def test_can_read_composite_type(self): assert 0 == result.a assert ('abc',) == result.b - @notprotocolv1 def test_special_float_cql_encoding(self): """ Test to insure that Infinity -Infinity and NaN are supported by the python driver. @@ -905,85 +886,6 @@ def test_smoke_duration_values(self): self.session.execute(prepared, (1, Duration(int("8FFFFFFFFFFFFFF0", 16), 0, 0))) -class TypeTestsProtocol(BasicSharedKeyspaceUnitTestCase): - - @greaterthancass21 - @lessthancass30 - def test_nested_types_with_protocol_version(self): - """ - Test to validate that nested type serialization works on various protocol versions. Provided - the version of cassandra is greater the 2.1.3 we would expect to nested to types to work at all protocol versions. - - @since 3.0.0 - @jira_ticket PYTHON-215 - @expected_result no exceptions are thrown - - @test_category data_types serialization - """ - ddl = '''CREATE TABLE {0}.t ( - k int PRIMARY KEY, - v list>>)'''.format(self.keyspace_name) - - self.session.execute(ddl) - ddl = '''CREATE TABLE {0}.u ( - k int PRIMARY KEY, - v set>>)'''.format(self.keyspace_name) - self.session.execute(ddl) - ddl = '''CREATE TABLE {0}.v ( - k int PRIMARY KEY, - v map>, frozen>>, - v1 frozen>)'''.format(self.keyspace_name) - self.session.execute(ddl) - - self.session.execute("CREATE TYPE {0}.typ (v0 frozen>>>, v1 frozen>)".format(self.keyspace_name)) - - ddl = '''CREATE TABLE {0}.w ( - k int PRIMARY KEY, - v frozen)'''.format(self.keyspace_name) - - self.session.execute(ddl) - - for pvi in range(3, 5): - self.run_inserts_at_version(pvi) - for pvr in range(3, 5): - self.read_inserts_at_level(pvr) - - def read_inserts_at_level(self, proto_ver): - session = TestCluster(protocol_version=proto_ver).connect(self.keyspace_name) - try: - results = session.execute('select * from t').one() - assert "[SortedSet([1, 2]), SortedSet([3, 5])]" == str(results.v) - - results = session.execute('select * from u').one() - assert "SortedSet([[1, 2], [3, 5]])" == str(results.v) - - results = session.execute('select * from v').one() - assert "{SortedSet([1, 2]): [1, 2, 3], SortedSet([3, 5]): [4, 5, 6]}" == str(results.v) - - results = session.execute('select * from w').one() - assert "typ(v0=OrderedMapSerializedKey([(1, [1, 2, 3]), (2, [4, 5, 6])]), v1=[7, 8, 9])" == str(results.v) - - finally: - session.cluster.shutdown() - - def run_inserts_at_version(self, proto_ver): - session = TestCluster(protocol_version=proto_ver).connect(self.keyspace_name) - try: - p = session.prepare('insert into t (k, v) values (?, ?)') - session.execute(p, (0, [{1, 2}, {3, 5}])) - - p = session.prepare('insert into u (k, v) values (?, ?)') - session.execute(p, (0, {(1, 2), (3, 5)})) - - p = session.prepare('insert into v (k, v, v1) values (?, ?, ?)') - session.execute(p, (0, {(1, 2): [1, 2, 3], (3, 5): [4, 5, 6]}, (123, 'four'))) - - p = session.prepare('insert into w (k, v) values (?, ?)') - session.execute(p, (0, ({1: [1, 2, 3], 2: [4, 5, 6]}, [7, 8, 9]))) - - finally: - session.cluster.shutdown() - @greaterthanorequalcass50 class TypeTestsVector(BasicSharedKeyspaceUnitTestCase): diff --git a/tests/integration/standard/test_udts.py b/tests/integration/standard/test_udts.py index dd696ea0e9..769f6bcdc4 100644 --- a/tests/integration/standard/test_udts.py +++ b/tests/integration/standard/test_udts.py @@ -22,7 +22,7 @@ from cassandra.util import OrderedMap from tests.integration import use_singledc, execute_until_pass, \ - BasicSegregatedKeyspaceUnitTestCase, greaterthancass20, lessthancass30, greaterthanorequalcass36, TestCluster + BasicSegregatedKeyspaceUnitTestCase, greaterthanorequalcass36, TestCluster from tests.integration.datatype_utils import update_datatypes, PRIMITIVE_DATATYPES, PRIMITIVE_DATATYPES_KEYS, \ COLLECTION_TYPES, get_sample, get_collection_sample import pytest @@ -36,7 +36,6 @@ def setup_module(): update_datatypes() -@greaterthancass20 class UDTTests(BasicSegregatedKeyspaceUnitTestCase): @property @@ -608,9 +607,6 @@ def test_can_insert_nested_collections(self): Test for inserting various types of nested COLLECTION_TYPES into tables and UDTs """ - if self.cass_version < (2, 1, 3): - raise unittest.SkipTest("Support for nested collections was introduced in Cassandra 2.1.3") - c = TestCluster() s = c.connect(self.keyspace_name, wait_for_all_pools=True) s.encoder.mapping[tuple] = s.encoder.cql_encode_tuple @@ -679,72 +675,3 @@ def test_non_alphanum_identifiers(self): assert k.__class__ != tuple # should be the namedtuple type assert k[0] == 'alphanum' assert k.field_0_ == 'alphanum' # named tuple with positional field name - - @lessthancass30 - def test_type_alteration(self): - """ - Support for ALTER TYPE was removed in CASSANDRA-12443 - """ - s = self.session - type_name = "type_name" - assert type_name not in s.cluster.metadata.keyspaces['udttests'].user_types - s.execute('CREATE TYPE %s (v0 int)' % (type_name,)) - assert type_name in s.cluster.metadata.keyspaces['udttests'].user_types - - s.execute('CREATE TABLE %s (k int PRIMARY KEY, v frozen<%s>)' % (self.table_name, type_name)) - s.execute('INSERT INTO %s (k, v) VALUES (0, {v0 : 1})' % (self.table_name,)) - - s.cluster.register_user_type('udttests', type_name, dict) - - val = s.execute('SELECT v FROM %s' % self.table_name).one()[0] - assert val['v0'] == 1 - - # add field - s.execute('ALTER TYPE %s ADD v1 text' % (type_name,)) - val = s.execute('SELECT v FROM %s' % self.table_name).one()[0] - assert val['v0'] == 1 - assert val['v1'] is None - s.execute("INSERT INTO %s (k, v) VALUES (0, {v0 : 2, v1 : 'sometext'})" % (self.table_name,)) - val = s.execute('SELECT v FROM %s' % self.table_name).one()[0] - assert val['v0'] == 2 - assert val['v1'] == 'sometext' - - # alter field type - s.execute('ALTER TYPE %s ALTER v1 TYPE blob' % (type_name,)) - s.execute("INSERT INTO %s (k, v) VALUES (0, {v0 : 3, v1 : 0xdeadbeef})" % (self.table_name,)) - val = s.execute('SELECT v FROM %s' % self.table_name).one()[0] - assert val['v0'] == 3 - assert val['v1'] == b'\xde\xad\xbe\xef' - - @lessthancass30 - def test_alter_udt(self): - """ - Test to ensure that altered UDT's are properly surfaced without needing to restart the underlying session. - - @since 3.0.0 - @jira_ticket PYTHON-226 - @expected_result UDT's will reflect added columns without a session restart. - - @test_category data_types, udt - """ - - # Create udt ensure it has the proper column names. - self.session.set_keyspace(self.keyspace_name) - self.session.execute("CREATE TYPE typetoalter (a int)") - typetoalter = namedtuple('typetoalter', ('a')) - self.session.execute("CREATE TABLE {0} (pk int primary key, typetoalter frozen)".format(self.function_table_name)) - insert_statement = self.session.prepare("INSERT INTO {0} (pk, typetoalter) VALUES (?, ?)".format(self.function_table_name)) - self.session.execute(insert_statement, [1, typetoalter(1)]) - results = self.session.execute("SELECT * from {0}".format(self.function_table_name)) - for result in results: - assert hasattr(result.typetoalter, 'a') - assert not hasattr(result.typetoalter, 'b') - - # Alter UDT and ensure the alter is honored in results - self.session.execute("ALTER TYPE typetoalter add b int") - typetoalter = namedtuple('typetoalter', ('a', 'b')) - self.session.execute(insert_statement, [2, typetoalter(2, 2)]) - results = self.session.execute("SELECT * from {0}".format(self.function_table_name)) - for result in results: - assert hasattr(result.typetoalter, 'a') - assert hasattr(result.typetoalter, 'b') diff --git a/tests/integration/util.py b/tests/integration/util.py index 7cbdfdb22d..5f091d9508 100644 --- a/tests/integration/util.py +++ b/tests/integration/util.py @@ -14,7 +14,6 @@ from itertools import chain -from tests.integration import PROTOCOL_VERSION import time @@ -53,5 +52,3 @@ def assert_quiescent_pool_state(cluster, wait=None): assert len(req_ids) == len(set(req_ids)) assert connection.highest_request_id == len(req_ids) + len(orphan_ids) - 1 assert connection.highest_request_id == max(chain(req_ids, orphan_ids)) - if PROTOCOL_VERSION < 3: - assert connection.highest_request_id == connection.max_request_id diff --git a/tests/unit/advanced/test_geometry.py b/tests/unit/advanced/test_geometry.py index 1927b51da7..c102ac9119 100644 --- a/tests/unit/advanced/test_geometry.py +++ b/tests/unit/advanced/test_geometry.py @@ -17,7 +17,6 @@ import struct import math from cassandra.cqltypes import lookup_casstype -from cassandra.protocol import ProtocolVersion from cassandra.cqltypes import PointType, LineStringType, PolygonType, WKBGeometryType from cassandra.util import Point, LineString, Polygon, _LinearRing, Distance, _HAS_GEOMET import pytest @@ -25,23 +24,19 @@ wkb_be = 0 wkb_le = 1 -protocol_versions = ProtocolVersion.SUPPORTED_VERSIONS - class GeoTypes(unittest.TestCase): samples = (Point(1, 2), LineString(((1, 2), (3, 4), (5, 6))), Polygon([(10.1, 10.0), (110.0, 10.0), (110., 110.0), (10., 110.0), (10., 10.0)], [[(20., 20.0), (20., 30.0), (30., 30.0), (30., 20.0), (20., 20.0)], [(40., 20.0), (40., 30.0), (50., 30.0), (50., 20.0), (40., 20.0)]])) def test_marshal_platform(self): - for proto_ver in protocol_versions: - for geo in self.samples: - cql_type = lookup_casstype(geo.__class__.__name__ + 'Type') - assert cql_type.from_binary(cql_type.to_binary(geo, proto_ver), proto_ver) == geo + for geo in self.samples: + cql_type = lookup_casstype(geo.__class__.__name__ + 'Type') + assert cql_type.from_binary(cql_type.to_binary(geo)) == geo def _verify_both_endian(self, typ, body_fmt, params, expected): - for proto_ver in protocol_versions: - assert typ.from_binary(struct.pack(">BI" + body_fmt, wkb_be, *params), proto_ver) == expected - assert typ.from_binary(struct.pack("BI" + body_fmt, wkb_be, *params)) == expected + assert typ.from_binary(struct.pack(" 0 diff --git a/tests/unit/io/utils.py b/tests/unit/io/utils.py index f43224058c..817a0791d6 100644 --- a/tests/unit/io/utils.py +++ b/tests/unit/io/utils.py @@ -200,7 +200,7 @@ def get_socket(self, connection): def set_socket(self, connection, obj): return setattr(connection, self.socket_attr_name, obj) - def make_header_prefix(self, message_class, version=3, stream_id=0): + def make_header_prefix(self, message_class, version=4, stream_id=0): return bytes().join(map(uint8_pack, [ 0xff & (HEADER_DIRECTION_TO_CLIENT | version), 0, # flags (compression) diff --git a/tests/unit/test_cluster.py b/tests/unit/test_cluster.py index 49208ac53e..d0d6073963 100644 --- a/tests/unit/test_cluster.py +++ b/tests/unit/test_cluster.py @@ -257,8 +257,6 @@ def test_protocol_downgrade_test(self): lower = ProtocolVersion.get_lower_supported(ProtocolVersion.V5) assert ProtocolVersion.V4 == lower lower = ProtocolVersion.get_lower_supported(ProtocolVersion.V4) - assert ProtocolVersion.V3 == lower - lower = ProtocolVersion.get_lower_supported(ProtocolVersion.V3) assert 0 == lower assert not ProtocolVersion.uses_error_code_map(ProtocolVersion.V4) diff --git a/tests/unit/test_marshalling.py b/tests/unit/test_marshalling.py index e4b415ac69..5ff6157367 100644 --- a/tests/unit/test_marshalling.py +++ b/tests/unit/test_marshalling.py @@ -13,8 +13,6 @@ # limitations under the License. import sys -from cassandra import ProtocolVersion - import unittest import platform @@ -75,7 +73,7 @@ (b'', 'MapType(AsciiType, BooleanType)', None), (b'', 'ListType(FloatType)', None), (b'', 'SetType(LongType)', None), - (b'\x00\x00\x00\x00', 'MapType(DecimalType, BooleanType)', OrderedMapSerializedKey(DecimalType, 3)), + (b'\x00\x00\x00\x00', 'MapType(DecimalType, BooleanType)', OrderedMapSerializedKey(DecimalType)), (b'\x00\x00\x00\x00', 'ListType(FloatType)', []), (b'\x00\x00\x00\x00', 'SetType(IntegerType)', sortedset()), (b'\x00\x00\x00\x01\x00\x00\x00\x10\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0', 'ListType(TimeUUIDType)', [UUID(bytes=b'\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0')]), @@ -88,7 +86,7 @@ (b'\x80\x00', 'ShortType', -32768) ) -ordered_map_value = OrderedMapSerializedKey(UTF8Type, 3) +ordered_map_value = OrderedMapSerializedKey(UTF8Type) ordered_map_value._insert(u'\u307fbob', 199) ordered_map_value._insert(u'', -1) ordered_map_value._insert(u'\\', 0) @@ -111,27 +109,26 @@ class UnmarshalTest(unittest.TestCase): def test_unmarshalling(self): for serializedval, valtype, nativeval in marshalled_value_pairs: unmarshaller = lookup_casstype(valtype) - whatwegot = unmarshaller.from_binary(serializedval, 3) + whatwegot = unmarshaller.from_binary(serializedval) assert whatwegot == nativeval, 'Unmarshaller for %s (%s) failed: unmarshal(%r) got %r instead of %r' % (valtype, unmarshaller, serializedval, whatwegot, nativeval) assert type(whatwegot) == type(nativeval), 'Unmarshaller for %s (%s) gave wrong type (%s instead of %s)' % (valtype, unmarshaller, type(whatwegot), type(nativeval)) def test_marshalling(self): for serializedval, valtype, nativeval in marshalled_value_pairs: marshaller = lookup_casstype(valtype) - whatwegot = marshaller.to_binary(nativeval, 3) + whatwegot = marshaller.to_binary(nativeval) assert whatwegot == serializedval, 'Marshaller for %s (%s) failed: marshal(%r) got %r instead of %r' % (valtype, marshaller, nativeval, whatwegot, serializedval) assert type(whatwegot) == type(serializedval), 'Marshaller for %s (%s) gave wrong type (%s instead of %s)' % (valtype, marshaller, type(whatwegot), type(serializedval)) def test_date(self): # separate test because it will deserialize as datetime - assert DateType.from_binary(DateType.to_binary(date(2015, 11, 2), 3), 3) == datetime(2015, 11, 2) + assert DateType.from_binary(DateType.to_binary(date(2015, 11, 2))) == datetime(2015, 11, 2) def test_decimal(self): # testing implicit numeric conversion # int, tuple(sign, digits, exp), float converted_types = (10001, (0, (1, 0, 0, 0, 0, 1), -3), 100.1, -87.629798) - for proto_ver in range(3, ProtocolVersion.MAX_SUPPORTED + 1): - for n in converted_types: - expected = Decimal(n) - assert DecimalType.from_binary(DecimalType.to_binary(n, proto_ver), proto_ver) == expected + for n in converted_types: + expected = Decimal(n) + assert DecimalType.from_binary(DecimalType.to_binary(n)) == expected diff --git a/tests/unit/test_orderedmap.py b/tests/unit/test_orderedmap.py index 156bbd5f30..3afa17af3b 100644 --- a/tests/unit/test_orderedmap.py +++ b/tests/unit/test_orderedmap.py @@ -167,17 +167,16 @@ def test_delitem(self): class OrderedMapSerializedKeyTest(unittest.TestCase): def test_init(self): - om = OrderedMapSerializedKey(UTF8Type, 3) + om = OrderedMapSerializedKey(UTF8Type) assert om == {} def test_normalized_lookup(self): key_type = lookup_casstype('MapType(UTF8Type, Int32Type)') - protocol_version = 3 - om = OrderedMapSerializedKey(key_type, protocol_version) + om = OrderedMapSerializedKey(key_type) key_ascii = {'one': 1} key_unicode = {u'two': 2} - om._insert_unchecked(key_ascii, key_type.serialize(key_ascii, protocol_version), object()) - om._insert_unchecked(key_unicode, key_type.serialize(key_unicode, protocol_version), object()) + om._insert_unchecked(key_ascii, key_type.serialize(key_ascii), object()) + om._insert_unchecked(key_unicode, key_type.serialize(key_unicode), object()) # type lookup is normalized by key_type # PYTHON-231 diff --git a/tests/unit/test_parameter_binding.py b/tests/unit/test_parameter_binding.py index 5416ac461d..dd26f22ddb 100644 --- a/tests/unit/test_parameter_binding.py +++ b/tests/unit/test_parameter_binding.py @@ -73,8 +73,6 @@ def test_float_precision(self): class BoundStatementTestV3(unittest.TestCase): - protocol_version = 3 - @classmethod def setUpClass(cls): column_metadata = [ColumnMetadata('keyspace', 'cf', 'rk0', Int32Type), @@ -86,7 +84,7 @@ def setUpClass(cls): routing_key_indexes=[1, 0], query=None, keyspace='keyspace', - protocol_version=cls.protocol_version, result_metadata=None, + result_metadata=None, result_metadata_id=None) cls.bound = BoundStatement(prepared_statement=cls.prepared) @@ -122,7 +120,6 @@ def test_inherit_fetch_size(self): routing_key_indexes=[], query=None, keyspace=keyspace, - protocol_version=self.protocol_version, result_metadata=None, result_metadata_id=None) prepared_statement.fetch_size = 1234 @@ -137,14 +134,21 @@ def test_too_few_parameters_for_routing_key(self): assert bound.keyspace == 'keyspace' def test_dict_missing_routing_key(self): - with pytest.raises(KeyError): + # UNSET_VALUE is ValueError for routing keys + with pytest.raises(ValueError): self.bound.bind({'rk0': 0, 'ck0': 0, 'v0': 0}) - with pytest.raises(KeyError): + with pytest.raises(ValueError): self.bound.bind({'rk1': 0, 'ck0': 0, 'v0': 0}) def test_missing_value(self): - with pytest.raises(KeyError): - self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0}) + # missing values are UNSET_VALUE + self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0}) + assert self.bound.values[-1] == UNSET_VALUE + + old_values = self.bound.values + self.bound.bind((0, 0, 0)) + assert self.bound.values is not old_values + assert self.bound.values[-1] == UNSET_VALUE def test_extra_value(self): self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0, 'v0': 0, 'should_not_be_here': 123}) # okay to have extra keys in dict @@ -163,7 +167,6 @@ def test_values_none(self): routing_key_indexes=[], query=None, keyspace='whatever', - protocol_version=self.protocol_version, result_metadata=None, result_metadata_id=None) bound = prepared_statement.bind(None) @@ -178,34 +181,6 @@ def test_bind_none(self): assert self.bound.values is not old_values assert self.bound.values[-1] == None - def test_unset_value(self): - with pytest.raises(ValueError): - self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0, 'v0': UNSET_VALUE}) - with pytest.raises(ValueError): - self.bound.bind((0, 0, 0, UNSET_VALUE)) - - -class BoundStatementTestV4(BoundStatementTestV3): - protocol_version = 4 - - def test_dict_missing_routing_key(self): - # in v4 it implicitly binds UNSET_VALUE for missing items, - # UNSET_VALUE is ValueError for routing keys - with pytest.raises(ValueError): - self.bound.bind({'rk0': 0, 'ck0': 0, 'v0': 0}) - with pytest.raises(ValueError): - self.bound.bind({'rk1': 0, 'ck0': 0, 'v0': 0}) - - def test_missing_value(self): - # in v4 missing values are UNSET_VALUE - self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0}) - assert self.bound.values[-1] == UNSET_VALUE - - old_values = self.bound.values - self.bound.bind((0, 0, 0)) - assert self.bound.values is not old_values - assert self.bound.values[-1] == UNSET_VALUE - def test_unset_value(self): self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0, 'v0': UNSET_VALUE}) assert self.bound.values[-1] == UNSET_VALUE @@ -214,5 +189,9 @@ def test_unset_value(self): assert self.bound.values[-1] == UNSET_VALUE +class BoundStatementTestV4(BoundStatementTestV3): + pass + + class BoundStatementTestV5(BoundStatementTestV4): - protocol_version = 5 + pass diff --git a/tests/unit/test_query.py b/tests/unit/test_query.py index 6b0ebe690e..44c7d14cf1 100644 --- a/tests/unit/test_query.py +++ b/tests/unit/test_query.py @@ -76,7 +76,6 @@ def _make_prepared_statement(self, is_lwt=False): routing_key_indexes=[], query="INSERT INTO test.table (id) VALUES (1)", keyspace=None, - protocol_version=4, result_metadata=[], result_metadata_id=None, is_lwt=is_lwt, diff --git a/tests/unit/test_types.py b/tests/unit/test_types.py index a5bd028b26..f5a67301d1 100644 --- a/tests/unit/test_types.py +++ b/tests/unit/test_types.py @@ -218,28 +218,28 @@ def test_datetype(self): now_timestamp = now_time_seconds * 1e3 # same results serialized - assert DateType.serialize(now_datetime, 0) == DateType.serialize(now_timestamp, 0) + assert DateType.serialize(now_datetime) == DateType.serialize(now_timestamp) # deserialize # epoc expected = 0 - assert DateType.deserialize(int64_pack(1000 * expected), 0) == datetime.datetime.fromtimestamp(expected, tz=datetime.timezone.utc).replace(tzinfo=None) + assert DateType.deserialize(int64_pack(1000 * expected)) == datetime.datetime.fromtimestamp(expected, tz=datetime.timezone.utc).replace(tzinfo=None) # beyond 32b expected = 2 ** 33 - assert DateType.deserialize(int64_pack(1000 * expected), 0) == datetime.datetime(2242, 3, 16, 12, 56, 32, tzinfo=datetime.timezone.utc).replace(tzinfo=None) + assert DateType.deserialize(int64_pack(1000 * expected)) == datetime.datetime(2242, 3, 16, 12, 56, 32, tzinfo=datetime.timezone.utc).replace(tzinfo=None) # less than epoc (PYTHON-119) expected = -770172256 - assert DateType.deserialize(int64_pack(1000 * expected), 0) == datetime.datetime(1945, 8, 5, 23, 15, 44, tzinfo=datetime.timezone.utc).replace(tzinfo=None) + assert DateType.deserialize(int64_pack(1000 * expected)) == datetime.datetime(1945, 8, 5, 23, 15, 44, tzinfo=datetime.timezone.utc).replace(tzinfo=None) # work around rounding difference among Python versions (PYTHON-230) expected = 1424817268.274 - assert DateType.deserialize(int64_pack(int(1000 * expected)), 0) == datetime.datetime(2015, 2, 24, 22, 34, 28, 274000, tzinfo=datetime.timezone.utc).replace(tzinfo=None) + assert DateType.deserialize(int64_pack(int(1000 * expected))) == datetime.datetime(2015, 2, 24, 22, 34, 28, 274000, tzinfo=datetime.timezone.utc).replace(tzinfo=None) # Large date overflow (PYTHON-452) expected = 2177403010.123 - assert DateType.deserialize(int64_pack(int(1000 * expected)), 0) == datetime.datetime(2038, 12, 31, 10, 10, 10, 123000, tzinfo=datetime.timezone.utc).replace(tzinfo=None) + assert DateType.deserialize(int64_pack(int(1000 * expected))) == datetime.datetime(2038, 12, 31, 10, 10, 10, 123000, tzinfo=datetime.timezone.utc).replace(tzinfo=None) def test_collection_null_support(self): """ @@ -254,10 +254,10 @@ def test_collection_null_support(self): int32_pack(4) + # size of item2 int32_pack(42) # item2 ) - assert [None, 42] == int_list.deserialize(value, 3) + assert [None, 42] == int_list.deserialize(value) set_list = SetType.apply_parameters([Int32Type]) - assert {None, 42} == set(set_list.deserialize(value, 3)) + assert {None, 42} == set(set_list.deserialize(value)) value = ( int32_pack(2) + # num items @@ -271,7 +271,7 @@ def test_collection_null_support(self): map_list = MapType.apply_parameters([Int32Type, Int32Type]) - assert [(42, None), (None, 42)] == map_list.deserialize(value, 3)._items # OrderedMapSerializedKey + assert [(42, None), (None, 42)] == map_list.deserialize(value)._items # OrderedMapSerializedKey def test_write_read_string(self): with tempfile.TemporaryFile() as f: @@ -340,11 +340,11 @@ def _round_trip_compare_fn(self, first, second): def _round_trip_test(self, data, ctype_str): ctype = parse_casstype_args(ctype_str) - data_bytes = ctype.serialize(data, 0) + data_bytes = ctype.serialize(data) serialized_size = ctype.subtype.serial_size() if serialized_size: assert serialized_size * len(data) == len(data_bytes) - result = ctype.deserialize(data_bytes, 0) + result = ctype.deserialize(data_bytes) assert len(data) == len(result) for idx in range(0,len(data)): self._round_trip_compare_fn(data[idx], result[idx]) @@ -464,50 +464,50 @@ def test_cql_parameterized_type(self): def test_serialization_fixed_size_too_small(self): ctype = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType, 5)") with pytest.raises(ValueError, match="Expected sequence of size 5 for vector of type float and dimension 5, observed sequence of length 4"): - ctype.serialize([1.2, 3.4, 5.6, 7.8], 0) + ctype.serialize([1.2, 3.4, 5.6, 7.8]) def test_serialization_fixed_size_too_big(self): ctype = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType, 4)") with pytest.raises(ValueError, match="Expected sequence of size 4 for vector of type float and dimension 4, observed sequence of length 5"): - ctype.serialize([1.2, 3.4, 5.6, 7.8, 9.10], 0) + ctype.serialize([1.2, 3.4, 5.6, 7.8, 9.10]) def test_serialization_variable_size_too_small(self): ctype = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.IntegerType, 5)") with pytest.raises(ValueError, match="Expected sequence of size 5 for vector of type varint and dimension 5, observed sequence of length 4"): - ctype.serialize([1, 2, 3, 4], 0) + ctype.serialize([1, 2, 3, 4]) def test_serialization_variable_size_too_big(self): ctype = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.IntegerType, 4)") with pytest.raises(ValueError, match="Expected sequence of size 4 for vector of type varint and dimension 4, observed sequence of length 5"): - ctype.serialize([1, 2, 3, 4, 5], 0) + ctype.serialize([1, 2, 3, 4, 5]) def test_deserialization_fixed_size_too_small(self): ctype_four = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType, 4)") - ctype_four_bytes = ctype_four.serialize([1.2, 3.4, 5.6, 7.8], 0) + ctype_four_bytes = ctype_four.serialize([1.2, 3.4, 5.6, 7.8]) ctype_five = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType, 5)") with pytest.raises(ValueError, match="Expected vector of type float and dimension 5 to have serialized size 20; observed serialized size of 16 instead"): - ctype_five.deserialize(ctype_four_bytes, 0) + ctype_five.deserialize(ctype_four_bytes) def test_deserialization_fixed_size_too_big(self): ctype_five = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType, 5)") - ctype_five_bytes = ctype_five.serialize([1.2, 3.4, 5.6, 7.8, 9.10], 0) + ctype_five_bytes = ctype_five.serialize([1.2, 3.4, 5.6, 7.8, 9.10]) ctype_four = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType, 4)") with pytest.raises(ValueError, match="Expected vector of type float and dimension 4 to have serialized size 16; observed serialized size of 20 instead"): - ctype_four.deserialize(ctype_five_bytes, 0) + ctype_four.deserialize(ctype_five_bytes) def test_deserialization_variable_size_too_small(self): ctype_four = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.IntegerType, 4)") - ctype_four_bytes = ctype_four.serialize([1, 2, 3, 4], 0) + ctype_four_bytes = ctype_four.serialize([1, 2, 3, 4]) ctype_five = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.IntegerType, 5)") with pytest.raises(ValueError, match="Error reading additional data during vector deserialization after successfully adding 4 elements"): - ctype_five.deserialize(ctype_four_bytes, 0) + ctype_five.deserialize(ctype_four_bytes) def test_deserialization_variable_size_too_big(self): ctype_five = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.IntegerType, 5)") - ctype_five_bytes = ctype_five.serialize([1, 2, 3, 4, 5], 0) + ctype_five_bytes = ctype_five.serialize([1, 2, 3, 4, 5]) ctype_four = parse_casstype_args("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.IntegerType, 4)") with pytest.raises(ValueError, match="Additional bytes remaining after vector deserialization completed"): - ctype_four.deserialize(ctype_five_bytes, 0) + ctype_four.deserialize(ctype_five_bytes) ZERO = datetime.timedelta(0) @@ -575,7 +575,7 @@ def test_deserialize_single_value(self): serialized = (int8_pack(0) + int64_pack(self.timestamp) + int8_pack(3)) - assert DateRangeType.deserialize(serialized, 5) == util.DateRange(value=util.DateRangeBound( + assert DateRangeType.deserialize(serialized) == util.DateRange(value=util.DateRangeBound( value=datetime.datetime(2017, 2, 1, 15, 42, 12, 404000), precision='HOUR') ) @@ -586,7 +586,7 @@ def test_deserialize_closed_range(self): int8_pack(2) + int64_pack(self.timestamp) + int8_pack(6)) - assert DateRangeType.deserialize(serialized, 5) == util.DateRange( + assert DateRangeType.deserialize(serialized) == util.DateRange( lower_bound=util.DateRangeBound( value=datetime.datetime(2017, 2, 1, 0, 0), precision='DAY' @@ -601,7 +601,7 @@ def test_deserialize_open_high(self): serialized = (int8_pack(2) + int64_pack(self.timestamp) + int8_pack(3)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( lower_bound=util.DateRangeBound( value=datetime.datetime(2017, 2, 1, 15, 0), @@ -614,7 +614,7 @@ def test_deserialize_open_low(self): serialized = (int8_pack(3) + int64_pack(self.timestamp) + int8_pack(4)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( lower_bound=util.OPEN_BOUND, upper_bound=util.DateRangeBound( @@ -624,13 +624,13 @@ def test_deserialize_open_low(self): ) def test_deserialize_single_open(self): - assert util.DateRange(value=util.OPEN_BOUND) == DateRangeType.deserialize(int8_pack(5), 5) + assert util.DateRange(value=util.OPEN_BOUND) == DateRangeType.deserialize(int8_pack(5)) def test_serialize_single_value(self): serialized = (int8_pack(0) + int64_pack(self.timestamp) + int8_pack(5)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( value=util.DateRangeBound( value=datetime.datetime(2017, 2, 1, 15, 42, 12), @@ -644,7 +644,7 @@ def test_serialize_closed_range(self): int8_pack(5) + int64_pack(self.timestamp) + int8_pack(0)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( lower_bound=util.DateRangeBound( value=datetime.datetime(2017, 2, 1, 15, 42, 12), @@ -660,7 +660,7 @@ def test_serialize_open_high(self): serialized = (int8_pack(2) + int64_pack(self.timestamp) + int8_pack(2)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( lower_bound=util.DateRangeBound( value=datetime.datetime(2017, 2, 1), @@ -673,7 +673,7 @@ def test_serialize_open_low(self): serialized = (int8_pack(2) + int64_pack(self.timestamp) + int8_pack(3)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( lower_bound=util.DateRangeBound( value=datetime.datetime(2017, 2, 1, 15), @@ -684,7 +684,7 @@ def test_serialize_open_low(self): def test_deserialize_both_open(self): serialized = (int8_pack(4)) - deserialized = DateRangeType.deserialize(serialized, 5) + deserialized = DateRangeType.deserialize(serialized) assert deserialized == util.DateRange( lower_bound=util.OPEN_BOUND, upper_bound=util.OPEN_BOUND @@ -693,31 +693,31 @@ def test_deserialize_both_open(self): def test_serialize_single_open(self): serialized = DateRangeType.serialize(util.DateRange( value=util.OPEN_BOUND, - ), 5) + )) assert int8_pack(5) == serialized def test_serialize_both_open(self): serialized = DateRangeType.serialize(util.DateRange( lower_bound=util.OPEN_BOUND, upper_bound=util.OPEN_BOUND - ), 5) + )) assert int8_pack(4) == serialized def test_failure_to_serialize_no_value_object(self): with pytest.raises(ValueError): - DateRangeType.serialize(object(), 5) + DateRangeType.serialize(object()) def test_failure_to_serialize_no_bounds_object(self): class no_bounds_object(object): value = lower_bound = None with pytest.raises(ValueError): - DateRangeType.serialize(no_bounds_object, 5) + DateRangeType.serialize(no_bounds_object) def test_serialized_value_round_trip(self): vals = [b'\x01\x00\x00\x01%\xe9a\xf9\xd1\x06\x00\x00\x01v\xbb>o\xff\x00', b'\x01\x00\x00\x00\xdcm\x03-\xd1\x06\x00\x00\x01v\xbb>o\xff\x00'] for serialized in vals: - assert serialized == DateRangeType.serialize(DateRangeType.deserialize(serialized, 0), 0) + assert serialized == DateRangeType.serialize(DateRangeType.deserialize(serialized)) def test_serialize_zero_datetime(self): """ @@ -734,7 +734,7 @@ def test_serialize_zero_datetime(self): DateRangeType.serialize(util.DateRange( lower_bound=(datetime.datetime(1970, 1, 1), 'YEAR'), upper_bound=(datetime.datetime(1970, 1, 1), 'YEAR') - ), 5) + )) def test_deserialize_zero_datetime(self): """ @@ -751,8 +751,7 @@ def test_deserialize_zero_datetime(self): DateRangeType.deserialize( (int8_pack(1) + int64_pack(0) + int8_pack(0) + - int64_pack(0) + int8_pack(0)), - 5 + int64_pack(0) + int8_pack(0)) )