3030import org .apache .hadoop .hdds .scm .container .replication .ContainerCheckRequest ;
3131import org .apache .hadoop .hdds .scm .container .replication .ReplicationManager ;
3232import org .apache .hadoop .hdds .scm .container .replication .ReplicationTestUtil ;
33- import org .junit .jupiter .api .Assertions ;
3433import org .junit .jupiter .api .BeforeEach ;
3534import org .junit .jupiter .api .Test ;
3635import org .mockito .Mockito ;
4443import static org .apache .hadoop .hdds .protocol .proto .HddsProtos .LifeCycleState .QUASI_CLOSED ;
4544import static org .apache .hadoop .hdds .scm .HddsTestUtils .getContainer ;
4645import static org .apache .hadoop .hdds .scm .HddsTestUtils .getReplicas ;
46+ import static org .junit .jupiter .api .Assertions .assertEquals ;
47+ import static org .junit .jupiter .api .Assertions .assertFalse ;
4748import static org .mockito .ArgumentMatchers .any ;
4849import static org .mockito .ArgumentMatchers .anyBoolean ;
4950import static org .mockito .ArgumentMatchers .eq ;
5051import static org .mockito .Mockito .times ;
52+ import static org .mockito .Mockito .verify ;
5153
5254/**
5355 * Tests for {@link QuasiClosedContainerHandler}. This handler is only meant
@@ -81,8 +83,8 @@ public void testECContainerReturnsFalse() {
8183 .setContainerReplicas (containerReplicas )
8284 .build ();
8385
84- Assertions . assertFalse (quasiClosedContainerHandler .handle (request ));
85- Mockito . verify (replicationManager , times (0 ))
86+ assertFalse (quasiClosedContainerHandler .handle (request ));
87+ verify (replicationManager , times (0 ))
8688 .sendCloseContainerReplicaCommand (any (), any (), anyBoolean ());
8789 }
8890
@@ -100,19 +102,18 @@ public void testOpenContainerReturnsFalse() {
100102 .setContainerReplicas (containerReplicas )
101103 .build ();
102104
103- Assertions . assertFalse (quasiClosedContainerHandler .handle (request ));
104- Mockito . verify (replicationManager , times (0 ))
105+ assertFalse (quasiClosedContainerHandler .handle (request ));
106+ verify (replicationManager , times (0 ))
105107 .sendCloseContainerReplicaCommand (any (), any (), anyBoolean ());
106108 }
107109
108110 /**
109- * When a container is QUASI_CLOSED, and it has greater than 50% of its
111+ * When a container is QUASI_CLOSED, and it has only 2
110112 * replicas in QUASI_CLOSED state with unique origin node id,
111- * the handler should send force close commands to the replica(s) with
112- * highest BCSID.
113+ * the handler should not force close it as all 3 unique replicas are needed.
113114 */
114115 @ Test
115- public void testQuasiClosedWithQuorumReturnsTrue () {
116+ public void testQuasiClosedWithQuorumReturnsFalse () {
116117 ContainerInfo containerInfo = ReplicationTestUtil .createContainerInfo (
117118 ratisReplicationConfig , 1 , QUASI_CLOSED );
118119 Set <ContainerReplica > containerReplicas = ReplicationTestUtil
@@ -136,16 +137,50 @@ public void testQuasiClosedWithQuorumReturnsTrue() {
136137 .setReadOnly (true )
137138 .build ();
138139
139- Assertions .assertFalse (quasiClosedContainerHandler .handle (request ));
140- Assertions .assertFalse (quasiClosedContainerHandler .handle (readRequest ));
141- Mockito .verify (replicationManager , times (2 ))
140+ assertFalse (quasiClosedContainerHandler .handle (request ));
141+ assertFalse (quasiClosedContainerHandler .handle (readRequest ));
142+ verify (replicationManager , times (0 ))
143+ .sendCloseContainerReplicaCommand (any (), any (), anyBoolean ());
144+ assertEquals (1 , request .getReport ().getStat (
145+ ReplicationManagerReport .HealthState .QUASI_CLOSED_STUCK ));
146+ }
147+
148+ /**
149+ * When a container is QUASI_CLOSED, and all 3 replicas are reported with unique
150+ * origins, it should be forced closed.
151+ */
152+ @ Test
153+ public void testQuasiClosedWithAllUniqueOriginSendsForceClose () {
154+ ContainerInfo containerInfo = ReplicationTestUtil .createContainerInfo (
155+ ratisReplicationConfig , 1 , QUASI_CLOSED );
156+ // These 3 replicas will have the same BCSID and unique origin node ids
157+ Set <ContainerReplica > containerReplicas = ReplicationTestUtil
158+ .createReplicas (containerInfo .containerID (),
159+ State .QUASI_CLOSED , 0 , 0 , 0 );
160+ ContainerCheckRequest request = new ContainerCheckRequest .Builder ()
161+ .setPendingOps (Collections .emptyList ())
162+ .setReport (new ReplicationManagerReport ())
163+ .setContainerInfo (containerInfo )
164+ .setContainerReplicas (containerReplicas )
165+ .build ();
166+ ContainerCheckRequest readRequest = new ContainerCheckRequest .Builder ()
167+ .setPendingOps (Collections .emptyList ())
168+ .setReport (new ReplicationManagerReport ())
169+ .setContainerInfo (containerInfo )
170+ .setContainerReplicas (containerReplicas )
171+ .setReadOnly (true )
172+ .build ();
173+
174+ assertFalse (quasiClosedContainerHandler .handle (request ));
175+ assertFalse (quasiClosedContainerHandler .handle (readRequest ));
176+ verify (replicationManager , times (3 ))
142177 .sendCloseContainerReplicaCommand (any (), any (), anyBoolean ());
143178 }
144179
145180 /**
146181 * The replicas are QUASI_CLOSED, but all of them have the same origin node
147- * id. Since a quorum (greater than 50% of replicas with unique origin node
148- * ids in QUASI_CLOSED state) is not formed, the handler should return false .
182+ * id. Since all replicas must have unique origin node ids, the handler
183+ * should not force close it .
149184 */
150185 @ Test
151186 public void testHealthyQuasiClosedContainerReturnsFalse () {
@@ -161,17 +196,16 @@ public void testHealthyQuasiClosedContainerReturnsFalse() {
161196 .setContainerReplicas (containerReplicas )
162197 .build ();
163198
164- Assertions . assertFalse (quasiClosedContainerHandler .handle (request ));
165- Mockito . verify (replicationManager , times (0 ))
199+ assertFalse (quasiClosedContainerHandler .handle (request ));
200+ verify (replicationManager , times (0 ))
166201 .sendCloseContainerReplicaCommand (any (), any (), anyBoolean ());
167- Assertions . assertEquals (1 , request .getReport ().getStat (
202+ assertEquals (1 , request .getReport ().getStat (
168203 ReplicationManagerReport .HealthState .QUASI_CLOSED_STUCK ));
169204 }
170205
171206 /**
172207 * Only one replica is in QUASI_CLOSED state. This fails the condition of
173- * having greater than 50% of replicas with unique origin nodes in
174- * QUASI_CLOSED state. The handler should return false.
208+ * having all replicas with unique origin nodes in QUASI_CLOSED state.
175209 */
176210 @ Test
177211 public void testQuasiClosedWithTwoOpenReplicasReturnsFalse () {
@@ -191,10 +225,10 @@ public void testQuasiClosedWithTwoOpenReplicasReturnsFalse() {
191225 .setContainerReplicas (containerReplicas )
192226 .build ();
193227
194- Assertions . assertFalse (quasiClosedContainerHandler .handle (request ));
195- Mockito . verify (replicationManager , times (0 ))
228+ assertFalse (quasiClosedContainerHandler .handle (request ));
229+ verify (replicationManager , times (0 ))
196230 .sendCloseContainerReplicaCommand (any (), any (), anyBoolean ());
197- Assertions . assertEquals (1 , request .getReport ().getStat (
231+ assertEquals (1 , request .getReport ().getStat (
198232 ReplicationManagerReport .HealthState .QUASI_CLOSED_STUCK ));
199233 }
200234
@@ -240,14 +274,14 @@ public void testReplicasWithHighestBCSIDAreClosed() {
240274 .setReadOnly (true )
241275 .build ();
242276
243- Assertions . assertFalse (quasiClosedContainerHandler .handle (request ));
244- Assertions . assertFalse (quasiClosedContainerHandler .handle (readRequest ));
277+ assertFalse (quasiClosedContainerHandler .handle (request ));
278+ assertFalse (quasiClosedContainerHandler .handle (readRequest ));
245279 // verify close command was sent for replicas with sequence ID 1001, that
246280 // is dnTwo and dnThree
247- Mockito . verify (replicationManager , times (1 ))
281+ verify (replicationManager , times (1 ))
248282 .sendCloseContainerReplicaCommand (eq (containerInfo ), eq (dnTwo ),
249283 anyBoolean ());
250- Mockito . verify (replicationManager , times (1 ))
284+ verify (replicationManager , times (1 ))
251285 .sendCloseContainerReplicaCommand (eq (containerInfo ), eq (dnThree ),
252286 anyBoolean ());
253287 }
0 commit comments