Copilot commented on code in PR #11409:
URL: https://github.com/apache/ozone/pull/11409#discussion_r4184250808


##########
hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/TestSCMStateMachine.java:
##########
@@ -49,4 +67,101 @@ public void testRatisEventsRecording() throws Exception {
 
     metrics.unRegister();
   }
+  
+  @Test
+  public void testApplyTransactionFlushesAfterRecordingTransactionInfo() 
throws Exception {
+    SCMHADBTransactionBuffer buffer = mock(SCMHADBTransactionBuffer.class);
+    SCMStateMachine stateMachine = newStateMachine(buffer, 
succeedingInvoker());
+
+    CompletableFuture<Message> result = 
stateMachine.applyTransaction(newTransaction(7));
+
+    assertTrue(result.isDone() && !result.isCompletedExceptionally());
+    InOrder order = inOrder(buffer);
+    order.verify(buffer).beginApplyingTransaction();
+    
order.verify(buffer).updateLatestTrxInfo(TransactionInfo.valueOf(TermIndex.valueOf(1,
 7)));
+    order.verify(buffer).flushIfPendingLimitReached();
+    order.verify(buffer).endApplyingTransaction();
+  }
+
+  @Test
+  public void testFlushCheckedForEveryAppliedTransaction() throws Exception {
+    SCMHADBTransactionBuffer buffer = mock(SCMHADBTransactionBuffer.class);
+    SCMStateMachine stateMachine = newStateMachine(buffer, 
succeedingInvoker());
+
+    for (int i = 1; i <= 5; i++) {
+      stateMachine.applyTransaction(newTransaction(i));
+    }
+
+    verify(buffer, times(5)).flushIfPendingLimitReached();
+    verify(buffer, times(5)).endApplyingTransaction();
+  }
+  
+  @Test
+  public void testFlushStillCheckedWhenTransactionIsLogicallyRejected() throws 
Exception {
+    SCMHADBTransactionBuffer buffer = mock(SCMHADBTransactionBuffer.class);
+    ScmInvoker<?> invoker = mock(ScmInvoker.class);
+    when(invoker.invokeLocal(anyString(), any()))
+        .thenThrow(new SCMException("rejected", 
ResultCodes.FAILED_TO_FIND_CONTAINER));
+    SCMStateMachine stateMachine = newStateMachine(buffer, invoker);
+
+    CompletableFuture<Message> result = 
stateMachine.applyTransaction(newTransaction(3));
+
+    assertTrue(result.isCompletedExceptionally());
+    InOrder order = inOrder(buffer);
+    
order.verify(buffer).updateLatestTrxInfo(TransactionInfo.valueOf(TermIndex.valueOf(1,
 3)));
+    order.verify(buffer).flushIfPendingLimitReached();
+    order.verify(buffer).endApplyingTransaction();
+  }
+
+  @Test
+  public void testFlushFailureTerminatesAndClosesApplyingWindow() throws 
Exception {
+    ExitUtils.disableSystemExit();
+    try {
+      SCMHADBTransactionBuffer buffer = mock(SCMHADBTransactionBuffer.class);
+      doThrow(new IllegalStateException("injected flush 
failure")).when(buffer).flushIfPendingLimitReached();
+      SCMStateMachine stateMachine = newStateMachine(buffer, 
succeedingInvoker());
+
+      assertThrows(ExitUtils.ExitException.class, () -> 
stateMachine.applyTransaction(newTransaction(9)));
+
+      verify(buffer).endApplyingTransaction();
+    } finally {
+      ExitUtils.clear();
+    }
+  }
+
+  private static TransactionContext newTransaction(long index) throws 
Exception {
+    SCMRatisRequest request = SCMRatisRequest.of(RequestType.PIPELINE, "op", 
new Class<?>[0]);
+    RaftProtos.StateMachineLogEntryProto smLogEntry = 
RaftProtos.StateMachineLogEntryProto.newBuilder()
+        .setLogData(request.encode().getContent())
+        .build();
+    RaftProtos.LogEntryProto logEntry = RaftProtos.LogEntryProto.newBuilder()
+        .setTerm(1)
+        .setIndex(index)
+        .setStateMachineLogEntry(smLogEntry)
+        .build();
+    TransactionContext trx = mock(TransactionContext.class);
+    when(trx.getStateMachineLogEntry()).thenReturn(smLogEntry);
+    when(trx.getLogEntry()).thenReturn(logEntry);
+    return trx;
+  }
+
+  private static SCMStateMachine newStateMachine(SCMHADBTransactionBuffer 
buffer, ScmInvoker<?> invoker) {
+    StorageContainerManager scm = mock(StorageContainerManager.class);
+    when(scm.getMetrics()).thenReturn(SCMMetrics.create());

Review Comment:
   Each call to this helper registers another global `SCMMetrics` source, but 
these new tests never unregister it. Since the helper is used by four test 
methods, later methods can fail with a duplicate metrics-source registration 
(the existing test explicitly unregisters its instance). Use a Mockito metrics 
instance here instead of registering a real source.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to