99import io .javaoperatorsdk .operator .processing .event .Event ;
1010import io .javaoperatorsdk .operator .processing .event .internal .CustomResourceEvent ;
1111import io .javaoperatorsdk .operator .processing .event .internal .TimerEvent ;
12+ import io .javaoperatorsdk .operator .processing .event .internal .TimerEventSource ;
13+ import io .javaoperatorsdk .operator .processing .retry .GenericRetry ;
1214import io .javaoperatorsdk .operator .sample .simple .TestCustomResource ;
15+ import java .util .Arrays ;
1316import java .util .List ;
1417import java .util .UUID ;
1518import org .junit .jupiter .api .BeforeEach ;
@@ -23,14 +26,26 @@ class DefaultEventHandlerTest {
2326 public static final int SEPARATE_EXECUTION_TIMEOUT = 450 ;
2427 private EventDispatcher eventDispatcherMock = mock (EventDispatcher .class );
2528 private CustomResourceCache customResourceCache = new CustomResourceCache ();
26- private DefaultEventHandler defaultEventHandler =
27- new DefaultEventHandler (customResourceCache , eventDispatcherMock , "Test" , null );
2829 private DefaultEventSourceManager defaultEventSourceManagerMock =
2930 mock (DefaultEventSourceManager .class );
31+ private TimerEventSource retryTimerEventSourceMock = mock (TimerEventSource .class );
32+
33+ private DefaultEventHandler defaultEventHandler =
34+ new DefaultEventHandler (customResourceCache , eventDispatcherMock , "Test" , null );
35+
36+ private DefaultEventHandler defaultEventHandlerWithRetry =
37+ new DefaultEventHandler (
38+ customResourceCache ,
39+ eventDispatcherMock ,
40+ "Test" ,
41+ GenericRetry .defaultLimitedExponentialRetry ());
3042
3143 @ BeforeEach
3244 public void setup () {
45+ when (defaultEventSourceManagerMock .getRetryTimerEventSource ())
46+ .thenReturn (retryTimerEventSourceMock );
3347 defaultEventHandler .setDefaultEventSourceManager (defaultEventSourceManagerMock );
48+ defaultEventHandlerWithRetry .setDefaultEventSourceManager (defaultEventSourceManagerMock );
3449 }
3550
3651 @ Test
@@ -85,13 +100,57 @@ public void cleanUpAfterDeleteEvent() {
85100 String uid = customResource .getMetadata ().getUid ();
86101
87102 defaultEventHandler .handleEvent (event );
88- // todo awaitility?
103+
89104 waitMinimalTime ();
90105
91106 verify (defaultEventSourceManagerMock , times (1 )).cleanup (uid );
92107 assertThat (customResourceCache .getLatestResource (uid )).isNotPresent ();
93108 }
94109
110+ @ Test
111+ public void schedulesAnEventRetryOnException () {
112+ Event event = prepareCREvent ();
113+ TestCustomResource customResource = testCustomResource ();
114+
115+ ExecutionScope executionScope = new ExecutionScope (Arrays .asList (event ), customResource );
116+ PostExecutionControl postExecutionControl =
117+ PostExecutionControl .exceptionDuringExecution (new RuntimeException ("test" ));
118+
119+ defaultEventHandlerWithRetry .eventProcessingFinished (executionScope , postExecutionControl );
120+
121+ verify (retryTimerEventSourceMock , times (1 ))
122+ .scheduleOnce (eq (customResource ), eq (GenericRetry .DEFAULT_INITIAL_INTERVAL ));
123+ }
124+
125+ @ Test
126+ public void executesTheControllerInstantlyAfterErrorIfEventsBuffered () {
127+ Event event = prepareCREvent ();
128+ TestCustomResource customResource = testCustomResource ();
129+ customResource .getMetadata ().setUid (event .getRelatedCustomResourceUid ());
130+ ExecutionScope executionScope = new ExecutionScope (Arrays .asList (event ), customResource );
131+ PostExecutionControl postExecutionControl =
132+ PostExecutionControl .exceptionDuringExecution (new RuntimeException ("test" ));
133+
134+ // start processing an event
135+ defaultEventHandlerWithRetry .handleEvent (event );
136+ // buffer an another event
137+ defaultEventHandlerWithRetry .handleEvent (event );
138+ verify (eventDispatcherMock , timeout (SEPARATE_EXECUTION_TIMEOUT ).times (1 ))
139+ .handleExecution (any ());
140+
141+ defaultEventHandlerWithRetry .eventProcessingFinished (executionScope , postExecutionControl );
142+
143+ ArgumentCaptor <ExecutionScope > executionScopeArgumentCaptor =
144+ ArgumentCaptor .forClass (ExecutionScope .class );
145+ verify (eventDispatcherMock , timeout (SEPARATE_EXECUTION_TIMEOUT ).times (2 ))
146+ .handleExecution (executionScopeArgumentCaptor .capture ());
147+ List <ExecutionScope > allValues = executionScopeArgumentCaptor .getAllValues ();
148+ assertThat (allValues ).hasSize (2 );
149+ assertThat (allValues .get (1 ).getEvents ()).hasSize (2 );
150+ verify (retryTimerEventSourceMock , never ())
151+ .scheduleOnce (eq (customResource ), eq (GenericRetry .DEFAULT_INITIAL_INTERVAL ));
152+ }
153+
95154 private void waitMinimalTime () {
96155 try {
97156 Thread .sleep (50 );
0 commit comments