You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ae...@apache.org on 2019/08/31 01:23:44 UTC

[hadoop] branch trunk updated: HDDS-1413. Attempt to fix TestCloseContainerCommandHandler by adjusting timeouts

This is an automated email from the ASF dual-hosted git repository.

aengineer pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new a2d083f  HDDS-1413. Attempt to fix TestCloseContainerCommandHandler by adjusting timeouts
a2d083f is described below

commit a2d083f2c546ef9e0a543ea287c2435c6440d9aa
Author: Doroszlai, Attila <ad...@apache.org>
AuthorDate: Thu Aug 29 18:01:21 2019 +0200

    HDDS-1413. Attempt to fix TestCloseContainerCommandHandler by adjusting timeouts
    
    Signed-off-by: Anu Engineer <ae...@apache.org>
---
 .../TestCloseContainerCommandHandler.java          | 410 +++++++--------------
 1 file changed, 143 insertions(+), 267 deletions(-)

diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/TestCloseContainerCommandHandler.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/TestCloseContainerCommandHandler.java
index 219b504..84a1e5d 100644
--- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/TestCloseContainerCommandHandler.java
+++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/TestCloseContainerCommandHandler.java
@@ -16,306 +16,187 @@
  */
 package org.apache.hadoop.ozone.container.common.statemachine.commandhandler;
 
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hdds.HddsConfigKeys;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
-import org.apache.hadoop.hdds.scm.ScmConfigKeys;
-import org.apache.hadoop.hdds.scm.container.ContainerID;
 import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
-import org.apache.hadoop.ozone.OzoneConfigKeys;
+import org.apache.hadoop.ozone.container.common.impl.ContainerSet;
 import org.apache.hadoop.ozone.container.common.interfaces.Container;
+import org.apache.hadoop.ozone.container.common.interfaces.Handler;
 import org.apache.hadoop.ozone.container.common.statemachine
     .DatanodeStateMachine;
 import org.apache.hadoop.ozone.container.common.statemachine.StateContext;
+import org.apache.hadoop.ozone.container.common.transport.server.XceiverServerSpi;
+import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer;
+import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData;
+import org.apache.hadoop.ozone.container.ozoneimpl.ContainerController;
 import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
 import org.apache.hadoop.ozone.protocol.commands.CloseContainerCommand;
-import org.apache.hadoop.test.GenericTestUtils;
-import org.apache.hadoop.hdds.ratis.RatisHelper;
-import org.apache.ratis.client.RaftClient;
-import org.apache.ratis.protocol.RaftGroup;
-import org.apache.ratis.protocol.RaftGroupId;
-import org.apache.ratis.protocol.RaftPeer;
-import org.apache.ratis.retry.RetryPolicy;
-import org.apache.ratis.rpc.SupportedRpcType;
-import org.apache.ratis.util.TimeDuration;
-import org.junit.AfterClass;
-import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mockito;
 
-import java.io.File;
 import java.io.IOException;
-import java.util.Collections;
-import java.util.Random;
 import java.util.UUID;
-import java.util.concurrent.TimeUnit;
+
+import static java.util.Collections.singletonMap;
+import static org.apache.hadoop.ozone.OzoneConsts.GB;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 /**
  * Test cases to verify CloseContainerCommandHandler in datanode.
  */
 public class TestCloseContainerCommandHandler {
 
-  private final StateContext context = Mockito.mock(StateContext.class);
-  private final Random random = new Random();
-  private static File testDir;
+  private static final long CONTAINER_ID = 123L;
+
+  private OzoneContainer ozoneContainer;
+  private StateContext context;
+  private XceiverServerSpi writeChannel;
+  private Container container;
+  private Handler containerHandler;
+  private PipelineID pipelineID;
+  private PipelineID nonExistentPipelineID = PipelineID.randomId();
+
+  private CloseContainerCommandHandler subject =
+      new CloseContainerCommandHandler();
+
+  @Before
+  public void before() throws Exception {
+    context = mock(StateContext.class);
+    DatanodeStateMachine dnStateMachine = mock(DatanodeStateMachine.class);
+    when(dnStateMachine.getDatanodeDetails())
+        .thenReturn(randomDatanodeDetails());
+    when(context.getParent()).thenReturn(dnStateMachine);
+
+    pipelineID = PipelineID.randomId();
+
+    KeyValueContainerData data = new KeyValueContainerData(CONTAINER_ID, GB,
+        pipelineID.getId().toString(), null);
+
+    container = new KeyValueContainer(data, new OzoneConfiguration());
+    ContainerSet containerSet = new ContainerSet();
+    containerSet.addContainer(container);
+
+    containerHandler = mock(Handler.class);
+    ContainerController controller = new ContainerController(containerSet,
+        singletonMap(ContainerProtos.ContainerType.KeyValueContainer,
+            containerHandler));
+
+    writeChannel = mock(XceiverServerSpi.class);
+    ozoneContainer = mock(OzoneContainer.class);
+    when(ozoneContainer.getController()).thenReturn(controller);
+    when(ozoneContainer.getContainerSet()).thenReturn(containerSet);
+    when(ozoneContainer.getWriteChannel()).thenReturn(writeChannel);
+    when(writeChannel.isExist(pipelineID.getProtobuf())).thenReturn(true);
+    when(writeChannel.isExist(nonExistentPipelineID.getProtobuf()))
+        .thenReturn(false);
+  }
 
   @Test
-  public void testCloseContainerViaRatis()
-      throws Exception {
-    final OzoneConfiguration conf = new OzoneConfiguration();
-    final DatanodeDetails datanodeDetails = randomDatanodeDetails();
-    final OzoneContainer ozoneContainer =
-        getOzoneContainer(conf, datanodeDetails);
-    ozoneContainer.start(UUID.randomUUID().toString());
-    try {
-      final Container container =
-          createContainer(conf, datanodeDetails, ozoneContainer);
-      Mockito.verify(context.getParent(),
-          Mockito.times(1)).triggerHeartbeat();
-      final long containerId = container.getContainerData().getContainerID();
-      final PipelineID pipelineId = PipelineID.valueOf(UUID.fromString(
-          container.getContainerData().getOriginPipelineId()));
-
-      // We have created a container via ratis.
-      // Now close the container on ratis.
-      final CloseContainerCommandHandler closeHandler =
-          new CloseContainerCommandHandler();
-      final CloseContainerCommand command = new CloseContainerCommand(
-          containerId, pipelineId);
-
-      closeHandler.handle(command, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-
-      Mockito.verify(context.getParent(),
-          Mockito.times(3)).triggerHeartbeat();
-    } finally {
-      ozoneContainer.stop();
-    }
+  public void closeContainerWithPipeline() throws Exception {
+    // close a container that's associated with an existing pipeline
+    subject.handle(closeWithKnownPipeline(), ozoneContainer, context, null);
+
+    verify(containerHandler)
+        .markContainerForClose(container);
+    verify(writeChannel)
+        .submitRequest(any(), eq(pipelineID.getProtobuf()));
+    verify(containerHandler, never())
+        .quasiCloseContainer(container);
   }
 
   @Test
-  public void testCloseContainerViaStandalone()
-      throws Exception {
-    final OzoneConfiguration conf = new OzoneConfiguration();
-    final DatanodeDetails datanodeDetails = randomDatanodeDetails();
-    final OzoneContainer ozoneContainer =
-        getOzoneContainer(conf, datanodeDetails);
-    ozoneContainer.start(UUID.randomUUID().toString());
-    try {
-      final Container container =
-          createContainer(conf, datanodeDetails, ozoneContainer);
-      Mockito.verify(context.getParent(),
-          Mockito.times(1)).triggerHeartbeat();
-      final long containerId = container.getContainerData().getContainerID();
-      // To quasi close specify a pipeline which doesn't exist in the datanode.
-      final PipelineID pipelineId = PipelineID.randomId();
-
-      // We have created a container via ratis. Now quasi close it.
-      final CloseContainerCommandHandler closeHandler =
-          new CloseContainerCommandHandler();
-      final CloseContainerCommand command = new CloseContainerCommand(
-          containerId, pipelineId);
-
-      closeHandler.handle(command, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.QUASI_CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-
-      Mockito.verify(context.getParent(),
-          Mockito.times(3)).triggerHeartbeat();
-    } finally {
-      ozoneContainer.stop();
-    }
+  public void closeContainerWithoutPipeline() throws IOException {
+    // close a container that's NOT associated with an open pipeline
+    subject.handle(closeWithUnknownPipeline(), ozoneContainer, context, null);
+
+    verify(containerHandler)
+        .markContainerForClose(container);
+    verify(writeChannel, never())
+        .submitRequest(any(), any());
+    verify(containerHandler)
+        .quasiCloseContainer(container);
+  }
+
+  @Test
+  public void forceCloseQuasiClosedContainer() throws Exception {
+    // force-close a container that's already quasi closed
+    container.getContainerData()
+        .setState(ContainerProtos.ContainerDataProto.State.QUASI_CLOSED);
+
+    subject.handle(forceCloseWithoutPipeline(), ozoneContainer, context, null);
+
+    verify(writeChannel, never())
+        .submitRequest(any(), any());
+    verify(containerHandler)
+        .closeContainer(container);
   }
 
   @Test
-  public void testQuasiCloseToClose() throws Exception {
-    final OzoneConfiguration conf = new OzoneConfiguration();
-    final DatanodeDetails datanodeDetails = randomDatanodeDetails();
-    final OzoneContainer ozoneContainer =
-        getOzoneContainer(conf, datanodeDetails);
-    ozoneContainer.start(UUID.randomUUID().toString());
-    try {
-      final Container container =
-          createContainer(conf, datanodeDetails, ozoneContainer);
-      Mockito.verify(context.getParent(),
-          Mockito.times(1)).triggerHeartbeat();
-      final long containerId = container.getContainerData().getContainerID();
-      // A pipeline which doesn't exist in the datanode.
-      final PipelineID pipelineId = PipelineID.randomId();
-
-      // We have created a container via ratis. Now quasi close it.
-      final CloseContainerCommandHandler closeHandler =
-          new CloseContainerCommandHandler();
-      final CloseContainerCommand command = new CloseContainerCommand(
-          containerId, pipelineId);
-
-      closeHandler.handle(command, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.QUASI_CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-
-      Mockito.verify(context.getParent(),
-          Mockito.times(3)).triggerHeartbeat();
-
-      // The container is quasi closed. Force close the container now.
-      final CloseContainerCommand closeCommand = new CloseContainerCommand(
-          containerId, pipelineId, true);
-
-      closeHandler.handle(closeCommand, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-
-      Mockito.verify(context.getParent(),
-          Mockito.times(4)).triggerHeartbeat();
-    } finally {
-      ozoneContainer.stop();
-    }
+  public void forceCloseOpenContainer() throws Exception {
+    // force-close a container that's NOT associated with an open pipeline
+    subject.handle(forceCloseWithoutPipeline(), ozoneContainer, context, null);
+
+    verify(writeChannel, never())
+        .submitRequest(any(), any());
+    verify(containerHandler)
+        .closeContainer(container);
   }
 
   @Test
-  public void testForceCloseOpenContainer() throws Exception {
-    final OzoneConfiguration conf = new OzoneConfiguration();
-    final DatanodeDetails datanodeDetails = randomDatanodeDetails();
-    final OzoneContainer ozoneContainer =
-        getOzoneContainer(conf, datanodeDetails);
-    ozoneContainer.start(UUID.randomUUID().toString());
-    try {
-      final Container container =
-          createContainer(conf, datanodeDetails, ozoneContainer);
-      Mockito.verify(context.getParent(),
-          Mockito.times(1)).triggerHeartbeat();
-      final long containerId = container.getContainerData().getContainerID();
-      // A pipeline which doesn't exist in the datanode.
-      final PipelineID pipelineId = PipelineID.randomId();
-
-      final CloseContainerCommandHandler closeHandler =
-          new CloseContainerCommandHandler();
-
-      final CloseContainerCommand closeCommand = new CloseContainerCommand(
-          containerId, pipelineId, true);
-
-      closeHandler.handle(closeCommand, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-
-      Mockito.verify(context.getParent(),
-          Mockito.times(3)).triggerHeartbeat();
-    } finally {
-      ozoneContainer.stop();
-    }
+  public void forceCloseOpenContainerWithPipeline() throws Exception {
+    // force-close a container that's associated with an existing pipeline
+    subject.handle(forceCloseWithPipeline(), ozoneContainer, context, null);
+
+    verify(containerHandler)
+        .markContainerForClose(container);
+    verify(writeChannel, never())
+        .submitRequest(any(), any());
+    verify(containerHandler, never())
+        .quasiCloseContainer(container);
+    verify(containerHandler, never())
+        .closeContainer(container);
   }
 
   @Test
-  public void testQuasiCloseClosedContainer()
-      throws Exception {
-    final OzoneConfiguration conf = new OzoneConfiguration();
-    final DatanodeDetails datanodeDetails = randomDatanodeDetails();
-    final OzoneContainer ozoneContainer = getOzoneContainer(
-        conf, datanodeDetails);
-    ozoneContainer.start(UUID.randomUUID().toString());
-    try {
-      final Container container = createContainer(
-          conf, datanodeDetails, ozoneContainer);
-      Mockito.verify(context.getParent(),
-          Mockito.times(1)).triggerHeartbeat();
-      final long containerId = container.getContainerData().getContainerID();
-      final PipelineID pipelineId = PipelineID.valueOf(UUID.fromString(
-          container.getContainerData().getOriginPipelineId()));
-
-      final CloseContainerCommandHandler closeHandler =
-          new CloseContainerCommandHandler();
-      final CloseContainerCommand closeCommand = new CloseContainerCommand(
-          containerId, pipelineId);
-
-      closeHandler.handle(closeCommand, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-
-      // The container is closed, now we send close command with
-      // pipeline id which doesn't exist.
-      // This should cause the datanode to trigger quasi close, since the
-      // container is already closed, this should do nothing.
-      // The command should not fail either.
-      final PipelineID randomPipeline = PipelineID.randomId();
-      final CloseContainerCommand quasiCloseCommand =
-          new CloseContainerCommand(containerId, randomPipeline);
-      closeHandler.handle(quasiCloseCommand, ozoneContainer, context, null);
-
-      Assert.assertEquals(ContainerProtos.ContainerDataProto.State.CLOSED,
-          ozoneContainer.getContainerSet().getContainer(containerId)
-              .getContainerState());
-    } finally {
-      ozoneContainer.stop();
-    }
+  public void closeAlreadyClosedContainer() throws Exception {
+    container.getContainerData()
+        .setState(ContainerProtos.ContainerDataProto.State.CLOSED);
+
+    // Since the container is already closed, these commands should do nothing,
+    // neither should they fail
+    subject.handle(closeWithUnknownPipeline(), ozoneContainer, context, null);
+    subject.handle(closeWithKnownPipeline(), ozoneContainer, context, null);
+
+    verify(containerHandler, never())
+        .markContainerForClose(container);
+    verify(containerHandler, never())
+        .quasiCloseContainer(container);
+    verify(containerHandler, never())
+        .closeContainer(container);
+    verify(writeChannel, never())
+        .submitRequest(any(), any());
   }
 
-  private OzoneContainer getOzoneContainer(final OzoneConfiguration conf,
-      final DatanodeDetails datanodeDetails) throws IOException {
-    testDir = GenericTestUtils.getTestDir(
-        TestCloseContainerCommandHandler.class.getName() + UUID.randomUUID());
-    conf.set(HddsConfigKeys.OZONE_METADATA_DIRS, testDir.getPath());
-    conf.set(ScmConfigKeys.HDDS_DATANODE_DIR_KEY, testDir.getPath());
-    conf.setBoolean(OzoneConfigKeys.DFS_CONTAINER_RATIS_IPC_RANDOM_PORT, true);
-    conf.setBoolean(OzoneConfigKeys.DFS_CONTAINER_IPC_RANDOM_PORT, true);
-
-    final DatanodeStateMachine datanodeStateMachine = Mockito.mock(
-        DatanodeStateMachine.class);
-    Mockito.when(datanodeStateMachine.getDatanodeDetails())
-        .thenReturn(datanodeDetails);
-    Mockito.when(context.getParent()).thenReturn(datanodeStateMachine);
-    final OzoneContainer ozoneContainer = new  OzoneContainer(
-        datanodeDetails, conf, context, null);
-    return ozoneContainer;
+  private CloseContainerCommand closeWithKnownPipeline() {
+    return new CloseContainerCommand(CONTAINER_ID, pipelineID);
   }
 
-  private Container createContainer(final Configuration conf,
-      final DatanodeDetails datanodeDetails,
-      final OzoneContainer ozoneContainer) throws Exception  {
-    final PipelineID pipelineID = PipelineID.randomId();
-    final RaftGroupId raftGroupId = RaftGroupId.valueOf(pipelineID.getId());
-    final RetryPolicy retryPolicy = RatisHelper.createRetryPolicy(conf);
-    final RaftPeer peer = RatisHelper.toRaftPeer(datanodeDetails);
-    final RaftGroup group = RatisHelper.newRaftGroup(raftGroupId,
-        Collections.singleton(datanodeDetails));
-    final int maxOutstandingRequests = 100;
-    final RaftClient client = RatisHelper
-        .newRaftClient(SupportedRpcType.GRPC, peer, retryPolicy,
-            maxOutstandingRequests,
-            TimeDuration.valueOf(3, TimeUnit.SECONDS));
-    Assert.assertTrue(client.groupAdd(group, peer.getId()).isSuccess());
-    Thread.sleep(10000);
-    final ContainerID containerId = ContainerID.valueof(
-        random.nextLong() & Long.MAX_VALUE);
-    ContainerProtos.ContainerCommandRequestProto.Builder request =
-        ContainerProtos.ContainerCommandRequestProto.newBuilder();
-    request.setCmdType(ContainerProtos.Type.CreateContainer);
-    request.setContainerID(containerId.getId());
-    request.setCreateContainer(
-        ContainerProtos.CreateContainerRequestProto.getDefaultInstance());
-    request.setDatanodeUuid(datanodeDetails.getUuidString());
-    ozoneContainer.getWriteChannel().submitRequest(
-        request.build(), pipelineID.getProtobuf());
-
-    final Container container = ozoneContainer.getContainerSet().getContainer(
-        containerId.getId());
-    Assert.assertEquals(ContainerProtos.ContainerDataProto.State.OPEN,
-        container.getContainerState());
-    return container;
+  private CloseContainerCommand closeWithUnknownPipeline() {
+    return new CloseContainerCommand(CONTAINER_ID, nonExistentPipelineID);
+  }
+
+  private CloseContainerCommand forceCloseWithPipeline() {
+    return new CloseContainerCommand(CONTAINER_ID, pipelineID, true);
+  }
+
+  private CloseContainerCommand forceCloseWithoutPipeline() {
+    return new CloseContainerCommand(CONTAINER_ID, nonExistentPipelineID, true);
   }
 
   /**
@@ -339,9 +220,4 @@ public class TestCloseContainerCommandHandler {
         .addPort(restPort);
     return builder.build();
   }
-
-  @AfterClass
-  public static void teardown() throws IOException {
-    FileUtils.deleteDirectory(testDir);
-  }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org