Search in sources :

Example 21 with MockPartitionId

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());
}
Also used : MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Port(com.github.ambry.network.Port) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Example 22 with MockPartitionId

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());
    }
}
Also used : MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Port(com.github.ambry.network.Port) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Example 23 with MockPartitionId

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());
    }
}
Also used : MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Port(com.github.ambry.network.Port) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Example 24 with MockPartitionId

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);
}
Also used : MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Port(com.github.ambry.network.Port) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap)

Example 25 with MockPartitionId

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);
}
Also used : MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Port(com.github.ambry.network.Port) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap)

Aggregations

MockPartitionId (com.github.ambry.clustermap.MockPartitionId)66 Test (org.junit.Test)51 PartitionId (com.github.ambry.clustermap.PartitionId)33 MockDataNodeId (com.github.ambry.clustermap.MockDataNodeId)31 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)26 ArrayList (java.util.ArrayList)26 ReplicaId (com.github.ambry.clustermap.ReplicaId)25 BlobId (com.github.ambry.commons.BlobId)23 Port (com.github.ambry.network.Port)20 MockReplicaId (com.github.ambry.clustermap.MockReplicaId)17 MetricRegistry (com.codahale.metrics.MetricRegistry)11 CloudBlobMetadata (com.github.ambry.cloud.CloudBlobMetadata)10 VerifiableProperties (com.github.ambry.config.VerifiableProperties)9 StorageManager (com.github.ambry.store.StorageManager)9 DataNodeId (com.github.ambry.clustermap.DataNodeId)8 BlobStoreTest (com.github.ambry.store.BlobStoreTest)8 Store (com.github.ambry.store.Store)7 ByteArrayInputStream (java.io.ByteArrayInputStream)7 Properties (java.util.Properties)7 NettyByteBufDataInputStream (com.github.ambry.utils.NettyByteBufDataInputStream)6