优化
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package com.baiyue.iam.notification;
|
||||
|
||||
import com.baiyue.iam.notification.mapper.NotificationTaskMapper;
|
||||
import com.baiyue.iam.notification.service.NotificationScheduler;
|
||||
import com.baiyue.iam.notification.service.NotificationService;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class NotificationSchedulerRecoveryTest {
|
||||
@Test void recoverySqlRequiresTimeoutAndNoSuccessfulDeliveryEvidence() throws Exception {
|
||||
Update retry = NotificationTaskMapper.class
|
||||
.getMethod("retryTimedOutDispatchingWithoutDeliveryEvidence", java.time.LocalDateTime.class, java.time.LocalDateTime.class)
|
||||
.getAnnotation(Update.class);
|
||||
String retrySql = String.join(" ", retry.value()).replaceAll("\\s+", " ").toUpperCase();
|
||||
|
||||
assertThat(retrySql).contains("TASK.STATUS = 'DISPATCHING'", "TASK.UPDATED_AT <= #{STALEBEFORE}",
|
||||
"TASK.SENT_AT IS NULL", "RECIPIENT.STATUS = 'DELIVERED'", "IAM_NOTIFICATION_INBOX")
|
||||
.contains("SET TASK.STATUS = 'RETRYING'");
|
||||
|
||||
Update dead = NotificationTaskMapper.class
|
||||
.getMethod("deadTimedOutDispatchingWithDeliveryEvidence", java.time.LocalDateTime.class, java.time.LocalDateTime.class)
|
||||
.getAnnotation(Update.class);
|
||||
String deadSql = String.join(" ", dead.value()).replaceAll("\\s+", " ").toUpperCase();
|
||||
assertThat(deadSql).contains("SET TASK.STATUS = 'DEAD'", "TASK.STATUS = 'DISPATCHING'",
|
||||
"TASK.UPDATED_AT <= #{STALEBEFORE}", "RECIPIENT.STATUS = 'DELIVERED'", "IAM_NOTIFICATION_INBOX",
|
||||
"DISPATCH_TIMEOUT_WITH_DELIVERY_EVIDENCE");
|
||||
}
|
||||
|
||||
@Test void schedulerRecoversBeforeClaimingScheduledAndRetryingTasks() {
|
||||
NotificationService service = mock(NotificationService.class);
|
||||
NotificationScheduler scheduler = new NotificationScheduler();
|
||||
ReflectionTestUtils.setField(scheduler, "service", service);
|
||||
ReflectionTestUtils.setField(scheduler, "dispatchTimeoutSeconds", 300L);
|
||||
when(service.dueScheduledTaskIds()).thenReturn(List.of(11L));
|
||||
when(service.retryingTaskIds()).thenReturn(List.of(12L));
|
||||
|
||||
scheduler.dispatch();
|
||||
|
||||
var ordered = inOrder(service);
|
||||
ordered.verify(service).recoverTimedOutDispatching(300L);
|
||||
ordered.verify(service).dueScheduledTaskIds();
|
||||
ordered.verify(service).dispatchScheduled(11L);
|
||||
ordered.verify(service).retryingTaskIds();
|
||||
ordered.verify(service).dispatchRetrying(12L);
|
||||
}
|
||||
|
||||
@Test void oneTaskFailureDoesNotBlockRemainingTasksOrRetryQueue() {
|
||||
NotificationService service = mock(NotificationService.class);
|
||||
NotificationScheduler scheduler = new NotificationScheduler();
|
||||
ReflectionTestUtils.setField(scheduler, "service", service);
|
||||
ReflectionTestUtils.setField(scheduler, "dispatchTimeoutSeconds", 300L);
|
||||
when(service.dueScheduledTaskIds()).thenReturn(List.of(11L, 12L));
|
||||
when(service.dispatchScheduled(11L)).thenThrow(new IllegalStateException("failed"));
|
||||
when(service.retryingTaskIds()).thenReturn(List.of(13L));
|
||||
|
||||
scheduler.dispatch();
|
||||
|
||||
verify(service).dispatchScheduled(12L);
|
||||
verify(service).dispatchRetrying(13L);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user