12
12
*/
13
13
package io .kubernetes .client .informer .cache ;
14
14
15
- import static org .junit .Assert .*;
16
- import static org .mockito .Mockito .*;
15
+ import static org .mockito .Mockito .any ;
16
+ import static org .mockito .Mockito .never ;
17
+ import static org .mockito .Mockito .times ;
18
+ import static org .mockito .Mockito .verify ;
19
+ import static org .mockito .Mockito .when ;
17
20
18
21
import io .kubernetes .client .informer .EventType ;
19
22
import io .kubernetes .client .informer .ListerWatcher ;
25
28
import io .kubernetes .client .util .CallGeneratorParams ;
26
29
import io .kubernetes .client .util .Watch ;
27
30
import io .kubernetes .client .util .Watchable ;
31
+ import java .time .Duration ;
28
32
import java .util .concurrent .atomic .AtomicReference ;
33
+ import org .awaitility .Awaitility ;
34
+ import org .hamcrest .core .IsEqual ;
29
35
import org .junit .Rule ;
30
36
import org .junit .Test ;
31
37
import org .junit .contrib .java .lang .system .EnvironmentVariables ;
@@ -43,15 +49,15 @@ public class ReflectorRunnableTest {
43
49
@ Mock private ListerWatcher <V1Pod , V1PodList > listerWatcher ;
44
50
45
51
@ Test
46
- public void testReflectorRunOnce () throws InterruptedException , ApiException {
52
+ public void testReflectorRunOnce () throws ApiException {
47
53
String mockResourceVersion = "1000" ;
48
54
when (listerWatcher .list (any ()))
49
55
.thenReturn (
50
56
new V1PodList ().metadata (new V1ListMeta ().resourceVersion (mockResourceVersion )));
51
57
when (listerWatcher .watch (any ()))
52
58
.then (
53
59
(v ) -> {
54
- Thread . sleep ( 999999L ); // block forever
60
+ Awaitility . await (). forever ( ); // block forever
55
61
return null ;
56
62
});
57
63
ReflectorRunnable <V1Pod , V1PodList > reflectorRunnable =
@@ -61,17 +67,17 @@ public void testReflectorRunOnce() throws InterruptedException, ApiException {
61
67
Thread thread = new Thread (reflectorRunnable ::run );
62
68
thread .setDaemon (true );
63
69
thread .start ();
64
-
65
- // sleep 1s for starting list-watch
66
- Thread .sleep (1000 );
67
-
68
- verify (deltaFIFO , times (1 )).replace (any (), any ());
69
- verify (deltaFIFO , never ()).add (any ());
70
- verify (listerWatcher , times (1 )).list (any ());
71
- verify (listerWatcher , times (1 )).watch (any ());
70
+ Awaitility .await ()
71
+ .atMost (Duration .ofSeconds (1 ))
72
+ .pollInterval (Duration .ofMillis (100 ))
73
+ .until (() -> mockResourceVersion .equals (reflectorRunnable .getLastSyncResourceVersion ()));
72
74
} finally {
73
75
reflectorRunnable .stop ();
74
76
}
77
+ verify (deltaFIFO , times (1 )).replace (any (), any ());
78
+ verify (deltaFIFO , never ()).add (any ());
79
+ verify (listerWatcher , times (1 )).list (any ());
80
+ verify (listerWatcher , times (1 )).watch (any ());
75
81
}
76
82
77
83
@ Test
@@ -98,18 +104,17 @@ public Watchable<V1Pod> watch(CallGeneratorParams params) throws ApiException {
98
104
Thread thread = new Thread (reflectorRunnable ::run );
99
105
thread .setDaemon (true );
100
106
thread .start ();
101
-
102
- Thread . sleep ( 1000 );
103
-
104
- assertTrue ( ((MockWatch <V1Pod >) watch ).isClosed ());
107
+ Awaitility . await ()
108
+ . atMost ( Duration . ofSeconds ( 1 ))
109
+ . pollInterval ( Duration . ofMillis ( 100 ))
110
+ . until (() -> ((MockWatch <V1Pod >) watch ).isClosed ());
105
111
} finally {
106
112
reflectorRunnable .stop ();
107
113
}
108
114
}
109
115
110
116
@ Test
111
- public void testReflectorRunnableCaptureListException ()
112
- throws ApiException , InterruptedException {
117
+ public void testReflectorRunnableCaptureListException () throws ApiException {
113
118
RuntimeException expectedException = new RuntimeException ("noxu" );
114
119
AtomicReference <Throwable > actualException = new AtomicReference <>();
115
120
when (listerWatcher .list (any ())).thenThrow (expectedException );
@@ -125,16 +130,17 @@ public void testReflectorRunnableCaptureListException()
125
130
Thread thread = new Thread (reflectorRunnable ::run );
126
131
thread .setDaemon (true );
127
132
thread .start ();
128
- Thread .sleep (1000 );
133
+ Awaitility .await ()
134
+ .atMost (Duration .ofSeconds (1 ))
135
+ .pollInterval (Duration .ofMillis (100 ))
136
+ .untilAtomic (actualException , new IsEqual <>(expectedException ));
129
137
} finally {
130
138
reflectorRunnable .stop ();
131
139
}
132
- assertEquals (expectedException , actualException .get ());
133
140
}
134
141
135
142
@ Test
136
- public void testReflectorRunnableCaptureWatchException ()
137
- throws ApiException , InterruptedException {
143
+ public void testReflectorRunnableCaptureWatchException () throws ApiException {
138
144
RuntimeException expectedException = new RuntimeException ("noxu" );
139
145
AtomicReference <Throwable > actualException = new AtomicReference <>();
140
146
when (listerWatcher .list (any ())).thenReturn (new V1PodList ().metadata (new V1ListMeta ()));
@@ -151,10 +157,62 @@ public void testReflectorRunnableCaptureWatchException()
151
157
Thread thread = new Thread (reflectorRunnable ::run );
152
158
thread .setDaemon (true );
153
159
thread .start ();
154
- Thread .sleep (1000 );
160
+ Awaitility .await ()
161
+ .atMost (Duration .ofSeconds (1 ))
162
+ .pollInterval (Duration .ofMillis (100 ))
163
+ .untilAtomic (actualException , new IsEqual <>(expectedException ));
164
+ } finally {
165
+ reflectorRunnable .stop ();
166
+ }
167
+ }
168
+
169
+ @ Test
170
+ public void testReflectorRelistShouldHonorLastSyncResourceVersion () {
171
+ String expectedResourceVersion = "999" ;
172
+ AtomicReference <String > requestedResourceVersion = new AtomicReference <>();
173
+ ReflectorRunnable <V1Pod , V1PodList > reflectorRunnable =
174
+ new ReflectorRunnable <>(
175
+ V1Pod .class ,
176
+ new ListerWatcher <V1Pod , V1PodList >() {
177
+ @ Override
178
+ public V1PodList list (CallGeneratorParams params ) throws ApiException {
179
+ requestedResourceVersion .set (params .resourceVersion );
180
+ return new V1PodList ()
181
+ .metadata (new V1ListMeta ().resourceVersion (expectedResourceVersion ));
182
+ }
183
+
184
+ @ Override
185
+ public Watchable <V1Pod > watch (CallGeneratorParams params ) throws ApiException {
186
+ throw new ApiException ("HTTP GONE" );
187
+ }
188
+ },
189
+ deltaFIFO );
190
+
191
+ // run the reflector twice, and check the requesting resource version at the second time.
192
+ // first run
193
+ try {
194
+ Thread thread = new Thread (reflectorRunnable ::run );
195
+ thread .setDaemon (true );
196
+ thread .start ();
197
+ Awaitility .await ()
198
+ .atMost (Duration .ofSeconds (1 ))
199
+ .pollInterval (Duration .ofMillis (100 ))
200
+ .until (
201
+ () -> expectedResourceVersion .equals (reflectorRunnable .getLastSyncResourceVersion ()));
202
+ } finally {
203
+ reflectorRunnable .stop ();
204
+ }
205
+ // second run
206
+ try {
207
+ Thread thread = new Thread (reflectorRunnable ::run );
208
+ thread .setDaemon (true );
209
+ thread .start ();
210
+ Awaitility .await ()
211
+ .atMost (Duration .ofSeconds (1 ))
212
+ .pollInterval (Duration .ofMillis (100 ))
213
+ .untilAtomic (requestedResourceVersion , new IsEqual <>(expectedResourceVersion ));
155
214
} finally {
156
215
reflectorRunnable .stop ();
157
216
}
158
- assertEquals (expectedException , actualException .get ());
159
217
}
160
218
}
0 commit comments