use of com.github.ambry.clustermap.MockPartitionId in project ambry by linkedin.
the class OperationTrackerTest method putOperationWithDynamicTargetTest.
/**
* Test put operation with both dynamic success target and get replica by state enabled.
* Test cases:
* Case 1: 1 LEADER and 2 STANDBY replicas (regular case)
* Case 2: 1 LEADER and 3 STANDBY replicas. One of them returns REQUEST_DISABLED error code. There are two combinations
* for remaining 3 replicas:
* (1) two success and one failure (whole operation should succeed)
* (2) one success and two failure (whole operation should fail)
* Case 3: 1 LEADER and 5 STANDBY replicas. Several combinations to discuss:
* (1) 3 REQUEST_DISABLED, 2 success and 1 failure (operation should succeed)
* (2) 2 REQUEST_DISABLED, 2 failure (operation should fail no matter what results are from remaining replicas)
* (3) 1 REQUEST_DISABLED, 1 failure, 4 success (operation should succeed)
* (4) 0 REQUEST_DISABLED, 2 failure, 4 success (operation should fail)
* Case 4: 1 LEADER, 4 STANDBY, 1 INACTIVE (this is to mock one replica has completed STANDBY -> INACTIVE)
* (1) 2 REQUEST_DISABLED, 1 failure and 2 success (operation should succeed)
* (2) 3 REQUEST_DISABLED, 1 failure (operation should fail no matter what result is from remaining replica)
*/
@Test
public void putOperationWithDynamicTargetTest() {
assumeTrue(operationTrackerType.equals(SIMPLE_OP_TRACKER) && replicasStateEnabled);
useDynamicTargetForPut = true;
List<Port> portList = Collections.singletonList(new Port(PORT, PortType.PLAINTEXT));
List<String> mountPaths = Collections.singletonList("mockMountPath");
datanodes = Collections.singletonList(new MockDataNodeId(portList, mountPaths, "dc-0"));
mockPartition = new MockPartitionId();
// Case 1
populateReplicaList(1, ReplicaState.LEADER);
populateReplicaList(2, ReplicaState.STANDBY);
localDcName = datanodes.get(0).getDatacenterName();
mockClusterMap = new MockClusterMap(false, datanodes, 1, Collections.singletonList(mockPartition), localDcName);
OperationTracker ot = getOperationTracker(true, 1, 3, RouterOperation.PutOperation, true);
sendRequests(ot, 3, false);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
assertTrue("Operation should succeed", ot.hasSucceeded());
// Case 2.1
populateReplicaList(1, ReplicaState.STANDBY);
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 4, RouterOperation.PutOperation, true);
sendRequests(ot, 4, false);
// make 1 replica return REQUEST_DISABLED, then 1 failure and 2 success
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
assertTrue("Operation should succeed", ot.hasSucceeded());
// Case 2.2
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 4, RouterOperation.PutOperation, true);
sendRequests(ot, 4, false);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
}
assertFalse("Operation should fail", ot.hasSucceeded());
// Case 3.1
populateReplicaList(2, ReplicaState.STANDBY);
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 6, RouterOperation.PutOperation, true);
sendRequests(ot, 6, false);
for (int i = 0; i < 3; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
}
assertFalse("Operation should not be done yet", ot.isDone());
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
assertFalse("Operation should not be done yet", ot.isDone());
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
assertTrue("Operation should succeed", ot.hasSucceeded());
// Case 3.2
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 6, RouterOperation.PutOperation, true);
sendRequests(ot, 6, false);
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
}
assertFalse("Operation should fail", ot.hasSucceeded());
// Case 3.3
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 6, RouterOperation.PutOperation, true);
sendRequests(ot, 6, false);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
for (int i = 0; i < 4; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
assertTrue("Operation should succeed", ot.hasSucceeded());
// Case 3.4
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 6, RouterOperation.PutOperation, true);
sendRequests(ot, 6, false);
for (int i = 0; i < 6; ++i) {
if (i < 2) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
} else {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
}
assertFalse("Operation should fail", ot.hasSucceeded());
// Case 4
// re-populate replica list
mockPartition.cleanUp();
repetitionTracker.clear();
populateReplicaList(1, ReplicaState.LEADER);
populateReplicaList(4, ReplicaState.STANDBY);
populateReplicaList(1, ReplicaState.INACTIVE);
ot = getOperationTracker(true, 1, 5, RouterOperation.PutOperation, true);
sendRequests(ot, 5, false);
// Case 4.1
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
}
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
assertFalse("Operation should not be done yet", ot.isDone());
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
assertTrue("Operation should succeed", ot.hasSucceeded());
// Case 4.2
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 5, RouterOperation.PutOperation, true);
sendRequests(ot, 5, false);
for (int i = 0; i < 3; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.REQUEST_DISABLED);
}
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
assertTrue("Operation should be done", ot.isDone());
assertFalse("Operation should fail", ot.hasSucceeded());
}
use of com.github.ambry.clustermap.MockPartitionId in project ambry by linkedin.
the class OperationTrackerTest method deleteTtlUpdateWithReplicaStateTest.
/**
* Test delete/ttlUpdate operation when replicasStateEnabled is enabled/disabled.
* local dc: 2 STANDBY and 1 INACTIVE; remote dc: 2 STANDBY and 1 INACTIVE
* 1. Issue 3 requests in parallel
* 2. Make 2 requests fail
* 3. Issue 1 requests (replicaState enabled tracker only has 4 eligible replicas)
* 4. Make 1 succeed and 1 fail (replicaState enabled tracker should fail)
* 5. Make remaining requests succeed, this only applies for tracker with replicaState disabled and operation should succeed.
*/
@Test
public void deleteTtlUpdateWithReplicaStateTest() {
assumeTrue(operationTrackerType.equals(SIMPLE_OP_TRACKER));
List<Port> portList = Collections.singletonList(new Port(PORT, PortType.PLAINTEXT));
List<String> mountPaths = Collections.singletonList("mockMountPath");
// set up one node per data center for testing
datanodes = new ArrayList<>(Arrays.asList(new MockDataNodeId(portList, mountPaths, "dc-0"), new MockDataNodeId(portList, mountPaths, "dc-1")));
mockPartition = new MockPartitionId();
localDcName = datanodes.get(0).getDatacenterName();
mockClusterMap = new MockClusterMap(false, datanodes, 1, Collections.singletonList(mockPartition), localDcName);
// put two STANDBY replicas in each data center (note that "populateReplicaList" method alternatively distributes
// the replica, so here we set 4 for two dc in total)
populateReplicaList(4, ReplicaState.STANDBY);
// put one INACTIVE in each data center
populateReplicaList(2, ReplicaState.INACTIVE);
// test both delete and Ttl Update cases
for (RouterOperation operation : EnumSet.of(RouterOperation.DeleteOperation, RouterOperation.TtlUpdateOperation)) {
repetitionTracker.clear();
OperationTracker ot = getOperationTracker(true, 1, 2, operation, true);
// issue delete/ttlUpdate requests to 2 local replica and 1 remote replica
sendRequests(ot, 3, false);
// make 2 requests fail and send requests again
for (int i = 0; i < 2; ++i) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
}
// for replicaState enabled operation tracker, only 1 eligible replica left, so numRequestsExpected = 1
sendRequests(ot, replicasStateEnabled ? 1 : 2, false);
// make 1 requests fail and 1 request succeed then replicaState enabled operation tracker should fail
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
if (replicasStateEnabled) {
assertFalse("Operation should fail", ot.hasSucceeded());
} else {
// if replicasStateEnabled = false, operation tracker is able to succeed after 1 more request succeed
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
assertTrue("Operation should succeed", ot.hasSucceeded());
}
assertTrue("Operation should be done", ot.isDone());
}
}
use of com.github.ambry.clustermap.MockPartitionId in project ambry by linkedin.
the class OperationTrackerTest method localPutWithReplicaStateTest.
/**
* Test put operation in local dc when replicasStateEnabled is enabled/disabled.
* Test steps:
* Case1: Only 2 STANDBY replicas in local dc;
* Make 1 succeed and the other fail (both current and replicaState enabled tracker should fail)
* Case2: 2 STANDBY, 1 INACTIVE replicas in local dc
* Make 1 fail and 2 succeed (replicaState enabled operation tracker should fail)
* Case3: 1 LEADER, 4 STANDBY and 1 INACTIVE in local dc
* Make 3 succeed and 2 fail (replicaState enabled operation tracker should fail)
*/
@Test
public void localPutWithReplicaStateTest() {
assumeTrue(operationTrackerType.equals(SIMPLE_OP_TRACKER));
List<Port> portList = Collections.singletonList(new Port(PORT, PortType.PLAINTEXT));
List<String> mountPaths = Collections.singletonList("mockMountPath");
datanodes = Collections.singletonList(new MockDataNodeId(portList, mountPaths, "dc-0"));
mockPartition = new MockPartitionId();
// test that if there are only 2 eligible replicas, the success target should use routerConfig.routerPutSuccessTarget
populateReplicaList(2, ReplicaState.STANDBY);
localDcName = datanodes.get(0).getDatacenterName();
mockClusterMap = new MockClusterMap(false, datanodes, 1, Collections.singletonList(mockPartition), localDcName);
OperationTracker ot = getOperationTracker(true, 1, 2, RouterOperation.PutOperation, true);
assertFalse("Operation should not have been done.", ot.isDone());
sendRequests(ot, 2, false);
// make one requests succeed, the other fail
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
assertFalse("Operation should fail", ot.hasSucceeded());
assertTrue("Operation should be done", ot.isDone());
// add one more replica in INACTIVE state, now we have 2 STANDBY and 1 INACTIVE replicas
populateReplicaList(1, ReplicaState.INACTIVE);
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 3, RouterOperation.PutOperation, true);
// issue PUT request
sendRequests(ot, replicasStateEnabled ? 2 : 3, false);
// make first request fail and rest requests succeed
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
while (!inflightReplicas.isEmpty()) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
}
if (replicasStateEnabled) {
assertFalse("Operation should fail because only 2 replicas eligible and 1 has failed", ot.hasSucceeded());
} else {
assertTrue("Operation should succeed when there are 2 success", ot.hasSucceeded());
}
// add three more replicas: one in LEADER state, the other two in STANDBY state
populateReplicaList(1, ReplicaState.LEADER);
populateReplicaList(2, ReplicaState.STANDBY);
// now we have 6 replicas: 1 LEADER, 4 STANDBY and 1 INACTIVE. Number of eligible replicas = 1 + 4 = 5
repetitionTracker.clear();
ot = getOperationTracker(true, 1, 5, RouterOperation.PutOperation, true);
// issue PUT request, parallelism should be 5 when replicaState is enabled.
sendRequests(ot, 5, false);
// remaining test is for replicaState enabled operation tracker
if (replicasStateEnabled) {
// make first 3 requests succeed
for (int i = 0; i < 3; i++) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.SUCCESS);
// success target should be 4 when replicaState is enabled for operation tracker, so operation is not done yet
// even though it has succeeded on 3 replicas.
assertFalse("Operation should not be done", ot.isDone());
}
// make last 2 requests fail, then operation should be done and result should be failure
for (int i = 0; i < 2; i++) {
ot.onResponse(inflightReplicas.poll(), TrackedRequestFinalState.FAILURE);
}
assertFalse("Operation should fail", ot.hasSucceeded());
assertTrue("Operation should be done", ot.isDone());
}
}
use of com.github.ambry.clustermap.MockPartitionId in project ambry by linkedin.
the class OperationTrackerTest method initializeWithCloudDcs.
/**
* Initialize 4 DCs, 2 disk datacenters, 2 cloud datacenters. Each disk datacenter has 3 replicas, and each cloud
* datacenter has 1 replica.
* @param makeCloudDcLocal {@code true} to make the local datacenter one of the cloud datacenters.
*/
private void initializeWithCloudDcs(boolean makeCloudDcLocal) {
List<Port> portList = Collections.singletonList(new Port(PORT, PortType.PLAINTEXT));
List<String> mountPaths = Collections.singletonList("mockMountPath");
mockPartition = new MockPartitionId();
List<MockDataNodeId> diskNodes = Arrays.asList(new MockDataNodeId(portList, mountPaths, "dc-0"), new MockDataNodeId(portList, mountPaths, "dc-1"));
populateReplicaList(3 * diskNodes.size(), ReplicaState.STANDBY, diskNodes);
List<MockDataNodeId> cloudNodes = Arrays.asList(new MockDataNodeId(portList, Collections.emptyList(), "cloud-dc-0"), new MockDataNodeId(portList, Collections.emptyList(), "cloud-dc-1"));
// only one cloud replica per cloud dc.
populateReplicaList(cloudNodes.size(), ReplicaState.STANDBY, cloudNodes);
datanodes = new ArrayList<>();
datanodes.addAll(diskNodes);
datanodes.addAll(cloudNodes);
localDcName = (makeCloudDcLocal ? cloudNodes : diskNodes).get(0).getDatacenterName();
mockClusterMap = new MockClusterMap(false, datanodes, 1, Collections.singletonList(mockPartition), localDcName);
}
use of com.github.ambry.clustermap.MockPartitionId in project ambry by linkedin.
the class OperationTrackerTest method initialize.
/**
* Initialize 4 DCs, each DC has 1 data node, which has 3 replicas.
*/
private void initialize() {
int replicaCount = 12;
List<Port> portList = Collections.singletonList(new Port(PORT, PortType.PLAINTEXT));
List<String> mountPaths = Collections.singletonList("mockMountPath");
datanodes = new ArrayList<>(Arrays.asList(new MockDataNodeId(portList, mountPaths, "dc-0"), new MockDataNodeId(portList, mountPaths, "dc-1"), new MockDataNodeId(portList, mountPaths, "dc-2"), new MockDataNodeId(portList, mountPaths, "dc-3")));
mockPartition = new MockPartitionId();
populateReplicaList(replicaCount, ReplicaState.STANDBY);
localDcName = datanodes.get(0).getDatacenterName();
mockClusterMap = new MockClusterMap(false, datanodes, 1, Collections.singletonList(mockPartition), localDcName);
}
Aggregations