3
3
import static io .javaoperatorsdk .operator .processing .KubernetesResourceUtils .getUID ;
4
4
import static org .assertj .core .api .Assertions .assertThat ;
5
5
import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
6
- import static org .mockito .Mockito .any ;
7
- import static org .mockito .Mockito .mock ;
8
- import static org .mockito .Mockito .never ;
9
- import static org .mockito .Mockito .timeout ;
10
- import static org .mockito .Mockito .times ;
11
- import static org .mockito .Mockito .verify ;
12
6
13
7
import io .fabric8 .kubernetes .client .CustomResource ;
14
8
import io .javaoperatorsdk .operator .TestUtils ;
15
9
import io .javaoperatorsdk .operator .processing .KubernetesResourceUtils ;
10
+ import io .javaoperatorsdk .operator .processing .event .Event ;
16
11
import io .javaoperatorsdk .operator .processing .event .EventHandler ;
17
12
import java .io .IOException ;
18
13
import java .util .List ;
14
+ import java .util .concurrent .CopyOnWriteArrayList ;
15
+ import java .util .concurrent .TimeUnit ;
16
+ import org .awaitility .Awaitility ;
17
+ import org .awaitility .core .ConditionFactory ;
18
+ import org .awaitility .core .ThrowingRunnable ;
19
19
import org .junit .jupiter .api .BeforeEach ;
20
- import org .junit .jupiter .api .Disabled ;
21
20
import org .junit .jupiter .api .Test ;
22
- import org .mockito .ArgumentCaptor ;
23
21
24
- @ Disabled ("Currently very flaky, will fix in https://github.com/java-operator-sdk/java-operator-sdk/issues/293" )
25
22
class TimerEventSourceTest {
26
23
27
24
public static final int INITIAL_DELAY = 50 ;
28
25
public static final int PERIOD = 50 ;
29
26
public static final int TESTING_TIME_SLACK = 40 ;
30
27
31
28
private TimerEventSource timerEventSource ;
32
- private EventHandler eventHandlerMock = mock ( EventHandler . class ) ;
29
+ private CapturingEventHandler eventHandlerMock ;
33
30
34
31
@ BeforeEach
35
32
public void setup () {
33
+ eventHandlerMock = new CapturingEventHandler ();
34
+
36
35
timerEventSource = new TimerEventSource ();
37
36
timerEventSource .setEventHandler (eventHandlerMock );
38
37
timerEventSource .start ();
@@ -41,73 +40,69 @@ public void setup() {
41
40
@ Test
42
41
public void producesEventsPeriodically () {
43
42
CustomResource customResource = TestUtils .testCustomResource ();
44
-
45
43
timerEventSource .schedule (customResource , INITIAL_DELAY , PERIOD );
46
44
47
- ArgumentCaptor <TimerEvent > argumentCaptor = ArgumentCaptor .forClass (TimerEvent .class );
48
- verify (eventHandlerMock , timeout (INITIAL_DELAY + PERIOD + TESTING_TIME_SLACK ).times (2 ))
49
- .handleEvent (argumentCaptor .capture ());
50
- List <TimerEvent > events = argumentCaptor .getAllValues ();
51
- assertThat (events )
52
- .allMatch (e -> e .getRelatedCustomResourceUid ().equals (getUID (customResource )));
53
- assertThat (events ).allMatch (e -> e .getEventSource ().equals (timerEventSource ));
45
+ untilAsserted (() -> {
46
+ assertThat (eventHandlerMock .events )
47
+ .hasSizeGreaterThan (2 );
48
+ assertThat (eventHandlerMock .events )
49
+ .allMatch (e -> e .getRelatedCustomResourceUid ().equals (getUID (customResource )));
50
+ assertThat (eventHandlerMock .events )
51
+ .allMatch (e -> e .getEventSource ().equals (timerEventSource ));
52
+ });
54
53
}
55
54
56
55
@ Test
57
- public void deRegistersPeriodicalEventSources () throws InterruptedException {
56
+ public void deRegistersPeriodicalEventSources () {
58
57
CustomResource customResource = TestUtils .testCustomResource ();
59
58
60
59
timerEventSource .schedule (customResource , INITIAL_DELAY , PERIOD );
61
- Thread .sleep (INITIAL_DELAY + PERIOD + TESTING_TIME_SLACK );
60
+ untilAsserted (() -> assertThat (eventHandlerMock .events ).hasSizeGreaterThan (1 ));
61
+
62
62
timerEventSource .eventSourceDeRegisteredForResource (getUID (customResource ));
63
- Thread .sleep (PERIOD + TESTING_TIME_SLACK );
64
63
65
- verify (eventHandlerMock , times (2 )).handleEvent (any ());
64
+ int size = eventHandlerMock .events .size ();
65
+ untilAsserted (() -> assertThat (eventHandlerMock .events ).hasSize (size ));
66
66
}
67
67
68
68
@ Test
69
- public void schedulesOnce () throws InterruptedException {
69
+ public void schedulesOnce () {
70
70
CustomResource customResource = TestUtils .testCustomResource ();
71
71
72
72
timerEventSource .scheduleOnce (customResource , PERIOD );
73
73
74
- Thread . sleep ( 2 * PERIOD + TESTING_TIME_SLACK );
75
- verify ( eventHandlerMock , times ( 1 )). handleEvent ( any ( ));
74
+ untilAsserted (() -> assertThat ( eventHandlerMock . events ). hasSize ( 1 ) );
75
+ untilAsserted ( PERIOD * 2 , 0 , () -> assertThat ( eventHandlerMock . events ). hasSize ( 1 ));
76
76
}
77
77
78
78
@ Test
79
- public void canCancelOnce () throws InterruptedException {
79
+ public void canCancelOnce () {
80
80
CustomResource customResource = TestUtils .testCustomResource ();
81
81
82
82
timerEventSource .scheduleOnce (customResource , PERIOD );
83
83
timerEventSource .cancelOnceSchedule (KubernetesResourceUtils .getUID (customResource ));
84
84
85
- Thread .sleep (PERIOD + TESTING_TIME_SLACK );
86
- verify (eventHandlerMock , never ()).handleEvent (any ());
85
+ untilAsserted (() -> assertThat (eventHandlerMock .events ).isEmpty ());
87
86
}
88
87
89
88
@ Test
90
- public void canRescheduleOnceEvent () throws InterruptedException {
89
+ public void canRescheduleOnceEvent () {
91
90
CustomResource customResource = TestUtils .testCustomResource ();
92
91
93
92
timerEventSource .scheduleOnce (customResource , PERIOD );
94
93
timerEventSource .scheduleOnce (customResource , 2 * PERIOD );
95
94
96
- Thread .sleep (PERIOD + TESTING_TIME_SLACK );
97
- verify (eventHandlerMock , never ()).handleEvent (any ());
98
- Thread .sleep (PERIOD + TESTING_TIME_SLACK );
99
- verify (eventHandlerMock , times (1 )).handleEvent (any ());
95
+ untilAsserted (PERIOD * 2 , PERIOD , () -> assertThat (eventHandlerMock .events ).hasSize (1 ));
100
96
}
101
97
102
98
@ Test
103
- public void deRegistersOnceEventSources () throws InterruptedException {
99
+ public void deRegistersOnceEventSources () {
104
100
CustomResource customResource = TestUtils .testCustomResource ();
105
101
106
102
timerEventSource .scheduleOnce (customResource , PERIOD );
107
103
timerEventSource .eventSourceDeRegisteredForResource (getUID (customResource ));
108
- Thread .sleep (PERIOD + TESTING_TIME_SLACK );
109
104
110
- verify ( eventHandlerMock , never ()). handleEvent ( any ());
105
+ untilAsserted (() -> assertThat ( eventHandlerMock . events ). isEmpty ());
111
106
}
112
107
113
108
@ Test
@@ -120,12 +115,42 @@ public void eventNotRegisteredIfStopped() throws IOException {
120
115
}
121
116
122
117
@ Test
123
- public void eventNotFiredIfStopped () throws InterruptedException , IOException {
118
+ public void eventNotFiredIfStopped () throws IOException {
124
119
timerEventSource .scheduleOnce (TestUtils .testCustomResource (), PERIOD );
125
120
timerEventSource .close ();
126
121
127
- Thread .sleep (PERIOD + TESTING_TIME_SLACK );
122
+ untilAsserted (() -> assertThat (eventHandlerMock .events ).isEmpty ());
123
+ }
124
+
125
+ private void untilAsserted (ThrowingRunnable assertion ) {
126
+ untilAsserted (INITIAL_DELAY , PERIOD , assertion );
127
+ }
128
+
129
+ private void untilAsserted (long initialDelay , long interval , ThrowingRunnable assertion ) {
130
+ long delay = INITIAL_DELAY ;
131
+ long period = PERIOD ;
132
+
133
+ ConditionFactory cf = Awaitility .await ();
134
+
135
+ if (initialDelay > 0 ) {
136
+ delay = initialDelay ;
137
+ cf = cf .pollDelay (initialDelay , TimeUnit .MILLISECONDS );
138
+ }
139
+ if (interval > 0 ) {
140
+ period = interval ;
141
+ cf = cf .pollInterval (interval , TimeUnit .MILLISECONDS );
142
+ }
143
+
144
+ cf = cf .atMost (delay + (period * 3 ), TimeUnit .MILLISECONDS );
145
+ cf .untilAsserted (assertion );
146
+ }
147
+
148
+ private static class CapturingEventHandler implements EventHandler {
149
+ private final List <Event > events = new CopyOnWriteArrayList <>();
128
150
129
- verify (eventHandlerMock , never ()).handleEvent (any ());
151
+ @ Override
152
+ public void handleEvent (Event event ) {
153
+ events .add (event );
154
+ }
130
155
}
131
156
}
0 commit comments