Yifan Cai created CASSANDRA-19842:
-------------------------------------

             Summary: [Analytics] Consistency level check incorrectly passes 
when majority of the replica set is unavailable for write
                 Key: CASSANDRA-19842
                 URL: https://issues.apache.org/jira/browse/CASSANDRA-19842
             Project: Cassandra
          Issue Type: Bug
          Components: Analytics Library
            Reporter: Yifan Cai
            Assignee: Yifan Cai


Consistency level check is performed before proceeding to bulk writing data. 
The check yields wrong results that when the majority of a replica set is 
unavailable, it still passes. Leading to writing data to replicas that cannot 
satisfy the desired consistency level. 

The following is the test to prove the bug. The test sets all 3 instances in 
the replica set as blocked (unavailable), so the validation is expected to 
throw. But it does not. 

{code:java}
@Test
void test()
{
    BulkWriterContext mockWriterContext = mock(BulkWriterContext.class);
    ClusterInfo mockClusterInfo = mock(ClusterInfo.class);
    when(mockWriterContext.cluster()).thenReturn(mockClusterInfo);

    CassandraContext mockCassandraContext = mock(CassandraContext.class);
    
when(mockClusterInfo.getCassandraContext()).thenReturn(mockCassandraContext);
    Map<String, String> replicationOptions = new HashMap<>();
    replicationOptions.put("class", "SimpleStrategy");
    replicationOptions.put("replication_factor", "3");
    TokenRangeMapping<RingInstance> topology = 
CassandraClusterInfo.getTokenRangeReplicas(() -> 
mockSimpleTokenRangeReplicasResponse(10, 3),
                                                                                
          () -> Partitioner.Murmur3Partitioner,
                                                                                
          () -> new ReplicationFactor(replicationOptions),
                                                                                
          ringInstance -> {
                                                                                
              int nodeId = 
Integer.parseInt(ringInstance.ipAddress().replace("localhost", ""));
                                                                                
              return nodeId <= 2; // block nodes 0, 1, 2
                                                                                
          });
    
when(mockClusterInfo.getTokenRangeMapping(anyBoolean())).thenReturn(topology);

    JobInfo mockJobInfo = mock(JobInfo.class);
    UUID jobId = UUID.randomUUID();
    when(mockJobInfo.getId()).thenReturn(jobId.toString());
    when(mockJobInfo.getRestoreJobId()).thenReturn(jobId);
    when(mockJobInfo.qualifiedTableName()).thenReturn(new 
QualifiedTableName("testkeyspace", "testtable"));
    
when(mockJobInfo.getConsistencyLevel()).thenReturn(ConsistencyLevel.CL.QUORUM);
    when(mockJobInfo.effectiveSidecarPort()).thenReturn(9043);
    when(mockJobInfo.jobKeepAliveMinutes()).thenReturn(-1);
    when(mockWriterContext.job()).thenReturn(mockJobInfo);

    BulkWriteValidator writerValidator = new 
BulkWriteValidator(mockWriterContext, new 
ReplicaAwareFailureHandler<>(Partitioner.Murmur3Partitioner));
    assertThatThrownBy(() -> writerValidator.validateClOrFail(topology))
    .isExactlyInstanceOf(RuntimeException.class)
    .hasMessageContaining("Failed to load");
}
{code}




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to