def test_no_profile_with_legacy(self): # don't construct with both self.assertRaises(ValueError, Cluster, load_balancing_policy=RoundRobinPolicy(), execution_profiles={'a': ExecutionProfile()}) self.assertRaises(ValueError, Cluster, default_retry_policy=DowngradingConsistencyRetryPolicy(), execution_profiles={'a': ExecutionProfile()}) self.assertRaises(ValueError, Cluster, load_balancing_policy=RoundRobinPolicy(), default_retry_policy=DowngradingConsistencyRetryPolicy(), execution_profiles={'a': ExecutionProfile()}) # can't add after cluster = Cluster(load_balancing_policy=RoundRobinPolicy()) self.assertRaises(ValueError, cluster.add_execution_profile, 'name', ExecutionProfile()) # session settings lock out profiles cluster = Cluster() session = Session(cluster, hosts=[Host("127.0.0.1", SimpleConvictionPolicy)]) for attr, value in (('default_timeout', 1), ('default_consistency_level', ConsistencyLevel.ANY), ('default_serial_consistency_level', ConsistencyLevel.SERIAL), ('row_factory', tuple_factory)): cluster._config_mode = _ConfigMode.UNCOMMITTED setattr(session, attr, value) self.assertRaises(ValueError, cluster.add_execution_profile, 'name' + attr, ExecutionProfile()) # don't accept profile self.assertRaises(ValueError, session.execute_async, "query", execution_profile='some name here')
def get_lb_policy(policy_name: str, policy_args: Dict[str, Any]) -> Policy: """ Creates load balancing policy. :param policy_name: Name of the policy to use. :type policy_name: str :param policy_args: Parameters for the policy. :type policy_args: Dict """ if policy_name == 'DCAwareRoundRobinPolicy': local_dc = policy_args.get('local_dc', '') used_hosts_per_remote_dc = int(policy_args.get('used_hosts_per_remote_dc', 0)) return DCAwareRoundRobinPolicy(local_dc, used_hosts_per_remote_dc) if policy_name == 'WhiteListRoundRobinPolicy': hosts = policy_args.get('hosts') if not hosts: raise Exception('Hosts must be specified for WhiteListRoundRobinPolicy') return WhiteListRoundRobinPolicy(hosts) if policy_name == 'TokenAwarePolicy': allowed_child_policies = ('RoundRobinPolicy', 'DCAwareRoundRobinPolicy', 'WhiteListRoundRobinPolicy',) child_policy_name = policy_args.get('child_load_balancing_policy', 'RoundRobinPolicy') child_policy_args = policy_args.get('child_load_balancing_policy_args', {}) if child_policy_name not in allowed_child_policies: return TokenAwarePolicy(RoundRobinPolicy()) else: child_policy = CassandraHook.get_lb_policy(child_policy_name, child_policy_args) return TokenAwarePolicy(child_policy) # Fallback to default RoundRobinPolicy return RoundRobinPolicy()
def test_black_list_with_host_filter_policy(self): """ Test to validate removing certain hosts from the query plan with HostFilterPolicy @since 3.8 @jira_ticket PYTHON-961 @expected_result the excluded hosts are ignored @test_category policy """ use_singledc() keyspace = 'test_black_list_with_hfp' ignored_address = (IP_FORMAT % 2) hfp = HostFilterPolicy( child_policy=RoundRobinPolicy(), predicate=lambda host: host.address != ignored_address ) cluster = Cluster( (IP_FORMAT % 1,), load_balancing_policy=hfp, protocol_version=PROTOCOL_VERSION, topology_event_refresh_window=0, status_event_refresh_window=0 ) self.addCleanup(cluster.shutdown) session = cluster.connect() self._wait_for_nodes_up([1, 2, 3]) self.assertNotIn(ignored_address, [h.address for h in hfp.make_query_plan()]) create_schema(cluster, session, keyspace) self._insert(session, keyspace) self._query(session, keyspace) # RoundRobin doesn't provide a gurantee on the order of the hosts # so we will have that for 127.0.0.1 and 127.0.0.3 the count for one # will be 4 and for the other 8 first_node_count = self.coordinator_stats.get_query_count(1) third_node_count = self.coordinator_stats.get_query_count(3) self.assertEqual(first_node_count + third_node_count, 12) self.assertTrue(first_node_count == 8 or first_node_count == 4) self.coordinator_stats.assert_query_count_equals(self, 2, 0) # policy should not allow reconnecting to ignored host force_stop(2) self._wait_for_nodes_down([2]) self.assertFalse(cluster.metadata._hosts[ignored_address].is_currently_reconnecting())
def test_default_profile(self): non_default_profile = ExecutionProfile(RoundRobinPolicy(), *[object() for _ in range(3)]) cluster = Cluster( execution_profiles={'non-default': non_default_profile}) session = Session(cluster, hosts=[]) self.assertEqual(cluster._config_mode, _ConfigMode.PROFILES) default_profile = cluster.profile_manager.profiles[ EXEC_PROFILE_DEFAULT] rf = session.execute_async("query") self._verify_response_future_profile(rf, default_profile) rf = session.execute_async("query", execution_profile='non-default') self._verify_response_future_profile(rf, non_default_profile)
def test_default_legacy(self): cluster = Cluster( load_balancing_policy=RoundRobinPolicy(), default_retry_policy=DowngradingConsistencyRetryPolicy()) self.assertEqual(cluster._config_mode, _ConfigMode.LEGACY) session = Session(cluster, hosts=[]) session.default_timeout = 3.7 session.default_consistency_level = ConsistencyLevel.ALL session.default_serial_consistency_level = ConsistencyLevel.SERIAL rf = session.execute_async("query") expected_profile = ExecutionProfile( cluster.load_balancing_policy, cluster.default_retry_policy, session.default_consistency_level, session.default_serial_consistency_level, session.default_timeout, session.row_factory) self._verify_response_future_profile(rf, expected_profile)
def test_predicate_changes(self): """ Test to validate host filter reacts correctly when the predicate return a different subset of the hosts HostFilterPolicy @since 3.8 @jira_ticket PYTHON-961 @expected_result the excluded hosts are ignored @test_category policy """ external_event = True contact_point = DefaultEndPoint("127.0.0.1") single_host = {Host(contact_point, SimpleConvictionPolicy)} all_hosts = { Host(DefaultEndPoint("127.0.0.{}".format(i)), SimpleConvictionPolicy) for i in (1, 2, 3) } predicate = lambda host: host.endpoint == contact_point if external_event else True hfp = ExecutionProfile(load_balancing_policy=HostFilterPolicy( RoundRobinPolicy(), predicate=predicate)) cluster = Cluster((contact_point, ), execution_profiles={EXEC_PROFILE_DEFAULT: hfp}, protocol_version=PROTOCOL_VERSION, topology_event_refresh_window=0, status_event_refresh_window=0) session = cluster.connect(wait_for_all_pools=True) queried_hosts = set() for _ in range(10): response = session.execute("SELECT * from system.local") queried_hosts.update(response.response_future.attempted_hosts) self.assertEqual(queried_hosts, single_host) external_event = False futures = session.update_created_pools() wait_futures(futures, timeout=cluster.connect_timeout) queried_hosts = set() for _ in range(10): response = session.execute("SELECT * from system.local") queried_hosts.update(response.response_future.attempted_hosts) self.assertEqual(queried_hosts, all_hosts)
def test_target_host_down(self): node_count = 4 hosts = [Host(i, Mock()) for i in range(node_count)] target_host = hosts[1] policy = DSELoadBalancingPolicy(RoundRobinPolicy()) policy.populate( Mock(metadata=ClusterMetaMock({'127.0.0.1': target_host})), hosts) query_plan = list( policy.make_query_plan(None, Mock(target_host='127.0.0.1'))) self.assertEqual(sorted(query_plan), hosts) target_host.is_up = False policy.on_down(target_host) query_plan = list( policy.make_query_plan(None, Mock(target_host='127.0.0.1'))) self.assertNotIn(target_host, query_plan)
def test_delay_can_be_0(self): """ Test to validate that the delay can be zero for the ConstantSpeculativeExecutionPolicy @since 3.13 @jira_ticket PYTHON-836 @expected_result all the queries are executed immediately @test_category policy """ query_to_prime = "INSERT INTO madeup_keyspace.madeup_table(k, v) VALUES (1, 2)" prime_query(query_to_prime, then={"delay_in_ms": 5000}) number_of_requests = 4 spec = ExecutionProfile( load_balancing_policy=RoundRobinPolicy(), speculative_execution_policy=ConstantSpeculativeExecutionPolicy( 0, number_of_requests)) cluster = Cluster() cluster.add_execution_profile("spec", spec) session = cluster.connect(wait_for_all_pools=True) self.addCleanup(cluster.shutdown) counter = count() def patch_and_count(f): def patched(*args, **kwargs): next(counter) print("patched") f(*args, **kwargs) return patched self.addCleanup(setattr, ResponseFuture, "send_request", ResponseFuture.send_request) ResponseFuture.send_request = patch_and_count( ResponseFuture.send_request) stmt = SimpleStatement(query_to_prime) stmt.is_idempotent = True results = session.execute(stmt, execution_profile="spec") self.assertEqual(len(results.response_future.attempted_hosts), 3) # send_request is called number_of_requests times for the speculative request # plus one for the call from the main thread. self.assertEqual(next(counter), number_of_requests + 1)
def test_statement_params_override_legacy(self): cluster = Cluster(load_balancing_policy=RoundRobinPolicy(), default_retry_policy=DowngradingConsistencyRetryPolicy()) self.assertEqual(cluster._config_mode, _ConfigMode.LEGACY) session = Session(cluster, hosts=[Host("127.0.0.1", SimpleConvictionPolicy)]) ss = SimpleStatement("query", retry_policy=DowngradingConsistencyRetryPolicy(), consistency_level=ConsistencyLevel.ALL, serial_consistency_level=ConsistencyLevel.SERIAL) my_timeout = 1.1234 self.assertNotEqual(ss.retry_policy.__class__, cluster.default_retry_policy) self.assertNotEqual(ss.consistency_level, session.default_consistency_level) self.assertNotEqual(ss._serial_consistency_level, session.default_serial_consistency_level) self.assertNotEqual(my_timeout, session.default_timeout) rf = session.execute_async(ss, timeout=my_timeout) expected_profile = ExecutionProfile(load_balancing_policy=cluster.load_balancing_policy, retry_policy=ss.retry_policy, request_timeout=my_timeout, consistency_level=ss.consistency_level, serial_consistency_level=ss._serial_consistency_level) self._verify_response_future_profile(rf, expected_profile)
def get_cassandra_session(host, port, user, password, ssl_cert, ssl_key, ssl_version): """A function that establishes a Cassandra connection :param host: Hostname of IP address :type host: str :param port: Port to connect to :type port: int :param user: Database user :type user: str :param password: Password for the database user :type password: str :param ssl_cert: Path to ssl_certificate :type ssl_cert: str :param ssl_key: Path to ssl_key :type ssl_key: str :param ssl_version: Version of the SSL environment used for the connection :type ssl_version: str :return: The function returns an instance for the cassandra session :rtype: object """ auth_provider = PlainTextAuthProvider(username=user, password=password) ssl_options = { 'certfile': ssl_cert, 'keyfile': ssl_key, 'ssl_version': PROTOCOL_TLSv1_2 } policy = RoundRobinPolicy() profile = ExecutionProfile(consistency_level=ConsistencyLevel.LOCAL_ONE, load_balancing_policy=policy) cluster = Cluster([host], port=port, ssl_options=ssl_options, auth_provider=auth_provider, execution_profiles={EXEC_PROFILE_DEFAULT: profile}) session = cluster.connect() return session
def test_paused_connections(self): """ Verify all requests come back as expected if node resumes within query timeout """ start_and_prime_singledc() profile = ExecutionProfile(request_timeout=500, load_balancing_policy=RoundRobinPolicy()) cluster = Cluster( protocol_version=PROTOCOL_VERSION, compression=False, execution_profiles={EXEC_PROFILE_DEFAULT: profile}, ) session = cluster.connect(wait_for_all_pools=True) self.addCleanup(cluster.shutdown) query = session.prepare("INSERT INTO table1 (id) VALUES (?)") prime_request(PauseReads()) futures = self._fill_buffers(session, query) # Make sure we actually have some stuck in-flight requests for in_flight in [ pool._connection.in_flight for pool in session.get_pools() ]: self.assertGreater(in_flight, 100) time.sleep(.5) for in_flight in [ pool._connection.in_flight for pool in session.get_pools() ]: self.assertGreater(in_flight, 100) prime_request(ResumeReads()) for future in futures: try: future.result() except NoHostAvailable as e: # We shouldn't have any timeouts here, but all of the queries beyond what can fit # in the tcp buffer will have returned with a ConnectionBusy exception self.assertIn("ConnectionBusy", str(e)) # Verify that we can continue sending queries without any problems for host in session.cluster.metadata.all_hosts(): session.execute(query, ["a"], host=host)
def cql(request): profile = ExecutionProfile( load_balancing_policy=RoundRobinPolicy(), consistency_level=ConsistencyLevel.LOCAL_QUORUM, serial_consistency_level=ConsistencyLevel.LOCAL_SERIAL, # The default timeout (in seconds) for execute() commands is 10, which # should have been more than enough, but in some extreme cases with a # very slow debug build running on a very busy machine and a very slow # request (e.g., a DROP KEYSPACE needing to drop multiple tables) # 10 seconds may not be enough, so let's increase it. See issue #7838. request_timeout=120) cluster = Cluster( execution_profiles={EXEC_PROFILE_DEFAULT: profile}, contact_points=[request.config.getoption('host')], port=request.config.getoption('port'), # TODO: make the protocol version an option, to allow testing with # different versions. If we drop this setting completely, it will # mean pick the latest version supported by the client and the server. protocol_version=4) return cluster.connect()
def conn(self, *, ssl_path: str = None) -> Session: # type: ignore """Establishes a Cassandra connection.""" auth_provider = (PlainTextAuthProvider( username=self.cassandra_user, password=self.cassandra_password) if self.cassandra_user is not None else None) ssl_opts = ({ "ca_certs": ssl_path, "ssl_version": PROTOCOL_TLSv1, "cert_reqs": CERT_REQUIRED, } if ssl_path is not None else None) cluster = Cluster( contact_points=self.cassandra_host, auth_provider=auth_provider, ssl_options=ssl_opts, load_balancing_policy=RoundRobinPolicy(), ) self._session = cluster.connect(self.cassandra_key_space) self._session.row_factory = dict_factory return self._session
def test_default_profile(self): non_default_profile = ExecutionProfile(RoundRobinPolicy(), *[object() for _ in range(2)]) cluster = Cluster(execution_profiles={'non-default': non_default_profile}) session = Session(cluster, hosts=[Host("127.0.0.1", SimpleConvictionPolicy)]) self.assertEqual(cluster._config_mode, _ConfigMode.PROFILES) default_profile = session.get_execution_profile(EXEC_PROFILE_DEFAULT) rf = session.execute_async("query") self._verify_response_future_profile(rf, default_profile) rf = session.execute_async("query", execution_profile='non-default') self._verify_response_future_profile(rf, non_default_profile) for name, ep in six.iteritems(cluster.profile_manager.profiles): self.assertEqual(ep, session.get_execution_profile(name)) # invalid ep with self.assertRaises(ValueError): session.get_execution_profile('non-existent')
class MockCluster(object): max_schema_agreement_wait = Cluster.max_schema_agreement_wait load_balancing_policy = RoundRobinPolicy() reconnection_policy = ConstantReconnectionPolicy(2) def __init__(self): self.metadata = MockMetadata() self.added_hosts = [] self.removed_hosts = [] self.scheduler = Mock(spec=_Scheduler) self.executor = Mock(spec=ThreadPoolExecutor) def add_host(self, address, signal=False): host = Host(address, SimpleConvictionPolicy) self.added_hosts.append(host) return host def remove_host(self, host): self.removed_hosts.append(host)
def init(args): global solr_connection solr_connection = SolrConnection(args.solr) global solr_collection solr_collection = solr_connection[args.collection] dc_policy = RoundRobinPolicy() token_policy = TokenAwarePolicy(dc_policy) global cassandra_cluster cassandra_cluster = Cluster(contact_points=args.cassandra, port=args.cassandraPort, protocol_version=int( args.cassandraProtocolVersion), load_balancing_policy=token_policy) global cassandra_session cassandra_session = cassandra_cluster.connect( keyspace=args.cassandraKeyspace) global cassandra_table cassandra_table = args.cassandraTable
def test_roundrobin(self): use_singledc() keyspace = 'test_roundrobin' cluster = Cluster( load_balancing_policy=RoundRobinPolicy(), protocol_version=PROTOCOL_VERSION) session = cluster.connect() wait_for_up(cluster, 1, wait=False) wait_for_up(cluster, 2, wait=False) wait_for_up(cluster, 3) create_schema(session, keyspace, replication_factor=3) self._insert(session, keyspace) self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 4) self.coordinator_stats.assert_query_count_equals(self, 2, 4) self.coordinator_stats.assert_query_count_equals(self, 3, 4) force_stop(3) wait_for_down(cluster, 3) self.coordinator_stats.reset_counts() self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 6) self.coordinator_stats.assert_query_count_equals(self, 2, 6) self.coordinator_stats.assert_query_count_equals(self, 3, 0) decommission(1) start(3) wait_for_down(cluster, 1) wait_for_up(cluster, 3) self.coordinator_stats.reset_counts() self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 0) self.coordinator_stats.assert_query_count_equals(self, 2, 6) self.coordinator_stats.assert_query_count_equals(self, 3, 6)
def test_driver_recovers_nework_isolation(self): start_and_prime_singledc() idle_heartbeat_timeout = 3 idle_heartbeat_interval = 1 listener = TrackDownListener() cluster = Cluster( protocol_version=PROTOCOL_VERSION, contact_points=['127.0.0.1'], idle_heartbeat_timeout=idle_heartbeat_timeout, idle_heartbeat_interval=idle_heartbeat_interval, executor_threads=16, compression=False, execution_profiles={ EXEC_PROFILE_DEFAULT: ExecutionProfile(load_balancing_policy=RoundRobinPolicy()) }) session = cluster.connect(wait_for_all_pools=True) cluster.register_listener(listener) prime_request(PrimeOptions(then=NO_THEN)) prime_request(RejectConnections(RejectType.REJECT_STARTUP)) time.sleep((idle_heartbeat_timeout + idle_heartbeat_interval) * 2) for host in cluster.metadata.all_hosts(): self.assertIn(host, listener.hosts_marked_down) self.assertRaises(NoHostAvailable, session.execute, "SELECT * from system.local") clear_queries() prime_request(AcceptConnections()) time.sleep(idle_heartbeat_timeout + idle_heartbeat_interval + 2) self.assertIsNotNone(session.execute("SELECT * from system.local"))
def test_thread_safety_during_modification(self): hosts = range(100) policy = RoundRobinPolicy() policy.populate(None, hosts) errors = [] def check_query_plan(): try: for i in xrange(100): list(policy.make_query_plan()) except Exception as exc: errors.append(exc) def host_up(): for i in xrange(1000): policy.on_up(randint(0, 99)) def host_down(): for i in xrange(1000): policy.on_down(randint(0, 99)) threads = [] for i in range(5): threads.append(Thread(target=check_query_plan)) threads.append(Thread(target=host_up)) threads.append(Thread(target=host_down)) # make the GIL switch after every instruction, maximizing # the chace of race conditions original_interval = sys.getcheckinterval() try: sys.setcheckinterval(0) map(lambda t: t.start(), threads) map(lambda t: t.join(), threads) finally: sys.setcheckinterval(original_interval) if errors: self.fail("Saw errors: %s" % (errors, ))
def test_statement_params_override_profile(self): non_default_profile = ExecutionProfile(RoundRobinPolicy(), *[object() for _ in range(2)]) cluster = Cluster(execution_profiles={'non-default': non_default_profile}) session = Session(cluster, hosts=[Host("127.0.0.1", SimpleConvictionPolicy)]) self.assertEqual(cluster._config_mode, _ConfigMode.PROFILES) rf = session.execute_async("query", execution_profile='non-default') ss = SimpleStatement("query", retry_policy=DowngradingConsistencyRetryPolicy(), consistency_level=ConsistencyLevel.ALL, serial_consistency_level=ConsistencyLevel.SERIAL) my_timeout = 1.1234 self.assertNotEqual(ss.retry_policy.__class__, rf._load_balancer.__class__) self.assertNotEqual(ss.consistency_level, rf.message.consistency_level) self.assertNotEqual(ss._serial_consistency_level, rf.message.serial_consistency_level) self.assertNotEqual(my_timeout, rf.timeout) rf = session.execute_async(ss, timeout=my_timeout, execution_profile='non-default') expected_profile = ExecutionProfile(non_default_profile.load_balancing_policy, ss.retry_policy, ss.consistency_level, ss._serial_consistency_level, my_timeout, non_default_profile.row_factory) self._verify_response_future_profile(rf, expected_profile)
def test_wrap_round_robin(self): cluster = Mock(spec=Cluster) cluster.metadata = Mock(spec=Metadata) hosts = [Host(str(i), SimpleConvictionPolicy) for i in range(4)] def get_replicas(keyspace, packed_key): index = struct.unpack('>i', packed_key)[0] return list(islice(cycle(hosts), index, index + 2)) cluster.metadata.get_replicas.side_effect = get_replicas policy = TokenAwarePolicy(RoundRobinPolicy()) policy.populate(cluster, hosts) for i in range(4): query = Statement(routing_key=struct.pack('>i', i)) qplan = list(policy.make_query_plan(None, query)) replicas = get_replicas(None, struct.pack('>i', i)) other = set(h for h in hosts if h not in replicas) self.assertEquals(replicas, qplan[:2]) self.assertEquals(other, set(qplan[2:]))
def test_roundrobin_two_dcs_2(self): use_multidc([2, 2]) keyspace = 'test_roundrobin_two_dcs_2' cluster = Cluster( load_balancing_policy=RoundRobinPolicy(), protocol_version=PROTOCOL_VERSION) session = cluster.connect() wait_for_up(cluster, 1, wait=False) wait_for_up(cluster, 2, wait=False) wait_for_up(cluster, 3, wait=False) wait_for_up(cluster, 4) create_schema(session, keyspace, replication_strategy=[2, 2]) self._insert(session, keyspace) self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 3) self.coordinator_stats.assert_query_count_equals(self, 2, 3) self.coordinator_stats.assert_query_count_equals(self, 3, 3) self.coordinator_stats.assert_query_count_equals(self, 4, 3) force_stop(1) bootstrap(5, 'dc1') # reset control connection self._insert(session, keyspace, count=1000) wait_for_up(cluster, 5) self.coordinator_stats.reset_counts() self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 0) self.coordinator_stats.assert_query_count_equals(self, 2, 3) self.coordinator_stats.assert_query_count_equals(self, 3, 3) self.coordinator_stats.assert_query_count_equals(self, 4, 3) self.coordinator_stats.assert_query_count_equals(self, 5, 3) cluster.shutdown()
def test_queued_requests_timeout(self): """ Verify that queued requests timeout as expected """ start_and_prime_singledc() profile = ExecutionProfile(request_timeout=.1, load_balancing_policy=RoundRobinPolicy()) cluster = Cluster( protocol_version=PROTOCOL_VERSION, compression=False, execution_profiles={EXEC_PROFILE_DEFAULT: profile}, ) session = cluster.connect(wait_for_all_pools=True) self.addCleanup(cluster.shutdown) query = session.prepare("INSERT INTO table1 (id) VALUES (?)") prime_request(PauseReads()) futures = [] for i in range(1000): future = session.execute_async(query, [str(i)]) future.add_callbacks(callback=self.callback_success, errback=self.callback_error) futures.append(future) successes = 0 for future in futures: try: future.result() successes += 1 except OperationTimedOut: pass # Simulacron will respond to a couple queries before cutting off reads, so we'll just verify # that only "a few" successes happened here self.assertLess(successes, 50) self.assertLess(self.callback_successes, 50) self.assertEqual(self.callback_errors, len(futures) - self.callback_successes)
def test_token_aware_composite_key(self): use_singledc() keyspace = 'test_token_aware_composite_key' table = 'composite' cluster, session = self._cluster_session_with_lbp( TokenAwarePolicy(RoundRobinPolicy())) self._wait_for_nodes_up(range(1, 4), cluster) create_schema(cluster, session, keyspace, replication_factor=2) session.execute('CREATE TABLE %s (' 'k1 int, ' 'k2 int, ' 'i int, ' 'PRIMARY KEY ((k1, k2)))' % table) prepared = session.prepare('INSERT INTO %s ' '(k1, k2, i) ' 'VALUES ' '(?, ?, ?)' % table) bound = prepared.bind((1, 2, 3)) result = session.execute(bound) self.assertIn( result.response_future.attempted_hosts[0], cluster.metadata.get_replicas(keyspace, bound.routing_key)) # There could be race condition with querying a node # which doesn't yet have the data so we query one of # the replicas results = session.execute( SimpleStatement('SELECT * FROM %s WHERE k1 = 1 AND k2 = 2' % table, routing_key=bound.routing_key)) self.assertIn( results.response_future.attempted_hosts[0], cluster.metadata.get_replicas(keyspace, bound.routing_key)) self.assertTrue(results[0].i) cluster.shutdown()
def setUp(self): """ Setup sessions and pause node1 """ # self.node1, self.node2, self.node3 = get_cluster().nodes.values() node1 = ExecutionProfile(load_balancing_policy=HostFilterPolicy( RoundRobinPolicy(), lambda host: host.address == "127.0.0.1")) self.cluster = Cluster( protocol_version=PROTOCOL_VERSION, execution_profiles={EXEC_PROFILE_DEFAULT: node1}) self.session = self.cluster.connect(wait_for_all_pools=True) self.control_connection_host_number = 1 self.node_to_stop = get_node(self.control_connection_host_number) ddl = ''' CREATE TABLE test3rf.timeout ( k int PRIMARY KEY, v int )''' self.session.execute(ddl) self.node_to_stop.pause()
def test_cluster_busy(self): """ Verify that once TCP buffer is full we get busy exceptions rather than timeouts """ start_and_prime_singledc() profile = ExecutionProfile(load_balancing_policy=RoundRobinPolicy()) cluster = Cluster( protocol_version=PROTOCOL_VERSION, compression=False, execution_profiles={EXEC_PROFILE_DEFAULT: profile}, ) session = cluster.connect(wait_for_all_pools=True) self.addCleanup(cluster.shutdown) query = session.prepare("INSERT INTO table1 (id) VALUES (?)") prime_request(PauseReads()) # These requests will get stuck in the TCP buffer and we have no choice but to let them time out self._fill_buffers(session, query, expected_blocked=3) # Now that our send buffer is completely full, verify we immediately get busy exceptions rather than timing out for i in range(1000): with self.assertRaises(NoHostAvailable) as e: session.execute(query, [str(i)]) self.assertIn("ConnectionBusy", str(e.exception))
def test_roundrobin(self): use_singledc() keyspace = 'test_roundrobin' cluster, session = self._cluster_session_with_lbp(RoundRobinPolicy()) self.addCleanup(cluster.shutdown) self._wait_for_nodes_up(range(1, 4), cluster) create_schema(cluster, session, keyspace, replication_factor=3) self._insert(session, keyspace) self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 4) self.coordinator_stats.assert_query_count_equals(self, 2, 4) self.coordinator_stats.assert_query_count_equals(self, 3, 4) force_stop(3) self._wait_for_nodes_down([3], cluster) self.coordinator_stats.reset_counts() self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 6) self.coordinator_stats.assert_query_count_equals(self, 2, 6) self.coordinator_stats.assert_query_count_equals(self, 3, 0) decommission(1) start(3) self._wait_for_nodes_down([1], cluster) self._wait_for_nodes_up([3], cluster) self.coordinator_stats.reset_counts() self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 0) self.coordinator_stats.assert_query_count_equals(self, 2, 6) self.coordinator_stats.assert_query_count_equals(self, 3, 6)
def test_token_aware_with_rf_2(self, use_prepared=False): use_singledc() keyspace = 'test_token_aware_with_rf_2' cluster, session = self._cluster_session_with_lbp(TokenAwarePolicy(RoundRobinPolicy())) self.addCleanup(cluster.shutdown) self._wait_for_nodes_up(range(1, 4), cluster) create_schema(cluster, session, keyspace, replication_factor=2) self._insert(session, keyspace) self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 0) self.coordinator_stats.assert_query_count_equals(self, 2, 12) self.coordinator_stats.assert_query_count_equals(self, 3, 0) self.coordinator_stats.reset_counts() stop(2) self._wait_for_nodes_down([2], cluster) self._query(session, keyspace) self.coordinator_stats.assert_query_count_equals(self, 1, 0) self.coordinator_stats.assert_query_count_equals(self, 2, 0) self.coordinator_stats.assert_query_count_equals(self, 3, 12)
def test_token_aware_composite_key(self): use_singledc() keyspace = 'test_token_aware_composite_key' table = 'composite' cluster, session = self._cluster_session_with_lbp(TokenAwarePolicy(RoundRobinPolicy())) self._wait_for_nodes_up(range(1, 4), cluster) create_schema(cluster, session, keyspace, replication_factor=2) session.execute('CREATE TABLE %s (' 'k1 int, ' 'k2 int, ' 'i int, ' 'PRIMARY KEY ((k1, k2)))' % table) prepared = session.prepare('INSERT INTO %s ' '(k1, k2, i) ' 'VALUES ' '(?, ?, ?)' % table) session.execute(prepared.bind((1, 2, 3))) results = session.execute('SELECT * FROM %s WHERE k1 = 1 AND k2 = 2' % table) self.assertTrue(results[0].i) cluster.shutdown()
def test_rfthree_tokenaware_none_down(self): keyspace = 'test_rfthree_tokenaware_none_down' cluster = Cluster( load_balancing_policy=TokenAwarePolicy(RoundRobinPolicy()), protocol_version=PROTOCOL_VERSION) session = cluster.connect(wait_for_all_pools=True) wait_for_up(cluster, 1) wait_for_up(cluster, 2) create_schema(cluster, session, keyspace, replication_factor=3) self._insert(session, keyspace, count=1) self._query(session, keyspace, count=1) self.coordinator_stats.assert_query_count_equals(self, 1, 0) self.coordinator_stats.assert_query_count_equals(self, 2, 1) self.coordinator_stats.assert_query_count_equals(self, 3, 0) self.coordinator_stats.reset_counts() self._assert_writes_succeed(session, keyspace, SINGLE_DC_CONSISTENCY_LEVELS) self._assert_reads_succeed(session, keyspace, SINGLE_DC_CONSISTENCY_LEVELS - set([ConsistencyLevel.ANY]), expected_reader=2) cluster.shutdown()