package jnpf.dmsService; import jnpf.dmsEntity.fenfa.DmsBupinghengRetry; import jnpf.dmsMapper.DmsBupinghengRetryMapper; import jnpf.exception.DataException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.List; import static org.mockito.Mockito.*; import static org.mockito.ArgumentMatchers.*; @ExtendWith(MockitoExtension.class) class DmsBupinghengRetryJobTest { @Mock DmsBupinghengRetryMapper mapper; @Mock DmsWenjianBupinghengService service; @InjectMocks DmsBupinghengRetryJob job; DmsBupinghengRetry task(int attempts) { DmsBupinghengRetry task = new DmsBupinghengRetry(); task.setTenantId("tenant"); task.setDocumentId("doc"); task.setVersion(2L); task.setAttempts(attempts); when(mapper.selectPending(100, 5)).thenReturn(List.of(task)); return task; } void claimed(DmsBupinghengRetry task) { when(mapper.claim(eq(task), anyString(), eq(5))).thenReturn(1); when(mapper.selectClaim(eq(task), anyString())).thenReturn(task); } @Test void losingClaimDoesNotExecute() { task(1); job.retryPending(); verifyNoInteractions(service); verify(mapper, never()).finish(any(), any(), anyBoolean(), any(), anyInt()); } @Test void successfulRetryClosesPersistentTask() throws Exception { DmsBupinghengRetry task = task(1); claimed(task); job.retryPending(); verify(service).executeScheduled("tenant", "doc", 2L); verify(mapper).finish(eq(task), anyString(), eq(true), isNull(), eq(0)); } @Test void transientFailureIsRetriedWithBackoff() throws Exception { DmsBupinghengRetry task = task(2); claimed(task); when(service.executeScheduled(any(), any(), any())).thenThrow(new IllegalStateException("connection unavailable")); job.retryPending(); verify(mapper).finish(eq(task), anyString(), eq(false), eq("connection unavailable"), eq(600)); } @Test void businessConflictRequiresManualCorrection() throws Exception { DmsBupinghengRetry task = task(1); claimed(task); when(service.executeScheduled(any(), any(), any())).thenThrow(new DataException("副本状态冲突")); job.retryPending(); verify(mapper).finish(eq(task), anyString(), eq(true), eq("副本状态冲突"), eq(300)); } @Test void retryLimitStopsTransientFailure() throws Exception { DmsBupinghengRetry task = task(5); claimed(task); when(service.executeScheduled(any(), any(), any())).thenThrow(new IllegalStateException("timeout")); job.retryPending(); verify(mapper).finish(eq(task), anyString(), eq(true), eq("timeout"), eq(3600)); } }