def test_replica_availability(self): """ @jira_ticket CASSANDRA-8640 Regression test for a bug (CASSANDRA-8640) that required all nodes to be available in order to run LWT queries, even if the query could complete correctly with quorum nodes available. """ session = self.prepare(nodes=3, rf=3) session.execute("CREATE TABLE test (k int PRIMARY KEY, v int)") session.execute("INSERT INTO test (k, v) VALUES (0, 0) IF NOT EXISTS") node1 = self.cluster.nodelist()[1] node2 = self.cluster.nodelist()[2] node2.stop() session.execute("INSERT INTO test (k, v) VALUES (1, 1) IF NOT EXISTS") node1.stop() assert_unavailable( session.execute, "INSERT INTO test (k, v) VALUES (2, 2) IF NOT EXISTS") node1.start(wait_for_binary_proto=True) session.execute("INSERT INTO test (k, v) VALUES (3, 3) IF NOT EXISTS") node2.start(wait_for_binary_proto=True) session.execute("INSERT INTO test (k, v) VALUES (4, 4) IF NOT EXISTS")
def _test_insert_query_from_node(self, session, dc_idx, rf_factors, num_nodes_alive, write_cl, read_cl, serial_cl=None, check_ret=True): """ Test availability for read and write via the session passed in as a parameter. """ self.log("Connected to %s for %s/%s/%s" % (session.cluster.contact_points, consistency_value_to_name(write_cl), consistency_value_to_name(read_cl), consistency_value_to_name(serial_cl))) start = 0 end = 100 age = 30 if self._should_succeed(write_cl, rf_factors, num_nodes_alive, dc_idx): for n in xrange(start, end): self.insert_user(session, n, age, write_cl, serial_cl) else: assert_unavailable(self.insert_user, session, end, age, write_cl, serial_cl) if self._should_succeed(read_cl, rf_factors, num_nodes_alive, dc_idx): for n in xrange(start, end): self.query_user(session, n, age, read_cl, check_ret) else: assert_unavailable(self.query_user, session, end, age, read_cl, check_ret)
def test_assertions(self): # assert_exception_test mock_session = Mock( ** {'execute.side_effect': AlreadyExists("Dummy exception message.")}) assert_exception(mock_session, "DUMMY QUERY", expected=AlreadyExists) # assert_unavailable_test mock_session = Mock(**{ 'execute.side_effect': Unavailable("Dummy Unavailabile message.") }) assert_unavailable(mock_session.execute) # assert_invalid_test mock_session = Mock(**{ 'execute.side_effect': InvalidRequest("Dummy InvalidRequest message.") }) assert_invalid(mock_session, "DUMMY QUERY") # assert_unauthorized_test mock_session = Mock(**{ 'execute.side_effect': Unauthorized("Dummy Unauthorized message.") }) assert_unauthorized(mock_session, "DUMMY QUERY", None) # assert_one_test mock_session = Mock() mock_session.execute = Mock(return_value=[[1, 1]]) assert_one(mock_session, "SELECT * FROM test", [1, 1]) # assert_none_test mock_session = Mock() mock_session.execute = Mock(return_value=[]) assert_none(mock_session, "SELECT * FROM test") # assert_all_test mock_session = Mock() mock_session.execute = Mock(return_value=[[i, i] for i in range(0, 10)]) assert_all(mock_session, "SELECT k, v FROM test", [[i, i] for i in range(0, 10)], ignore_order=True) # assert_almost_equal_test assert_almost_equal(1, 1.1, 1.2, 1.9, error=1.0) # assert_row_count_test mock_session = Mock() mock_session.execute = Mock(return_value=[[1]]) assert_row_count(mock_session, 'test', 1) # assert_length_equal_test check = [1, 2, 3, 4] assert_length_equal(check, 4)
def logged_batch_throws_uae_test(self): """ Test that logged batch throws UAE if there aren't enough live nodes """ session = self.prepare(nodes=3) [node.stop(wait_other_notice=True) for node in self.cluster.nodelist()[1:]] session.consistency_level = ConsistencyLevel.ONE assert_unavailable(session.execute, """ BEGIN BATCH INSERT INTO users (id, firstname, lastname) VALUES (0, 'Jack', 'Sparrow') INSERT INTO users (id, firstname, lastname) VALUES (1, 'Will', 'Turner') APPLY BATCH """)
def logged_batch_throws_uae_test(self): """ Test that logged batch throws UAE if there aren't enough live nodes """ session = self.prepare(nodes=3) [node.stop(wait_other_notice=True) for node in self.cluster.nodelist()[1:]] session.consistency_level = 'ONE' assert_unavailable(session.execute, """ BEGIN BATCH INSERT INTO users (id, firstname, lastname) VALUES (0, 'Jack', 'Sparrow') INSERT INTO users (id, firstname, lastname) VALUES (1, 'Will', 'Turner') APPLY BATCH """)
def ttl_is_respected_on_repair_test(self): """ Test that ttl is respected on repair """ self.prepare() self.session1.execute(""" ALTER KEYSPACE ks WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1}; """) self.session1.execute(""" INSERT INTO ttl_table (key, col1) VALUES (1, 1) USING TTL 5; """) self.session1.execute(""" INSERT INTO ttl_table (key, col1) VALUES (2, 2) USING TTL 1000; """) assert_all( self.session1, "SELECT * FROM ttl_table;", [[1, 1, None, None], [2, 2, None, None]] ) time.sleep(7) self.node1.stop() session2 = self.patient_exclusive_cql_connection(self.node2) session2.execute("USE ks;") assert_unavailable(session2.execute, "SELECT * FROM ttl_table;") self.node1.start(wait_for_binary_proto=True) self.session1 = self.patient_exclusive_cql_connection(self.node1) self.session1.execute("USE ks;") self.session1.execute(""" ALTER KEYSPACE ks WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 2}; """) self.node1.repair(['ks']) ttl_start = time.time() ttl_session1 = self.session1.execute('SELECT ttl(col1) FROM ttl_table;') self.node1.stop() assert_row_count(session2, 'ttl_table', 1) assert_all( session2, "SELECT * FROM ttl_table;", [[2, 2, None, None]] ) # Check that the TTL on both server are the same ttl_session2 = session2.execute('SELECT ttl(col1) FROM ttl_table;') ttl_session1 = ttl_session1[0][0] - (time.time() - ttl_start) assert_almost_equal(ttl_session1, ttl_session2[0][0], error=0.005)
def test_ttl_is_respected_on_repair(self): """ Test that ttl is respected on repair """ self.prepare() self.session1.execute(""" ALTER KEYSPACE ks WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1}; """) self.session1.execute(""" INSERT INTO ttl_table (key, col1) VALUES (1, 1) USING TTL 5; """) self.session1.execute(""" INSERT INTO ttl_table (key, col1) VALUES (2, 2) USING TTL 1000; """) assert_all( self.session1, "SELECT * FROM ttl_table;", [[1, 1, None, None], [2, 2, None, None]] ) time.sleep(7) self.node1.stop() session2 = self.patient_exclusive_cql_connection(self.node2) session2.execute("USE ks;") assert_unavailable(session2.execute, "SELECT * FROM ttl_table;") self.node1.start(wait_for_binary_proto=True) self.session1 = self.patient_exclusive_cql_connection(self.node1) self.session1.execute("USE ks;") self.session1.execute(""" ALTER KEYSPACE ks WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 2}; """) self.node1.repair(['ks']) ttl_start = time.time() ttl_session1 = self.session1.execute('SELECT ttl(col1) FROM ttl_table;') self.node1.stop() assert_row_count(session2, 'ttl_table', 1) assert_all( session2, "SELECT * FROM ttl_table;", [[2, 2, None, None]] ) # Check that the TTL on both server are the same ttl_session2 = session2.execute('SELECT ttl(col1) FROM ttl_table;') ttl_session1 = ttl_session1[0][0] - (time.time() - ttl_start) assert_almost_equal(ttl_session1, ttl_session2[0][0], error=0.005)
def assertions_test(self): # assert_exception_test mock_session = Mock(**{'execute.side_effect': AlreadyExists("Dummy exception message.")}) assert_exception(mock_session, "DUMMY QUERY", expected=AlreadyExists) # assert_unavailable_test mock_session = Mock(**{'execute.side_effect': Unavailable("Dummy Unavailabile message.")}) assert_unavailable(mock_session.execute) # assert_invalid_test mock_session = Mock(**{'execute.side_effect': InvalidRequest("Dummy InvalidRequest message.")}) assert_invalid(mock_session, "DUMMY QUERY") # assert_unauthorized_test mock_session = Mock(**{'execute.side_effect': Unauthorized("Dummy Unauthorized message.")}) assert_unauthorized(mock_session, "DUMMY QUERY", None) # assert_one_test mock_session = Mock() mock_session.execute = Mock(return_value=[[1, 1]]) assert_one(mock_session, "SELECT * FROM test", [1, 1]) # assert_none_test mock_session = Mock() mock_session.execute = Mock(return_value=[]) assert_none(mock_session, "SELECT * FROM test") # assert_all_test mock_session = Mock() mock_session.execute = Mock(return_value=[[i, i] for i in range(0, 10)]) assert_all(mock_session, "SELECT k, v FROM test", [[i, i] for i in range(0, 10)], ignore_order=True) # assert_almost_equal_test assert_almost_equal(1, 1.1, 1.2, 1.9, error=1.0) # assert_row_count_test mock_session = Mock() mock_session.execute = Mock(return_value=[[1]]) assert_row_count(mock_session, 'test', 1) # assert_length_equal_test check = [1, 2, 3, 4] assert_length_equal(check, 4)
def replica_availability_test(self): """ @jira_ticket CASSANDRA-8640 Regression test for a bug (CASSANDRA-8640) that required all nodes to be available in order to run LWT queries, even if the query could complete correctly with quorum nodes available. """ session = self.prepare(nodes=3, rf=3) session.execute("CREATE TABLE test (k int PRIMARY KEY, v int)") session.execute("INSERT INTO test (k, v) VALUES (0, 0) IF NOT EXISTS") self.cluster.nodelist()[2].stop() session.execute("INSERT INTO test (k, v) VALUES (1, 1) IF NOT EXISTS") self.cluster.nodelist()[1].stop() assert_unavailable(session.execute, "INSERT INTO test (k, v) VALUES (2, 2) IF NOT EXISTS") self.cluster.nodelist()[1].start(wait_for_binary_proto=True, wait_other_notice=True) session.execute("INSERT INTO test (k, v) VALUES (3, 3) IF NOT EXISTS") self.cluster.nodelist()[2].start(wait_for_binary_proto=True) session.execute("INSERT INTO test (k, v) VALUES (4, 4) IF NOT EXISTS")