Skip to content

Commit 93abfee

Browse files
authored
Merge pull request #2124 from brendandburns/exec_test
Deflake the DefaultControllerTest.
2 parents 1bb926a + 02a2e79 commit 93abfee

File tree

1 file changed

+42
-12
lines changed

1 file changed

+42
-12
lines changed

extended/src/test/java/io/kubernetes/client/extended/controller/DefaultControllerTest.java

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@
2525
import java.util.List;
2626
import java.util.concurrent.ExecutorService;
2727
import java.util.concurrent.Executors;
28+
import java.util.concurrent.Semaphore;
2829
import java.util.concurrent.atomic.AtomicBoolean;
2930
import org.junit.After;
3031
import org.junit.Before;
3132
import org.junit.Test;
3233
import org.junit.runner.RunWith;
3334
import org.mockito.Mock;
35+
import org.mockito.invocation.InvocationOnMock;
3436
import org.mockito.junit.MockitoJUnitRunner;
37+
import org.mockito.stubbing.Answer;
3538

3639
@RunWith(MockitoJUnitRunner.class)
3740
public class DefaultControllerTest {
@@ -67,23 +70,34 @@ public void testStartingStoppingController() throws InterruptedException {
6770
testController.setWorkerThreadPool(Executors.newScheduledThreadPool(1));
6871

6972
Request request1 = new Request("test1");
70-
when(mockReconciler.reconcile(request1)).thenReturn(new Result(false));
73+
final Semaphore latch = new Semaphore(1);
74+
latch.acquire();
75+
when(mockReconciler.reconcile(request1))
76+
.thenAnswer(
77+
new Answer() {
78+
public Object answer(InvocationOnMock invocation) {
79+
latch.release();
80+
return new Result(false);
81+
}
82+
});
7183

7284
// emit an event when the controller hasn't started
7385
workQueue.add(request1);
86+
// I don't love sleeping here, but we're waiting for something we don't expect
87+
// to happen, so there's no good way to do it other than sleep (that I can think of)
7488
cooldown();
7589
verify(mockReconciler, times(0)).reconcile(request1);
7690

7791
controllerThead.submit(testController::run);
78-
79-
cooldown();
92+
latch.acquire();
8093
verify(mockReconciler, times(1)).reconcile(request1);
8194

8295
testController.shutdown();
8396
Request request2 = new Request("test2");
8497

8598
// emit an event after the controller has shutdown
8699
workQueue.add(request2);
100+
// as above wrt sleep
87101
cooldown();
88102
verify(mockReconciler, times(0)).reconcile(request2);
89103
}
@@ -92,8 +106,18 @@ public void testStartingStoppingController() throws InterruptedException {
92106
public void testControllerWontStartBeforeReady() throws InterruptedException {
93107

94108
Request request1 = new Request("test1");
95-
when(mockReconciler.reconcile(request1)).thenReturn(new Result(false));
109+
final Semaphore latch = new Semaphore(1);
96110

111+
when(mockReconciler.reconcile(request1))
112+
.thenAnswer(
113+
new Answer() {
114+
public Object answer(InvocationOnMock invocation) {
115+
latch.release();
116+
return new Result(false);
117+
}
118+
});
119+
120+
latch.acquire();
97121
AtomicBoolean ready = new AtomicBoolean(false);
98122
DefaultController testController =
99123
new DefaultController("", mockReconciler, workQueue, () -> ready.get());
@@ -105,12 +129,13 @@ public void testControllerWontStartBeforeReady() throws InterruptedException {
105129

106130
// emit an event when the controller hasn't been ready
107131
workQueue.add(request1);
132+
// As above wrt sleep
108133
cooldown();
109134

110135
verify(mockReconciler, times(0)).reconcile(request1);
111136

112137
ready.set(true);
113-
cooldown();
138+
latch.acquire();
114139
verify(mockReconciler, times(1)).reconcile(request1);
115140
}
116141

@@ -120,18 +145,23 @@ public void testControllerKeepsWorkingWhenReconcilerAbortsWithRuntimeException()
120145
AtomicBoolean aborts = new AtomicBoolean(true);
121146
AtomicBoolean resumed = new AtomicBoolean(false);
122147
List<Request> finishedRequests = new ArrayList<>();
148+
final Semaphore latch = new Semaphore(1);
123149
DefaultController testController =
124150
new DefaultController(
125151
"",
126152
new Reconciler() {
127153
@Override
128154
public Result reconcile(Request request) {
129-
if (aborts.get()) {
130-
throw new RuntimeException("Oops!!");
155+
try {
156+
if (aborts.get()) {
157+
throw new RuntimeException("Oops!!");
158+
}
159+
resumed.set(true);
160+
finishedRequests.add(request);
161+
return new Result(false);
162+
} finally {
163+
latch.release();
131164
}
132-
resumed.set(true);
133-
finishedRequests.add(request);
134-
return new Result(false);
135165
}
136166
},
137167
workQueue);
@@ -142,13 +172,13 @@ public Result reconcile(Request request) {
142172

143173
Request request1 = new Request("test1");
144174
workQueue.add(request1);
145-
cooldown();
175+
latch.acquire();
146176

147177
aborts.set(false);
148178
// emit another event, the previous one has been backoff'd
149179
Request request2 = new Request("test2");
150180
workQueue.add(request2);
151-
cooldown();
181+
latch.acquire();
152182
testController.shutdown();
153183

154184
assertTrue(resumed.get());

0 commit comments

Comments
 (0)