def use_cluster_with_graph(num_nodes): """ This is a work around to account for the fact that spark nodes will conflict over master assignment when started all at once. """ # Create the cluster but don't start it. use_singledc(start=False, workloads=['graph', 'spark']) # Start first node. get_node(1).start(wait_for_binary_proto=True) # Wait binary protocol port to open wait_for_node_socket(get_node(1), 120) # Wait for spark master to start up spark_master_http = ("localhost", 7080) common.check_socket_listening(spark_master_http, timeout=60) tmp_cluster = Cluster(protocol_version=PROTOCOL_VERSION) # Start up remaining nodes. try: session = tmp_cluster.connect() statement = "ALTER KEYSPACE dse_leases WITH REPLICATION = {'class': 'NetworkTopologyStrategy', 'dc1': '%d'}" % (num_nodes) session.execute(statement) finally: tmp_cluster.shutdown() for i in range(1, num_nodes+1): if i is not 1: node = get_node(i) node.start(wait_for_binary_proto=True) wait_for_node_socket(node, 120) # Wait for workers to show up as Alive on master wait_for_spark_workers(3, 120)
class BasicGraphUnitTestCase(BasicKeyspaceUnitTestCase): """ This is basic graph unit test case that provides various utility methods that can be leveraged for testcase setup and tear down """ @property def graph_name(self): return self._testMethodName.lower() def session_setup(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect() self.ks_name = self._testMethodName.lower() self.cass_version, self.cql_version = get_server_versions() def setUp(self): self.session_setup() self.reset_graph() profiles = self.cluster.profile_manager.profiles profiles[EXEC_PROFILE_GRAPH_DEFAULT].graph_options.graph_name = self.graph_name profiles[EXEC_PROFILE_GRAPH_ANALYTICS_DEFAULT].graph_options.graph_name = self.graph_name self.clear_schema() def tearDown(self): self.cluster.shutdown() def clear_schema(self): self.session.execute_graph('schema.clear()') def reset_graph(self): reset_graph(self.session, self.graph_name) def wait_for_graph_inserted(self): wait_for_graph_inserted(self.session, self.graph_name)
data3 = randint(1,100) current = time.localtime() bucket = str(current.tm_year) + str(current.tm_mon) + str(current.tm_mday) + str(current.tm_hour) + str(current.tm_min) d = time.strftime('%Y-%m-%dT%H:%M:%S', current) query = """ INSERT INTO demo.table1 (bucket, ts, d, data1, data2, data3) VALUES ('%s', now(), '%s', %s, %s, %s) """ % (str(bucket), str(d), int(data1), int(data2), int(data3)) session.execute (query) #session.execute_async (query) ts = int(time.time() * 1000) while ts + cross_dc_latency_ms > int(time.time() * 1000): t1 = 0 c = c + 1 x = x + 1 #print ".", if(x == rowcount): last_c = coordinator future = session.execute_async (query, trace=True ) result = future.result() try: trace = future.get_query_trace(1) coordinator = trace.coordinator except: coordinator = last_c for h in session.hosts: if h.address == coordinator: used_dc = h.datacenter print(""" Rows Written %s (%s) - %s""" ) % (c, used_dc, d) x = 0 cluster.shutdown() sys.exit(0)
class PreparedStatementTests(unittest.TestCase): @classmethod def setUpClass(cls): cls.cass_version = get_server_versions() def setUp(self): self.cluster = Cluster(metrics_enabled=True, protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect() def tearDown(self): self.cluster.shutdown() def test_basic(self): """ Test basic PreparedStatement usage """ self.session.execute( """ DROP KEYSPACE IF EXISTS preparedtests """ ) self.session.execute( """ CREATE KEYSPACE preparedtests WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} """) self.session.set_keyspace("preparedtests") self.session.execute( """ CREATE TABLE cf0 ( a text, b text, c text, PRIMARY KEY (a, b) ) """) prepared = self.session.prepare( """ INSERT INTO cf0 (a, b, c) VALUES (?, ?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind(('a', 'b', 'c')) self.session.execute(bound) prepared = self.session.prepare( """ SELECT * FROM cf0 WHERE a=? """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind(('a')) results = self.session.execute(bound) self.assertEqual(results, [('a', 'b', 'c')]) # test with new dict binding prepared = self.session.prepare( """ INSERT INTO cf0 (a, b, c) VALUES (?, ?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind({ 'a': 'x', 'b': 'y', 'c': 'z' }) self.session.execute(bound) prepared = self.session.prepare( """ SELECT * FROM cf0 WHERE a=? """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind({'a': 'x'}) results = self.session.execute(bound) self.assertEqual(results, [('x', 'y', 'z')]) def test_missing_primary_key(self): """ Ensure an InvalidRequest is thrown when prepared statements are missing the primary key """ self._run_missing_primary_key(self.session) def _run_missing_primary_key(self, session): statement_to_prepare = """INSERT INTO test3rf.test (v) VALUES (?)""" # logic needed work with changes in CASSANDRA-6237 if self.cass_version[0] >= (3, 0, 0): self.assertRaises(InvalidRequest, session.prepare, statement_to_prepare) else: prepared = session.prepare(statement_to_prepare) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1,)) self.assertRaises(InvalidRequest, session.execute, bound) def test_missing_primary_key_dicts(self): """ Ensure an InvalidRequest is thrown when prepared statements are missing the primary key with dict bindings """ self._run_missing_primary_key_dicts(self.session) def _run_missing_primary_key_dicts(self, session): statement_to_prepare = """ INSERT INTO test3rf.test (v) VALUES (?)""" # logic needed work with changes in CASSANDRA-6237 if self.cass_version[0] >= (3, 0, 0): self.assertRaises(InvalidRequest, session.prepare, statement_to_prepare) else: prepared = session.prepare(statement_to_prepare) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind({'v': 1}) self.assertRaises(InvalidRequest, session.execute, bound) def test_too_many_bind_values(self): """ Ensure a ValueError is thrown when attempting to bind too many variables """ self._run_too_many_bind_values(self.session) def _run_too_many_bind_values(self, session): statement_to_prepare = """ INSERT INTO test3rf.test (v) VALUES (?)""" # logic needed work with changes in CASSANDRA-6237 if self.cass_version[0] >= (3, 0, 0): self.assertRaises(InvalidRequest, session.prepare, statement_to_prepare) else: prepared = session.prepare(statement_to_prepare) self.assertIsInstance(prepared, PreparedStatement) self.assertRaises(ValueError, prepared.bind, (1, 2)) def test_imprecise_bind_values_dicts(self): """ Ensure an error is thrown when attempting to bind the wrong values with dict bindings """ prepared = self.session.prepare( """ INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) # too many values is ok - others are ignored 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 self.assertRaises(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}) # also catch too few variables with dicts self.assertIsInstance(prepared, PreparedStatement) if PROTOCOL_VERSION < 4: self.assertRaises(KeyError, prepared.bind, {}) else: # post v4, the driver attempts to use UNSET_VALUE for unspecified keys self.assertRaises(ValueError, prepared.bind, {}) def test_none_values(self): """ Ensure binding None is handled correctly """ prepared = self.session.prepare( """ INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1, None)) self.session.execute(bound) prepared = self.session.prepare( """ SELECT * FROM test3rf.test WHERE k=? """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1,)) results = self.session.execute(bound) self.assertEqual(results[0].v, None) def test_unset_values(self): """ Test to validate that UNSET_VALUEs are bound, and have the expected effect Prepare a statement and insert all values. Then follow with execute excluding parameters. Verify that the original values are unaffected. @since 2.6.0 @jira_ticket PYTHON-317 @expected_result UNSET_VALUE is implicitly added to bind parameters, and properly encoded, leving unset values unaffected. @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)") insert = self.session.prepare("INSERT INTO test1rf.test_unset_values (k, v0, v1) VALUES (?, ?, ?)") select = self.session.prepare("SELECT * FROM test1rf.test_unset_values WHERE k=?") bind_expected = [ # initial condition ((0, 0, 0), (0, 0, 0)), # unset implicit ((0, 1,), (0, 1, 0)), ({'k': 0, 'v0': 2}, (0, 2, 0)), ({'k': 0, 'v1': 1}, (0, 2, 1)), # unset explicit ((0, 3, UNSET_VALUE), (0, 3, 1)), ((0, UNSET_VALUE, 2), (0, 3, 2)), ({'k': 0, 'v0': 4, 'v1': UNSET_VALUE}, (0, 4, 2)), ({'k': 0, 'v0': UNSET_VALUE, 'v1': 3}, (0, 4, 3)), # nulls still work ((0, None, None), (0, None, None)), ] for params, expected in bind_expected: self.session.execute(insert, params) results = self.session.execute(select, (0,)) self.assertEqual(results[0], expected) self.assertRaises(ValueError, self.session.execute, select, (UNSET_VALUE, 0, 0)) def test_no_meta(self): prepared = self.session.prepare( """ INSERT INTO test3rf.test (k, v) VALUES (0, 0) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind(None) bound.consistency_level = ConsistencyLevel.ALL self.session.execute(bound) prepared = self.session.prepare( """ SELECT * FROM test3rf.test WHERE k=0 """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind(None) bound.consistency_level = ConsistencyLevel.ALL results = self.session.execute(bound) self.assertEqual(results[0].v, 0) def test_none_values_dicts(self): """ Ensure binding None is handled correctly with dict bindings """ # test with new dict binding prepared = self.session.prepare( """ INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind({'k': 1, 'v': None}) self.session.execute(bound) prepared = self.session.prepare( """ SELECT * FROM test3rf.test WHERE k=? """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind({'k': 1}) results = self.session.execute(bound) self.assertEqual(results[0].v, None) def test_async_binding(self): """ Ensure None binding over async queries """ prepared = self.session.prepare( """ INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) future = self.session.execute_async(prepared, (873, None)) future.result() prepared = self.session.prepare( """ SELECT * FROM test3rf.test WHERE k=? """) self.assertIsInstance(prepared, PreparedStatement) future = self.session.execute_async(prepared, (873,)) results = future.result() self.assertEqual(results[0].v, None) def test_async_binding_dicts(self): """ Ensure None binding over async queries with dict bindings """ prepared = self.session.prepare( """ INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) future = self.session.execute_async(prepared, {'k': 873, 'v': None}) future.result() prepared = self.session.prepare( """ SELECT * FROM test3rf.test WHERE k=? """) self.assertIsInstance(prepared, PreparedStatement) future = self.session.execute_async(prepared, {'k': 873}) results = future.result() self.assertEqual(results[0].v, None) def test_raise_error_on_prepared_statement_execution_dropped_table(self): """ test for error in executing prepared statement on a dropped table test_raise_error_on_execute_prepared_statement_dropped_table tests that an InvalidRequest is raised when a prepared statement is executed after its corresponding table is dropped. This happens because if a prepared statement is invalid, the driver attempts to automatically re-prepare it on a non-existing table. @expected_errors InvalidRequest If a prepared statement is executed on a dropped table @since 2.6.0 @jira_ticket PYTHON-207 @expected_result InvalidRequest error should be raised upon prepared statement execution. @test_category prepared_statements """ self.session.execute("CREATE TABLE test3rf.error_test (k int PRIMARY KEY, v int)") prepared = self.session.prepare("SELECT * FROM test3rf.error_test WHERE k=?") self.session.execute("DROP TABLE test3rf.error_test") with self.assertRaises(InvalidRequest): self.session.execute(prepared, [0]) # TODO revisit this test, it on hold now due to CASSANDRA-10786 @unittest.skip def test_invalidated_result_metadata(self): """ Tests to make sure cached metadata is updated when an invalidated prepared statement is reprepared. @since 2.7.0 @jira_ticket PYTHON-621 Prior to this fix, the request would blow up with a protocol error when the result was decoded expecting a different number of columns. """ s = self.session s.result_factory = tuple_factory table = "test1rf.%s" % self._testMethodName.lower() s.execute("DROP TABLE IF EXISTS %s" % table) s.execute("CREATE TABLE %s (k int PRIMARY KEY, a int, b int, c int)" % table) s.execute("INSERT INTO %s (k, a, b, c) VALUES (0, 0, 0, 0)" % table) wildcard_prepared = s.prepare("SELECT * FROM %s" % table) original_result_metadata = wildcard_prepared.result_metadata self.assertEqual(len(original_result_metadata), 4) r = s.execute(wildcard_prepared) self.assertEqual(r[0], (0, 0, 0, 0)) s.execute("ALTER TABLE %s DROP c" % table) # Get a bunch of requests in the pipeline with varying states of result_meta, reprepare, resolved futures = set(s.execute_async(wildcard_prepared.bind(None)) for _ in range(200)) for f in futures: self.assertEqual(f.result()[0], (0, 0, 0)) self.assertIsNot(wildcard_prepared.result_metadata, original_result_metadata) s.execute("DROP TABLE %s" % table)
class HeartbeatTest(unittest.TestCase): """ Test to validate failing a heartbeat check doesn't mark a host as down @since 3.3 @jira_ticket PYTHON-286 @expected_result host should not be marked down when heartbeat fails @test_category connection heartbeat """ def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION, idle_heartbeat_interval=1) self.session = self.cluster.connect(wait_for_all_pools=True) def tearDown(self): self.cluster.shutdown() @local def test_heart_beat_timeout(self): # Setup a host listener to ensure the nodes don't go down test_listener = TestHostListener() host = "127.0.0.1" node = get_node(1) initial_connections = self.fetch_connections(host, self.cluster) self.assertNotEqual(len(initial_connections), 0) self.cluster.register_listener(test_listener) # Pause the node try: node.pause() # Wait for connections associated with this host go away self.wait_for_no_connections(host, self.cluster) # Resume paused node finally: node.resume() # Run a query to ensure connections are re-established current_host = "" count = 0 while current_host != host and count < 100: rs = self.session.execute_async("SELECT * FROM system.local", trace=False) rs.result() current_host = str(rs._current_host) count += 1 time.sleep(.1) self.assertLess(count, 100, "Never connected to the first node") new_connections = self.wait_for_connections(host, self.cluster) self.assertIsNone(test_listener.host_down) # Make sure underlying new connections don't match previous ones for connection in initial_connections: self.assertFalse(connection in new_connections) def fetch_connections(self, host, cluster): # Given a cluster object and host grab all connection associated with that host connections = [] holders = cluster.get_connection_holders() for conn in holders: if host == str(getattr(conn, 'host', '')): if conn._connection is not None: connections.append(conn._connection) return connections def wait_for_connections(self, host, cluster): retry = 0 while(retry < 300): retry += 1 connections = self.fetch_connections(host, cluster) if len(connections) is not 0: return connections time.sleep(.1) self.fail("No new connections found") def wait_for_no_connections(self, host, cluster): retry = 0 while(retry < 100): retry += 1 connections = self.fetch_connections(host, cluster) if len(connections) is 0: return time.sleep(.5) self.fail("Connections never cleared")
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 = Cluster(protocol_version=PROTOCOL_VERSION) s = c.connect(self.keyspace_name, wait_for_all_pools=True) s.encoder.mapping[tuple] = s.encoder.cql_encode_tuple name = self._testMethodName s.execute(""" CREATE TYPE %s ( m frozen<map<int,text>>, t tuple<int,text>, l frozen<list<int>>, s frozen<set<int>> )""" % name) s.execute(""" CREATE TYPE %s_nested ( m frozen<map<int,text>>, t tuple<int,text>, l frozen<list<int>>, s frozen<set<int>>, u frozen<%s> )""" % (name, name)) s.execute(""" CREATE TABLE %s ( k int PRIMARY KEY, map_map map<frozen<map<int,int>>, frozen<map<int,int>>>, map_set map<frozen<set<int>>, frozen<set<int>>>, map_list map<frozen<list<int>>, frozen<list<int>>>, map_tuple map<frozen<tuple<int, int>>, frozen<tuple<int>>>, map_udt map<frozen<%s_nested>, frozen<%s>>, )""" % (name, name, name)) validate = partial(self.insert_select_column, s, name) validate( 'map_map', OrderedMap([({ 1: 1, 2: 2 }, { 3: 3, 4: 4 }), ({ 5: 5, 6: 6 }, { 7: 7, 8: 8 })])) validate( 'map_set', OrderedMap([(set((1, 2)), set((3, 4))), (set((5, 6)), set( (7, 8)))])) validate('map_list', OrderedMap([([1, 2], [3, 4]), ([5, 6], [7, 8])])) validate('map_tuple', OrderedMap([((1, 2), (3, )), ((4, 5), (6, ))])) value = nested_collection_udt({ 1: 'v1', 2: 'v2' }, (3, 'v3'), [4, 5, 6, 7], set((8, 9, 10))) key = nested_collection_udt_nested(value.m, value.t, value.l, value.s, value) key2 = nested_collection_udt_nested({3: 'v3'}, value.t, value.l, value.s, value) validate('map_udt', OrderedMap([(key, value), (key2, value)])) c.shutdown()
class ClientExceptionTests(unittest.TestCase): def setUp(self): """ Test is skipped if run with native protocol version <4 """ self.support_v5 = True if PROTOCOL_VERSION < 4: raise unittest.SkipTest( "Native protocol 4,0+ is required for custom payloads, currently using %r" % (PROTOCOL_VERSION,)) try: self.cluster = Cluster(protocol_version=ProtocolVersion.MAX_SUPPORTED, allow_beta_protocol_version=True) self.session = self.cluster.connect() except NoHostAvailable: log.info("Protocol Version 5 not supported,") self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect() self.support_v5 = False self.nodes_currently_failing = [] self.node1, self.node2, self.node3 = get_cluster().nodes.values() def tearDown(self): self.cluster.shutdown() failing_nodes = [] # Restart the nodes to fully functional again self.setFailingNodes(failing_nodes, "testksfail") def execute_helper(self, session, query): tries = 0 while tries < 100: try: return session.execute(query) except OperationTimedOut: ex_type, ex, tb = sys.exc_info() log.warn("{0}: {1} Backtrace: {2}".format(ex_type.__name__, ex, traceback.extract_tb(tb))) del tb tries += 1 raise RuntimeError("Failed to execute query after 100 attempts: {0}".format(query)) def execute_concurrent_args_helper(self, session, query, params): tries = 0 while tries < 100: try: return execute_concurrent_with_args(session, query, params, concurrency=50) except (ReadTimeout, WriteTimeout, OperationTimedOut, ReadFailure, WriteFailure): ex_type, ex, tb = sys.exc_info() log.warn("{0}: {1} Backtrace: {2}".format(ex_type.__name__, ex, traceback.extract_tb(tb))) del tb tries += 1 raise RuntimeError("Failed to execute query after 100 attempts: {0}".format(query)) def setFailingNodes(self, failing_nodes, keyspace): """ This method will take in a set of failing nodes, and toggle all of the nodes in the provided list to fail writes. @param failing_nodes A definitive list of nodes that should fail writes @param keyspace The keyspace to enable failures on """ # Ensure all of the nodes on the list have failures enabled for node in failing_nodes: if node not in self.nodes_currently_failing: node.stop(wait_other_notice=True, gently=False) node.start(jvm_args=[" -Dcassandra.test.fail_writes_ks=" + keyspace], wait_for_binary_proto=True, wait_other_notice=True) self.nodes_currently_failing.append(node) # Ensure all nodes not on the list, but that are currently set to failing are enabled for node in self.nodes_currently_failing: if node not in failing_nodes: node.stop(wait_other_notice=True, gently=True) node.start(wait_for_binary_proto=True, wait_other_notice=True) self.nodes_currently_failing.remove(node) def _perform_cql_statement(self, text, consistency_level, expected_exception, session=None): """ Simple helper method to preform cql statements and check for expected exception @param text CQl statement to execute @param consistency_level Consistency level at which it is to be executed @param expected_exception Exception expected to be throw or none """ if session is None: session = self.session statement = SimpleStatement(text) statement.consistency_level = consistency_level if expected_exception is None: self.execute_helper(session, statement) else: with self.assertRaises(expected_exception) as cm: self.execute_helper(session, statement) if self.support_v5 and (isinstance(cm.exception, WriteFailure) or isinstance(cm.exception, ReadFailure)): if isinstance(cm.exception, ReadFailure): self.assertEqual(list(cm.exception.error_code_map.values())[0], 1) else: self.assertEqual(list(cm.exception.error_code_map.values())[0], 0) def test_write_failures_from_coordinator(self): """ Test to validate that write failures from the coordinator are surfaced appropriately. test_write_failures_from_coordinator Enable write failures on the various nodes using a custom jvm flag, cassandra.test.fail_writes_ks. This will cause writes to fail on that specific node. Depending on the replication factor of the keyspace, and the consistency level, we will expect the coordinator to send WriteFailure, or not. @since 2.6.0, 3.7.0 @jira_ticket PYTHON-238, PYTHON-619 @expected_result Appropriate write failures from the coordinator @test_category queries:basic """ # Setup temporary keyspace. self._perform_cql_statement( """ CREATE KEYSPACE testksfail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'} """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) # create table self._perform_cql_statement( """ CREATE TABLE testksfail.test ( k int PRIMARY KEY, v int ) """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) # Disable one node failing_nodes = [self.node1] self.setFailingNodes(failing_nodes, "testksfail") # With one node disabled we would expect a write failure with ConsistencyLevel of all self._perform_cql_statement( """ INSERT INTO testksfail.test (k, v) VALUES (1, 0 ) """, consistency_level=ConsistencyLevel.ALL, expected_exception=WriteFailure) # We have two nodes left so a write with consistency level of QUORUM should complete as expected self._perform_cql_statement( """ INSERT INTO testksfail.test (k, v) VALUES (1, 0 ) """, consistency_level=ConsistencyLevel.QUORUM, expected_exception=None) failing_nodes = [] # Restart the nodes to fully functional again self.setFailingNodes(failing_nodes, "testksfail") # Drop temporary keyspace self._perform_cql_statement( """ DROP KEYSPACE testksfail """, consistency_level=ConsistencyLevel.ANY, expected_exception=None) def test_tombstone_overflow_read_failure(self): """ Test to validate that a ReadFailure is returned from the node when a specified threshold of tombstombs is reached. test_tombstomb_overflow_read_failure First sets the tombstone failure threshold down to a level that allows it to be more easily encountered. We then create some wide rows and ensure they are deleted appropriately. This produces the correct amount of tombstombs. Upon making a simple query we expect to get a read failure back from the coordinator. @since 2.6.0, 3.7.0 @jira_ticket PYTHON-238, PYTHON-619 @expected_result Appropriate write failures from the coordinator @test_category queries:basic """ # Setup table for "wide row" self._perform_cql_statement( """ CREATE TABLE test3rf.test2 ( k int, v0 int, v1 int, PRIMARY KEY (k,v0)) """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) statement = self.session.prepare("INSERT INTO test3rf.test2 (k, v0,v1) VALUES (1,?,1)") parameters = [(x,) for x in range(3000)] self.execute_concurrent_args_helper(self.session, statement, parameters) statement = self.session.prepare("DELETE v1 FROM test3rf.test2 WHERE k = 1 AND v0 =?") parameters = [(x,) for x in range(2001)] self.execute_concurrent_args_helper(self.session, statement, parameters) self._perform_cql_statement( """ SELECT * FROM test3rf.test2 WHERE k = 1 """, consistency_level=ConsistencyLevel.ALL, expected_exception=ReadFailure) self._perform_cql_statement( """ DROP TABLE test3rf.test2; """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) def test_user_function_failure(self): """ Test to validate that exceptions in user defined function are correctly surfaced by the driver to us. test_user_function_failure First creates a table to use for testing. Then creates a function that will throw an exception when invoked. It then invokes the function and expects a FunctionException. Finally it preforms cleanup operations. @since 2.6.0 @jira_ticket PYTHON-238 @expected_result Function failures when UDF throws exception @test_category queries:basic """ # create UDF that throws an exception self._perform_cql_statement( """ CREATE FUNCTION test3rf.test_failure(d double) RETURNS NULL ON NULL INPUT RETURNS double LANGUAGE java AS 'throw new RuntimeException("failure");'; """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) # Create test table self._perform_cql_statement( """ CREATE TABLE test3rf.d (k int PRIMARY KEY , d double); """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) # Insert some values self._perform_cql_statement( """ INSERT INTO test3rf.d (k,d) VALUES (0, 5.12); """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) # Run the function expect a function failure exception self._perform_cql_statement( """ SELECT test_failure(d) FROM test3rf.d WHERE k = 0; """, consistency_level=ConsistencyLevel.ALL, expected_exception=FunctionFailure) self._perform_cql_statement( """ DROP FUNCTION test3rf.test_failure; """, consistency_level=ConsistencyLevel.ALL, expected_exception=None) self._perform_cql_statement( """ DROP TABLE test3rf.d; """, consistency_level=ConsistencyLevel.ALL, expected_exception=None)
class SerialConsistencyTests(unittest.TestCase): def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect() def tearDown(self): self.cluster.shutdown() def test_conditional_update(self): self.session.execute("INSERT INTO test3rf.test (k, v) VALUES (0, 0)") statement = SimpleStatement( "UPDATE test3rf.test SET v=1 WHERE k=0 IF v=1", serial_consistency_level=ConsistencyLevel.SERIAL) # crazy test, but PYTHON-299 # TODO: expand to check more parameters get passed to statement, and on to messages self.assertEqual(statement.serial_consistency_level, ConsistencyLevel.SERIAL) future = self.session.execute_async(statement) result = future.result() self.assertEqual(future.message.serial_consistency_level, ConsistencyLevel.SERIAL) self.assertTrue(result) self.assertFalse(result[0].applied) statement = SimpleStatement( "UPDATE test3rf.test SET v=1 WHERE k=0 IF v=0", serial_consistency_level=ConsistencyLevel.LOCAL_SERIAL) self.assertEqual(statement.serial_consistency_level, ConsistencyLevel.LOCAL_SERIAL) future = self.session.execute_async(statement) result = future.result() self.assertEqual(future.message.serial_consistency_level, ConsistencyLevel.LOCAL_SERIAL) self.assertTrue(result) self.assertTrue(result[0].applied) def test_conditional_update_with_prepared_statements(self): self.session.execute("INSERT INTO test3rf.test (k, v) VALUES (0, 0)") statement = self.session.prepare( "UPDATE test3rf.test SET v=1 WHERE k=0 IF v=2") statement.serial_consistency_level = ConsistencyLevel.SERIAL future = self.session.execute_async(statement) result = future.result() self.assertEqual(future.message.serial_consistency_level, ConsistencyLevel.SERIAL) self.assertTrue(result) self.assertFalse(result[0].applied) statement = self.session.prepare( "UPDATE test3rf.test SET v=1 WHERE k=0 IF v=0") bound = statement.bind(()) bound.serial_consistency_level = ConsistencyLevel.LOCAL_SERIAL future = self.session.execute_async(bound) result = future.result() self.assertEqual(future.message.serial_consistency_level, ConsistencyLevel.LOCAL_SERIAL) self.assertTrue(result) self.assertTrue(result[0].applied) def test_conditional_update_with_batch_statements(self): self.session.execute("INSERT INTO test3rf.test (k, v) VALUES (0, 0)") statement = BatchStatement( serial_consistency_level=ConsistencyLevel.SERIAL) statement.add("UPDATE test3rf.test SET v=1 WHERE k=0 IF v=1") self.assertEqual(statement.serial_consistency_level, ConsistencyLevel.SERIAL) future = self.session.execute_async(statement) result = future.result() self.assertEqual(future.message.serial_consistency_level, ConsistencyLevel.SERIAL) self.assertTrue(result) self.assertFalse(result[0].applied) statement = BatchStatement( serial_consistency_level=ConsistencyLevel.LOCAL_SERIAL) statement.add("UPDATE test3rf.test SET v=1 WHERE k=0 IF v=0") self.assertEqual(statement.serial_consistency_level, ConsistencyLevel.LOCAL_SERIAL) future = self.session.execute_async(statement) result = future.result() self.assertEqual(future.message.serial_consistency_level, ConsistencyLevel.LOCAL_SERIAL) self.assertTrue(result) self.assertTrue(result[0].applied) def test_bad_consistency_level(self): statement = SimpleStatement("foo") self.assertRaises(ValueError, setattr, statement, 'serial_consistency_level', ConsistencyLevel.ONE) self.assertRaises(ValueError, SimpleStatement, 'foo', serial_consistency_level=ConsistencyLevel.ONE)
def readStream(targetCluster): coordinator = dc last_c = coordinator used_dc = dc current = time.localtime() bucket = str(current.tm_year) + str(current.tm_mon) + str( current.tm_mday) + str(current.tm_hour) + str(current.tm_min) profile1 = ExecutionProfile( load_balancing_policy=DCAwareRoundRobinPolicy( local_dc=dc, used_hosts_per_remote_dc=3), speculative_execution_policy=ConstantSpeculativeExecutionPolicy( .05, 20), consistency_level=CL) print("Connecting to cluster") if (targetCluster == "DDAC"): contactpoints = ddaccontactpoints else: contactpoints = osscontactpoints cluster = Cluster( contact_points=contactpoints, auth_provider=auth_provider, ssl_options=ssl_opts, execution_profiles={EXEC_PROFILE_DEFAULT: profile1}, ) session = cluster.connect() x = 0 y = 0 while x <= count: r = {} #Results Dictionary current = time.localtime() bucket = str(current.tm_year) + str(current.tm_mon) + str( current.tm_mday) + str(current.tm_hour) + str(current.tm_min) #r["d"] = time.strftime('%Y-%m-%dT%H:%M:%S', current) query = """ select * from demo.table2 where bucket = '%s' limit 1 """ % ( bucket) readfail = 0 r["result"] = "Successful" try: results = session.execute(query) except Exception as e: print("Read failed.") readfail = 1 for i in e: errormsg = i errormsg = str(errormsg).replace('"', '') r["count"] = x r["dc"] = used_dc r["result"] = errormsg r["d"] = "00:00:00" yield json.dumps(r) + "\r\n" if readfail == 1: cluster.shutdown() return yield for row in results: r["d"] = row.d if (y == rowcount): y = 0 try: future = session.execute_async(query, trace=True) result = future.result() try: trace = future.get_query_trace(1) coordinator = trace.coordinator except: coordinator = last_c for h in session.hosts: if h.address == coordinator: used_dc = h.datacenter r["count"] = x r["dc"] = used_dc yield json.dumps(r) + "\r\n" except Exception as e: for i in e: errormsg = i errormsg = str(errormsg).replace('"', '') print("Read trace failed.") r["count"] = x r["dc"] = used_dc r["result"] = errormsg yield json.dumps(r) + "\r\n" cluster.shutdown() time.sleep(.03) # an artificial delay x = x + 1 y = y + 1 cluster.shutdown()
contact_points=osscontactpoints, auth_provider=auth_provider, ssl_options=ssl_opts, execution_profiles={EXEC_PROFILE_DEFAULT: profile2}, ) ddacSession = ddacCluster.connect() ossSession = ossCluster.connect() print("Connected to cluster") ddacSession.execute(ks_query) ddacSession.execute( """ CREATE TABLE IF NOT EXISTS demo.table2 ( bucket text, ts timeuuid, d text, data1 text, data2 text, data3 text, PRIMARY KEY (bucket, ts)) WITH CLUSTERING ORDER BY (ts desc) """ ) ddacCluster.shutdown() ossSession.execute(ks_query) ossSession.execute( """ CREATE TABLE IF NOT EXISTS demo.table2 ( bucket text, ts timeuuid, d text, data1 text, data2 text, data3 text, PRIMARY KEY (bucket, ts)) WITH CLUSTERING ORDER BY (ts desc) """ ) ossCluster.shutdown() #API Endpoints Below #>>>>>>>>>>>>>>>>>>>>>>>INIT @app.route('/') def index(): return "Ping? Pong!"
class ConnectionTest(BaseCassEngTestCase): @classmethod def setUpClass(cls): connection.unregister_connection('default') cls.keyspace1 = 'ctest1' cls.keyspace2 = 'ctest2' super(ConnectionTest, cls).setUpClass() cls.setup_cluster = Cluster(protocol_version=PROTOCOL_VERSION) cls.setup_session = cls.setup_cluster.connect() ddl = "CREATE KEYSPACE {0} WITH replication = {{'class': 'SimpleStrategy', 'replication_factor': '{1}'}}".format( cls.keyspace1, 1) execute_with_long_wait_retry(cls.setup_session, ddl) ddl = "CREATE KEYSPACE {0} WITH replication = {{'class': 'SimpleStrategy', 'replication_factor': '{1}'}}".format( cls.keyspace2, 1) execute_with_long_wait_retry(cls.setup_session, ddl) @classmethod def tearDownClass(cls): execute_with_long_wait_retry(cls.setup_session, "DROP KEYSPACE {0}".format(cls.keyspace1)) execute_with_long_wait_retry(cls.setup_session, "DROP KEYSPACE {0}".format(cls.keyspace2)) models.DEFAULT_KEYSPACE = DEFAULT_KEYSPACE cls.setup_cluster.shutdown() setup_connection(DEFAULT_KEYSPACE) models.DEFAULT_KEYSPACE def setUp(self): self.c = Cluster(protocol_version=PROTOCOL_VERSION, execution_profiles={ EXEC_PROFILE_DEFAULT: ExecutionProfile(row_factory=dict_factory) }) self.session1 = self.c.connect(keyspace=self.keyspace1) self.session2 = self.c.connect(keyspace=self.keyspace2) def tearDown(self): self.c.shutdown() def test_connection_session_switch(self): """ Test to ensure that when the default keyspace is changed in a session and that session, is set in the connection class, that the new defaul keyspace is honored. @since 3.1 @jira_ticket PYTHON-486 @expected_result CQLENGINE adopts whatever keyspace is passed in vai the set_session method as default @test_category object_mapper """ connection.set_session(self.session1) sync_table(TestConnectModel) TCM1 = TestConnectModel.create(id=1, keyspace=self.keyspace1) connection.set_session(self.session2) sync_table(TestConnectModel) TCM2 = TestConnectModel.create(id=1, keyspace=self.keyspace2) connection.set_session(self.session1) self.assertEqual(1, TestConnectModel.objects.count()) self.assertEqual(TestConnectModel.objects.first(), TCM1) connection.set_session(self.session2) self.assertEqual(1, TestConnectModel.objects.count()) self.assertEqual(TestConnectModel.objects.first(), TCM2) @local def test_connection_setup_with_setup(self): connection.setup(hosts=None, default_keyspace=None) self.assertIsNotNone( connection.get_connection("default").cluster.metadata.get_host( "127.0.0.1")) @local def test_connection_setup_with_default(self): connection.default() self.assertIsNotNone( connection.get_connection("default").cluster.metadata.get_host( "127.0.0.1"))
class ControlConnectionTests(unittest.TestCase): def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) def tearDown(self): try: self.session.execute("DROP KEYSPACE keyspacetodrop ") except (ConfigurationException): # we already removed the keyspace. pass self.cluster.shutdown() def test_drop_keyspace(self): """ Test to validate that dropping a keyspace with user defined types doesn't kill the control connection. Creates a keyspace, and populates with a user defined type. It then records the control_connection's id. It will then drop the keyspace and get the id of the control_connection again. They should be the same. If they are not dropping the keyspace likely caused the control connection to be rebuilt. @since 2.7.0 @jira_ticket PYTHON-358 @expected_result the control connection is not killed @test_category connection """ self.session = self.cluster.connect() self.session.execute(""" CREATE KEYSPACE keyspacetodrop WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor': '1' } """) self.session.set_keyspace("keyspacetodrop") self.session.execute("CREATE TYPE user (age int, name text)") self.session.execute( "CREATE TABLE mytable (a int PRIMARY KEY, b frozen<user>)") cc_id_pre_drop = id(self.cluster.control_connection._connection) self.session.execute("DROP KEYSPACE keyspacetodrop") cc_id_post_drop = id(self.cluster.control_connection._connection) self.assertEqual(cc_id_post_drop, cc_id_pre_drop) def test_get_control_connection_host(self): """ Test to validate Cluster.get_control_connection_host() metadata @since 3.5.0 @jira_ticket PYTHON-583 @expected_result the control connection metadata should accurately reflect cluster state. @test_category metadata """ host = self.cluster.get_control_connection_host() self.assertEqual(host, None) self.session = self.cluster.connect() cc_host = self.cluster.control_connection._connection.host host = self.cluster.get_control_connection_host() self.assertEqual(host.address, cc_host) self.assertEqual(host.is_up, True) # reconnect and make sure that the new host is reflected correctly self.cluster.control_connection._reconnect() new_host = self.cluster.get_control_connection_host() self.assertNotEqual(host, new_host)
class MetricsTests(unittest.TestCase): def setUp(self): contact_point = ['127.0.0.2'] self.cluster = Cluster( contact_points=contact_point, metrics_enabled=True, protocol_version=PROTOCOL_VERSION, execution_profiles={ EXEC_PROFILE_DEFAULT: ExecutionProfile( load_balancing_policy=WhiteListRoundRobinPolicy( contact_point), retry_policy=FallthroughRetryPolicy()) }) self.session = self.cluster.connect("test3rf", wait_for_all_pools=True) def tearDown(self): self.cluster.shutdown() def test_connection_error(self): """ Trigger and ensure connection_errors are counted Stop all node with the driver knowing about the "DOWN" states. """ # Test writes for i in range(0, 100): self.session.execute_async( "INSERT INTO test (k, v) VALUES ({0}, {1})".format(i, i)) # Stop the cluster get_cluster().stop(wait=True, gently=False) try: # Ensure the nodes are actually down query = SimpleStatement("SELECT * FROM test", consistency_level=ConsistencyLevel.ALL) with self.assertRaises(NoHostAvailable): self.session.execute(query) finally: get_cluster().start(wait_for_binary_proto=True, wait_other_notice=True) # Give some time for the cluster to come back up, for the next test time.sleep(5) self.assertGreater(self.cluster.metrics.stats.connection_errors, 0) def test_write_timeout(self): """ Trigger and ensure write_timeouts are counted Write a key, value pair. Pause a node without the coordinator node knowing about the "DOWN" state. Attempt a write at cl.ALL and receive a WriteTimeout. """ # Test write self.session.execute("INSERT INTO test (k, v) VALUES (1, 1)") # Assert read query = SimpleStatement("SELECT * FROM test WHERE k=1", consistency_level=ConsistencyLevel.ALL) results = execute_until_pass(self.session, query) self.assertTrue(results) # Pause node so it shows as unreachable to coordinator get_node(1).pause() try: # Test write query = SimpleStatement("INSERT INTO test (k, v) VALUES (2, 2)", consistency_level=ConsistencyLevel.ALL) with self.assertRaises(WriteTimeout): self.session.execute(query, timeout=None) self.assertEqual(1, self.cluster.metrics.stats.write_timeouts) finally: get_node(1).resume() def test_read_timeout(self): """ Trigger and ensure read_timeouts are counted Write a key, value pair. Pause a node without the coordinator node knowing about the "DOWN" state. Attempt a read at cl.ALL and receive a ReadTimeout. """ # Test write self.session.execute("INSERT INTO test (k, v) VALUES (1, 1)") # Assert read query = SimpleStatement("SELECT * FROM test WHERE k=1", consistency_level=ConsistencyLevel.ALL) results = execute_until_pass(self.session, query) self.assertTrue(results) # Pause node so it shows as unreachable to coordinator get_node(1).pause() try: # Test read query = SimpleStatement("SELECT * FROM test", consistency_level=ConsistencyLevel.ALL) with self.assertRaises(ReadTimeout): self.session.execute(query, timeout=None) self.assertEqual(1, self.cluster.metrics.stats.read_timeouts) finally: get_node(1).resume() def test_unavailable(self): """ Trigger and ensure unavailables are counted Write a key, value pair. Stop a node with the coordinator node knowing about the "DOWN" state. Attempt an insert/read at cl.ALL and receive a Unavailable Exception. """ # Test write self.session.execute("INSERT INTO test (k, v) VALUES (1, 1)") # Assert read query = SimpleStatement("SELECT * FROM test WHERE k=1", consistency_level=ConsistencyLevel.ALL) results = execute_until_pass(self.session, query) self.assertTrue(results) # Stop node gracefully # Sometimes this commands continues with the other nodes having not noticed # 1 is down, and a Timeout error is returned instead of an Unavailable get_node(1).stop(wait=True, wait_other_notice=True) try: # Test write query = SimpleStatement("INSERT INTO test (k, v) VALUES (2, 2)", consistency_level=ConsistencyLevel.ALL) with self.assertRaises(Unavailable): self.session.execute(query) self.assertEqual(self.cluster.metrics.stats.unavailables, 1) # Test write query = SimpleStatement("SELECT * FROM test", consistency_level=ConsistencyLevel.ALL) with self.assertRaises(Unavailable): self.session.execute(query, timeout=None) self.assertEqual(self.cluster.metrics.stats.unavailables, 2) finally: get_node(1).start(wait_other_notice=True, wait_for_binary_proto=True) # Give some time for the cluster to come back up, for the next test time.sleep(5) self.cluster.shutdown()
def test_metrics_per_cluster(self): """ Test to validate that metrics can be scopped to invdividual clusters @since 3.6.0 @jira_ticket PYTHON-561 @expected_result metrics should be scopped to a cluster level @test_category metrics """ cluster2 = Cluster( metrics_enabled=True, protocol_version=PROTOCOL_VERSION, execution_profiles={ EXEC_PROFILE_DEFAULT: ExecutionProfile(retry_policy=FallthroughRetryPolicy()) }) cluster2.connect(self.ks_name, wait_for_all_pools=True) query = SimpleStatement("SELECT * FROM {0}.{0}".format(self.ks_name), consistency_level=ConsistencyLevel.ALL) self.session.execute(query) # Pause node so it shows as unreachable to coordinator get_node(1).pause() try: # Test write query = SimpleStatement( "INSERT INTO {0}.{0} (k, v) VALUES (2, 2)".format( self.ks_name), consistency_level=ConsistencyLevel.ALL) with self.assertRaises(WriteTimeout): self.session.execute(query, timeout=None) finally: get_node(1).resume() # Change the scales stats_name of the cluster2 cluster2.metrics.set_stats_name('cluster2-metrics') stats_cluster1 = self.cluster.metrics.get_stats() stats_cluster2 = cluster2.metrics.get_stats() # Test direct access to stats self.assertEqual(1, self.cluster.metrics.stats.write_timeouts) self.assertEqual(0, cluster2.metrics.stats.write_timeouts) # Test direct access to a child stats self.assertNotEqual(0.0, self.cluster.metrics.request_timer['mean']) self.assertEqual(0.0, cluster2.metrics.request_timer['mean']) # Test access via metrics.get_stats() self.assertNotEqual(0.0, stats_cluster1['request_timer']['mean']) self.assertEqual(0.0, stats_cluster2['request_timer']['mean']) # Test access by stats_name self.assertEqual( 0.0, scales.getStats()['cluster2-metrics']['request_timer']['mean']) cluster2.shutdown()
class PreparedStatementTests(unittest.TestCase): def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect() def tearDown(self): self.cluster.shutdown() def test_routing_key(self): """ Simple code coverage to ensure routing_keys can be accessed """ prepared = self.session.prepare(""" INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1, None)) self.assertEqual(bound.routing_key, b'\x00\x00\x00\x01') def test_empty_routing_key_indexes(self): """ Ensure when routing_key_indexes are blank, the routing key should be None """ prepared = self.session.prepare(""" INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) prepared.routing_key_indexes = None self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1, None)) self.assertEqual(bound.routing_key, None) def test_predefined_routing_key(self): """ Basic test that ensures _set_routing_key() overrides the current routing key """ prepared = self.session.prepare(""" INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1, None)) bound._set_routing_key('fake_key') self.assertEqual(bound.routing_key, 'fake_key') def test_multiple_routing_key_indexes(self): """ Basic test that uses a fake routing_key_index """ prepared = self.session.prepare(""" INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) prepared.routing_key_indexes = [0, 1] bound = prepared.bind((1, 2)) self.assertEqual( bound.routing_key, b'\x00\x04\x00\x00\x00\x01\x00\x00\x04\x00\x00\x00\x02\x00') prepared.routing_key_indexes = [1, 0] bound = prepared.bind((1, 2)) self.assertEqual( bound.routing_key, b'\x00\x04\x00\x00\x00\x02\x00\x00\x04\x00\x00\x00\x01\x00') def test_bound_keyspace(self): """ Ensure that bound.keyspace works as expected """ prepared = self.session.prepare(""" INSERT INTO test3rf.test (k, v) VALUES (?, ?) """) self.assertIsInstance(prepared, PreparedStatement) bound = prepared.bind((1, 2)) self.assertEqual(bound.keyspace, 'test3rf')
class BatchStatementTests(BasicSharedKeyspaceUnitTestCase): def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect(wait_for_all_pools=True) def tearDown(self): self.cluster.shutdown() def confirm_results(self): keys = set() values = set() # Assuming the test data is inserted at default CL.ONE, we need ALL here to guarantee we see # everything inserted results = self.session.execute( SimpleStatement("SELECT * FROM test3rf.test", consistency_level=ConsistencyLevel.ALL)) for result in results: keys.add(result.k) values.add(result.v) self.assertEqual(set(range(10)), keys, msg=results) self.assertEqual(set(range(10)), values, msg=results) def test_string_statements(self): batch = BatchStatement(BatchType.LOGGED) for i in range(10): batch.add("INSERT INTO test3rf.test (k, v) VALUES (%s, %s)", (i, i)) self.session.execute(batch) self.session.execute_async(batch).result() self.confirm_results() def test_simple_statements(self): batch = BatchStatement(BatchType.LOGGED) for i in range(10): batch.add( SimpleStatement( "INSERT INTO test3rf.test (k, v) VALUES (%s, %s)"), (i, i)) self.session.execute(batch) self.session.execute_async(batch).result() self.confirm_results() def test_prepared_statements(self): prepared = self.session.prepare( "INSERT INTO test3rf.test (k, v) VALUES (?, ?)") batch = BatchStatement(BatchType.LOGGED) for i in range(10): batch.add(prepared, (i, i)) self.session.execute(batch) self.session.execute_async(batch).result() self.confirm_results() def test_bound_statements(self): prepared = self.session.prepare( "INSERT INTO test3rf.test (k, v) VALUES (?, ?)") batch = BatchStatement(BatchType.LOGGED) for i in range(10): batch.add(prepared.bind((i, i))) self.session.execute(batch) self.session.execute_async(batch).result() self.confirm_results() def test_no_parameters(self): batch = BatchStatement(BatchType.LOGGED) batch.add("INSERT INTO test3rf.test (k, v) VALUES (0, 0)") batch.add("INSERT INTO test3rf.test (k, v) VALUES (1, 1)", ()) batch.add( SimpleStatement("INSERT INTO test3rf.test (k, v) VALUES (2, 2)")) batch.add( SimpleStatement("INSERT INTO test3rf.test (k, v) VALUES (3, 3)"), ()) prepared = self.session.prepare( "INSERT INTO test3rf.test (k, v) VALUES (4, 4)") batch.add(prepared) batch.add(prepared, ()) batch.add(prepared.bind([])) batch.add(prepared.bind([]), ()) batch.add("INSERT INTO test3rf.test (k, v) VALUES (5, 5)", ()) batch.add("INSERT INTO test3rf.test (k, v) VALUES (6, 6)", ()) batch.add("INSERT INTO test3rf.test (k, v) VALUES (7, 7)", ()) batch.add("INSERT INTO test3rf.test (k, v) VALUES (8, 8)", ()) batch.add("INSERT INTO test3rf.test (k, v) VALUES (9, 9)", ()) self.assertRaises(ValueError, batch.add, prepared.bind([]), (1)) self.assertRaises(ValueError, batch.add, prepared.bind([]), (1, 2)) self.assertRaises(ValueError, batch.add, prepared.bind([]), (1, 2, 3)) self.session.execute(batch) self.confirm_results() def test_unicode(self): ddl = ''' CREATE TABLE test3rf.testtext ( k int PRIMARY KEY, v text )''' self.session.execute(ddl) unicode_text = u'Fran\u00E7ois' query = u'INSERT INTO test3rf.testtext (k, v) VALUES (%s, %s)' try: batch = BatchStatement(BatchType.LOGGED) batch.add(u"INSERT INTO test3rf.testtext (k, v) VALUES (%s, %s)", (0, unicode_text)) self.session.execute(batch) finally: self.session.execute("DROP TABLE test3rf.testtext") def test_too_many_statements(self): # The actual max # of statements is 0xFFFF, but this can occasionally cause a server write timeout. large_batch = 0xFFF max_statements = 0xFFFF ss = SimpleStatement("INSERT INTO test3rf.test (k, v) VALUES (0, 0)") b = BatchStatement(batch_type=BatchType.UNLOGGED, consistency_level=ConsistencyLevel.ONE) # large number works works b.add_all([ss] * large_batch, [None] * large_batch) self.session.execute(b, timeout=30.0) b = BatchStatement(batch_type=BatchType.UNLOGGED, consistency_level=ConsistencyLevel.ONE) # max + 1 raises b.add_all([ss] * max_statements, [None] * max_statements) self.assertRaises(ValueError, b.add, ss) # also would have bombed trying to encode b._statements_and_parameters.append((False, ss.query_string, ())) self.assertRaises(NoHostAvailable, self.session.execute, b)
class QueryPagingTests(unittest.TestCase): def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect(wait_for_all_pools=True) self.session.execute("TRUNCATE test3rf.test") def tearDown(self): self.cluster.shutdown() def test_paging(self): statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, list(statements_and_params)) prepared = self.session.prepare("SELECT * FROM test3rf.test") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size self.assertEqual(100, len(list(self.session.execute("SELECT * FROM test3rf.test")))) statement = SimpleStatement("SELECT * FROM test3rf.test") self.assertEqual(100, len(list(self.session.execute(statement)))) self.assertEqual(100, len(list(self.session.execute(prepared)))) def test_paging_state(self): """ Test to validate paging state api @since 3.7.0 @jira_ticket PYTHON-200 @expected_result paging state should returned should be accurate, and allow for queries to be resumed. @test_category queries """ statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, list(statements_and_params)) list_all_results = [] self.session.default_fetch_size = 3 result_set = self.session.execute("SELECT * FROM test3rf.test") while(result_set.has_more_pages): for row in result_set.current_rows: self.assertNotIn(row, list_all_results) list_all_results.extend(result_set.current_rows) page_state = result_set.paging_state result_set = self.session.execute("SELECT * FROM test3rf.test", paging_state=page_state) if(len(result_set.current_rows) > 0): list_all_results.append(result_set.current_rows) self.assertEqual(len(list_all_results), 100) def test_paging_verify_writes(self): statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, statements_and_params) prepared = self.session.prepare("SELECT * FROM test3rf.test") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size results = self.session.execute("SELECT * FROM test3rf.test") result_array = set() result_set = set() for result in results: result_array.add(result.k) result_set.add(result.v) self.assertEqual(set(range(100)), result_array) self.assertEqual(set([0]), result_set) statement = SimpleStatement("SELECT * FROM test3rf.test") results = self.session.execute(statement) result_array = set() result_set = set() for result in results: result_array.add(result.k) result_set.add(result.v) self.assertEqual(set(range(100)), result_array) self.assertEqual(set([0]), result_set) results = self.session.execute(prepared) result_array = set() result_set = set() for result in results: result_array.add(result.k) result_set.add(result.v) self.assertEqual(set(range(100)), result_array) self.assertEqual(set([0]), result_set) def test_paging_verify_with_composite_keys(self): ddl = ''' CREATE TABLE test3rf.test_paging_verify_2 ( k1 int, k2 int, v int, PRIMARY KEY(k1, k2) )''' self.session.execute(ddl) statements_and_params = zip(cycle(["INSERT INTO test3rf.test_paging_verify_2 " "(k1, k2, v) VALUES (0, %s, %s)"]), [(i, i + 1) for i in range(100)]) execute_concurrent(self.session, statements_and_params) prepared = self.session.prepare("SELECT * FROM test3rf.test_paging_verify_2") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size results = self.session.execute("SELECT * FROM test3rf.test_paging_verify_2") result_array = [] value_array = [] for result in results: result_array.append(result.k2) value_array.append(result.v) self.assertSequenceEqual(range(100), result_array) self.assertSequenceEqual(range(1, 101), value_array) statement = SimpleStatement("SELECT * FROM test3rf.test_paging_verify_2") results = self.session.execute(statement) result_array = [] value_array = [] for result in results: result_array.append(result.k2) value_array.append(result.v) self.assertSequenceEqual(range(100), result_array) self.assertSequenceEqual(range(1, 101), value_array) results = self.session.execute(prepared) result_array = [] value_array = [] for result in results: result_array.append(result.k2) value_array.append(result.v) self.assertSequenceEqual(range(100), result_array) self.assertSequenceEqual(range(1, 101), value_array) def test_async_paging(self): statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, list(statements_and_params)) prepared = self.session.prepare("SELECT * FROM test3rf.test") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size self.assertEqual(100, len(list(self.session.execute_async("SELECT * FROM test3rf.test").result()))) statement = SimpleStatement("SELECT * FROM test3rf.test") self.assertEqual(100, len(list(self.session.execute_async(statement).result()))) self.assertEqual(100, len(list(self.session.execute_async(prepared).result()))) def test_async_paging_verify_writes(self): ddl = ''' CREATE TABLE test3rf.test_async_paging_verify ( k1 int, k2 int, v int, PRIMARY KEY(k1, k2) )''' self.session.execute(ddl) statements_and_params = zip(cycle(["INSERT INTO test3rf.test_async_paging_verify " "(k1, k2, v) VALUES (0, %s, %s)"]), [(i, i + 1) for i in range(100)]) execute_concurrent(self.session, statements_and_params) prepared = self.session.prepare("SELECT * FROM test3rf.test_async_paging_verify") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size results = self.session.execute_async("SELECT * FROM test3rf.test_async_paging_verify").result() result_array = [] value_array = [] for result in results: result_array.append(result.k2) value_array.append(result.v) self.assertSequenceEqual(range(100), result_array) self.assertSequenceEqual(range(1, 101), value_array) statement = SimpleStatement("SELECT * FROM test3rf.test_async_paging_verify") results = self.session.execute_async(statement).result() result_array = [] value_array = [] for result in results: result_array.append(result.k2) value_array.append(result.v) self.assertSequenceEqual(range(100), result_array) self.assertSequenceEqual(range(1, 101), value_array) results = self.session.execute_async(prepared).result() result_array = [] value_array = [] for result in results: result_array.append(result.k2) value_array.append(result.v) self.assertSequenceEqual(range(100), result_array) self.assertSequenceEqual(range(1, 101), value_array) def test_paging_callbacks(self): """ Test to validate callback api @since 3.9.0 @jira_ticket PYTHON-733 @expected_result callbacks shouldn't be called twice per message and the fetch_size should be handled in a transparent way to the user @test_category queries """ statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, list(statements_and_params)) prepared = self.session.prepare("SELECT * FROM test3rf.test") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size future = self.session.execute_async("SELECT * FROM test3rf.test", timeout=20) event = Event() counter = count() number_of_calls = count() def handle_page(rows, future, counter, number_of_calls): next(number_of_calls) for row in rows: next(counter) if future.has_more_pages: future.start_fetching_next_page() else: event.set() def handle_error(err): event.set() self.fail(err) future.add_callbacks(callback=handle_page, callback_args=(future, counter, number_of_calls), errback=handle_error) event.wait() self.assertEqual(next(number_of_calls), 100 // fetch_size + 1) self.assertEqual(next(counter), 100) # simple statement future = self.session.execute_async(SimpleStatement("SELECT * FROM test3rf.test"), timeout=20) event.clear() counter = count() number_of_calls = count() future.add_callbacks(callback=handle_page, callback_args=(future, counter, number_of_calls), errback=handle_error) event.wait() self.assertEqual(next(number_of_calls), 100 // fetch_size + 1) self.assertEqual(next(counter), 100) # prepared statement future = self.session.execute_async(prepared, timeout=20) event.clear() counter = count() number_of_calls = count() future.add_callbacks(callback=handle_page, callback_args=(future, counter, number_of_calls), errback=handle_error) event.wait() self.assertEqual(next(number_of_calls), 100 // fetch_size + 1) self.assertEqual(next(counter), 100) def test_concurrent_with_paging(self): statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, list(statements_and_params)) prepared = self.session.prepare("SELECT * FROM test3rf.test") for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000): self.session.default_fetch_size = fetch_size results = execute_concurrent_with_args(self.session, prepared, [None] * 10) self.assertEqual(10, len(results)) for (success, result) in results: self.assertTrue(success) self.assertEqual(100, len(list(result))) def test_fetch_size(self): """ Ensure per-statement fetch_sizes override the default fetch size. """ statements_and_params = zip(cycle(["INSERT INTO test3rf.test (k, v) VALUES (%s, 0)"]), [(i, ) for i in range(100)]) execute_concurrent(self.session, list(statements_and_params)) prepared = self.session.prepare("SELECT * FROM test3rf.test") self.session.default_fetch_size = 10 result = self.session.execute(prepared, []) self.assertTrue(result.has_more_pages) self.session.default_fetch_size = 2000 result = self.session.execute(prepared, []) self.assertFalse(result.has_more_pages) self.session.default_fetch_size = None result = self.session.execute(prepared, []) self.assertFalse(result.has_more_pages) self.session.default_fetch_size = 10 prepared.fetch_size = 2000 result = self.session.execute(prepared, []) self.assertFalse(result.has_more_pages) prepared.fetch_size = None result = self.session.execute(prepared, []) self.assertFalse(result.has_more_pages) prepared.fetch_size = 10 result = self.session.execute(prepared, []) self.assertTrue(result.has_more_pages) prepared.fetch_size = 2000 bound = prepared.bind([]) result = self.session.execute(bound, []) self.assertFalse(result.has_more_pages) prepared.fetch_size = None bound = prepared.bind([]) result = self.session.execute(bound, []) self.assertFalse(result.has_more_pages) prepared.fetch_size = 10 bound = prepared.bind([]) result = self.session.execute(bound, []) self.assertTrue(result.has_more_pages) bound.fetch_size = 2000 result = self.session.execute(bound, []) self.assertFalse(result.has_more_pages) bound.fetch_size = None result = self.session.execute(bound, []) self.assertFalse(result.has_more_pages) bound.fetch_size = 10 result = self.session.execute(bound, []) self.assertTrue(result.has_more_pages) s = SimpleStatement("SELECT * FROM test3rf.test", fetch_size=None) result = self.session.execute(s, []) self.assertFalse(result.has_more_pages) s = SimpleStatement("SELECT * FROM test3rf.test") result = self.session.execute(s, []) self.assertTrue(result.has_more_pages) s = SimpleStatement("SELECT * FROM test3rf.test") s.fetch_size = None result = self.session.execute(s, []) self.assertFalse(result.has_more_pages)
class LightweightTransactionTests(unittest.TestCase): def setUp(self): self.cluster = Cluster(protocol_version=PROTOCOL_VERSION) self.session = self.cluster.connect() ddl = ''' CREATE TABLE test3rf.lwt ( k int PRIMARY KEY, v int )''' self.session.execute(ddl) def tearDown(self): """ Shutdown cluster """ self.session.execute("DROP TABLE test3rf.lwt") self.cluster.shutdown() def test_no_connection_refused_on_timeout(self): """ Test for PYTHON-91 "Connection closed after LWT timeout" Verifies that connection to the cluster is not shut down when timeout occurs. Number of iterations can be specified with LWT_ITERATIONS environment variable. Default value is 1000 """ insert_statement = self.session.prepare( "INSERT INTO test3rf.lwt (k, v) VALUES (0, 0) IF NOT EXISTS") delete_statement = self.session.prepare( "DELETE FROM test3rf.lwt WHERE k = 0 IF EXISTS") iterations = int(os.getenv("LWT_ITERATIONS", 1000)) # Prepare series of parallel statements statements_and_params = [] for i in range(iterations): statements_and_params.append((insert_statement, ())) statements_and_params.append((delete_statement, ())) received_timeout = False results = execute_concurrent(self.session, statements_and_params, raise_on_first_error=False) for (success, result) in results: if success: continue else: # In this case result is an exception if type(result).__name__ == "NoHostAvailable": self.fail("PYTHON-91: Disconnected from Cassandra: %s" % result.message) if type(result).__name__ == "WriteTimeout": received_timeout = True continue if type(result).__name__ == "WriteFailure": received_timeout = True continue if type(result).__name__ == "ReadTimeout": continue if type(result).__name__ == "ReadFailure": continue self.fail("Unexpected exception %s: %s" % (type(result).__name__, result.message)) # Make sure test passed self.assertTrue(received_timeout)
def test_can_register_udt_before_connecting(self): """ Test the registration of UDTs before session creation """ c = Cluster(protocol_version=PROTOCOL_VERSION) s = c.connect(wait_for_all_pools=True) s.execute(""" CREATE KEYSPACE udt_test_register_before_connecting WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor': '1' } """) s.set_keyspace("udt_test_register_before_connecting") s.execute("CREATE TYPE user (age int, name text)") s.execute("CREATE TABLE mytable (a int PRIMARY KEY, b frozen<user>)") s.execute(""" CREATE KEYSPACE udt_test_register_before_connecting2 WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor': '1' } """) s.set_keyspace("udt_test_register_before_connecting2") s.execute("CREATE TYPE user (state text, is_cool boolean)") s.execute("CREATE TABLE mytable (a int PRIMARY KEY, b frozen<user>)") # now that types are defined, shutdown and re-create Cluster c.shutdown() c = Cluster(protocol_version=PROTOCOL_VERSION) User1 = namedtuple('user', ('age', 'name')) User2 = namedtuple('user', ('state', 'is_cool')) c.register_user_type("udt_test_register_before_connecting", "user", User1) c.register_user_type("udt_test_register_before_connecting2", "user", User2) s = c.connect(wait_for_all_pools=True) s.set_keyspace("udt_test_register_before_connecting") s.execute("INSERT INTO mytable (a, b) VALUES (%s, %s)", (0, User1(42, 'bob'))) result = s.execute("SELECT b FROM mytable WHERE a=0") row = result[0] self.assertEqual(42, row.b.age) self.assertEqual('bob', row.b.name) self.assertTrue(type(row.b) is User1) # use the same UDT name in a different keyspace s.set_keyspace("udt_test_register_before_connecting2") s.execute("INSERT INTO mytable (a, b) VALUES (%s, %s)", (0, User2('Texas', True))) result = s.execute("SELECT b FROM mytable WHERE a=0") row = result[0] self.assertEqual('Texas', row.b.state) self.assertEqual(True, row.b.is_cool) self.assertTrue(type(row.b) is User2) s.execute("DROP KEYSPACE udt_test_register_before_connecting") s.execute("DROP KEYSPACE udt_test_register_before_connecting2") c.shutdown()
def test_can_insert_udt_all_collection_datatypes(self): """ Test for inserting various types of COLLECTION_TYPES into UDT's """ c = Cluster(protocol_version=PROTOCOL_VERSION) s = c.connect(self.keyspace_name, wait_for_all_pools=True) # create UDT alpha_type_list = [] start_index = ord('a') for i, collection_type in enumerate(COLLECTION_TYPES): for j, datatype in enumerate(PRIMITIVE_DATATYPES_KEYS): if collection_type == "map": type_string = "{0}_{1} {2}<{3}, {3}>".format( chr(start_index + i), chr(start_index + j), collection_type, datatype) elif collection_type == "tuple": type_string = "{0}_{1} frozen<{2}<{3}>>".format( chr(start_index + i), chr(start_index + j), collection_type, datatype) else: type_string = "{0}_{1} {2}<{3}>".format( chr(start_index + i), chr(start_index + j), collection_type, datatype) alpha_type_list.append(type_string) s.execute(""" CREATE TYPE alldatatypes ({0}) """.format(', '.join(alpha_type_list))) s.execute( "CREATE TABLE mytable (a int PRIMARY KEY, b frozen<alldatatypes>)") # register UDT alphabet_list = [] for i in range(ord('a'), ord('a') + len(COLLECTION_TYPES)): for j in range(ord('a'), ord('a') + len(PRIMITIVE_DATATYPES_KEYS)): alphabet_list.append('{0}_{1}'.format(chr(i), chr(j))) Alldatatypes = namedtuple("alldatatypes", alphabet_list) c.register_user_type(self.keyspace_name, "alldatatypes", Alldatatypes) # insert UDT data params = [] for collection_type in COLLECTION_TYPES: for datatype in PRIMITIVE_DATATYPES_KEYS: params.append((get_collection_sample(collection_type, datatype))) insert = s.prepare("INSERT INTO mytable (a, b) VALUES (?, ?)") s.execute(insert, (0, Alldatatypes(*params))) # retrieve and verify data results = s.execute("SELECT * FROM mytable") row = results[0].b for expected, actual in zip(params, row): self.assertEqual(expected, actual) c.shutdown()
class TimeoutTimerTest(unittest.TestCase): def setUp(self): """ Setup sessions and pause node1 """ self.cluster = Cluster(protocol_version=PROTOCOL_VERSION, execution_profiles={EXEC_PROFILE_DEFAULT: ExecutionProfile( load_balancing_policy=HostFilterPolicy( RoundRobinPolicy(), lambda host: host.address == "127.0.0.1" ) ) } ) 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 tearDown(self): """ Shutdown cluster and resume node1 """ self.node_to_stop.resume() self.session.execute("DROP TABLE test3rf.timeout") self.cluster.shutdown() def test_async_timeouts(self): """ Test to validate that timeouts are honored Exercise the underlying timeouts, by attempting a query that will timeout. Ensure the default timeout is still honored. Make sure that user timeouts are also honored. @since 2.7.0 @jira_ticket PYTHON-108 @expected_result timeouts should be honored @test_category """ # Because node1 is stopped these statements will all timeout ss = SimpleStatement('SELECT * FROM test3rf.test', consistency_level=ConsistencyLevel.ALL) # Test with default timeout (should be 10) start_time = time.time() future = self.session.execute_async(ss) with self.assertRaises(OperationTimedOut): future.result() end_time = time.time() total_time = end_time-start_time expected_time = self.cluster.profile_manager.default.request_timeout # check timeout and ensure it's within a reasonable range self.assertAlmostEqual(expected_time, total_time, delta=.05) # Test with user defined timeout (Should be 1) expected_time = 1 start_time = time.time() future = self.session.execute_async(ss, timeout=expected_time) mock_callback = Mock(return_value=None) mock_errorback = Mock(return_value=None) future.add_callback(mock_callback) future.add_errback(mock_errorback) with self.assertRaises(OperationTimedOut): future.result() end_time = time.time() total_time = end_time-start_time # check timeout and ensure it's within a reasonable range self.assertAlmostEqual(expected_time, total_time, delta=.05) self.assertTrue(mock_errorback.called) self.assertFalse(mock_callback.called)