Skip to content

Commit 94c97b6

Browse files
committed
#2541 Replace waitLock with CountDownLatch for better thread handling
1 parent 0acc3fe commit 94c97b6

File tree

2 files changed

+38
-13
lines changed

2 files changed

+38
-13
lines changed

jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/App.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import com.jme3.app.state.VideoRecorderAppState;
3737
import com.jme3.math.ColorRGBA;
3838

39+
import java.util.function.Consumer;
40+
3941
/**
4042
* The app used for the tests. AppState(s) are used to inject the actual test code.
4143
* @author Richard Tingle (aka richtea)
@@ -46,10 +48,17 @@ public App(AppState... initialStates){
4648
super(initialStates);
4749
}
4850

51+
Consumer<Throwable> onError = (onError) -> {};
52+
4953
@Override
5054
public void simpleInitApp(){
5155
getViewPort().setBackgroundColor(ColorRGBA.Black);
5256
setTimer(new VideoRecorderAppState.IsoTimer(60));
5357
}
5458

59+
@Override
60+
public void handleError(String errMsg, Throwable t) {
61+
super.handleError(errMsg, t);
62+
onError.accept(t);
63+
}
5564
}

jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/TestDriver.java

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,12 @@
5757
import java.util.Collections;
5858
import java.util.Comparator;
5959
import java.util.List;
60+
import java.util.concurrent.CountDownLatch;
6061
import java.util.concurrent.Executor;
6162
import java.util.concurrent.Executors;
63+
import java.util.concurrent.TimeUnit;
64+
import java.util.logging.Level;
65+
import java.util.logging.Logger;
6266
import java.util.stream.Stream;
6367

6468
import static org.junit.jupiter.api.Assertions.fail;
@@ -72,6 +76,8 @@
7276
*/
7377
public class TestDriver extends BaseAppState{
7478

79+
private static final Logger logger = Logger.getLogger(TestDriver.class.getName());
80+
7581
public static final String IMAGES_ARE_DIFFERENT = "Images are different. (If you are running the test locally this is expected, images only reproducible on github CI infrastructure)";
7682

7783
public static final String IMAGES_ARE_DIFFERENT_SIZES = "Images are different sizes.";
@@ -94,7 +100,7 @@ public class TestDriver extends BaseAppState{
94100

95101
ScreenshotNoInputAppState screenshotAppState;
96102

97-
private final Object waitLock = new Object();
103+
private CountDownLatch waitLatch;
98104

99105
private final int tickToTerminateApp;
100106

@@ -113,23 +119,26 @@ public void update(float tpf){
113119
}
114120
if(tick >= tickToTerminateApp){
115121
getApplication().stop(true);
116-
synchronized (waitLock) {
117-
waitLock.notify(); // Release the wait
118-
}
122+
waitLatch.countDown();
119123
}
120124

121125
tick++;
122126
}
123127

124-
@Override protected void initialize(Application app){}
128+
@Override protected void initialize(Application app){
129+
((App)app).onError = error -> {
130+
logger.log(Level.WARNING, "Error in test application", error);
131+
waitLatch.countDown();
132+
};
133+
134+
}
125135

126136
@Override protected void cleanup(Application app){}
127137

128138
@Override protected void onEnable(){}
129139

130140
@Override protected void onDisable(){}
131141

132-
133142
/**
134143
* Boots up the application on a separate thread (blocks this thread) and then does the following:
135144
* - Takes screenshots on the requested frames
@@ -161,16 +170,23 @@ public static void bootAppForTest(TestType testType, AppSettings appSettings, St
161170
app.setSettings(appSettings);
162171
app.setShowSettings(false);
163172

173+
testDriver.waitLatch = new CountDownLatch(1);
164174
executor.execute(() -> app.start(JmeContext.Type.Display));
165175

166-
synchronized (testDriver.waitLock) {
167-
try {
168-
testDriver.waitLock.wait(10000); // Wait for the screenshot to be taken and application to stop
169-
Thread.sleep(1000); //give time for openGL is fully released before starting a new test (get random JVM crashes without this)
170-
} catch (InterruptedException e) {
171-
Thread.currentThread().interrupt();
172-
throw new RuntimeException(e);
176+
int maxWaitTimeMilliseconds = 45000;
177+
178+
try {
179+
boolean exitedProperly = testDriver.waitLatch.await(maxWaitTimeMilliseconds, TimeUnit.MILLISECONDS);
180+
181+
if(!exitedProperly){
182+
logger.warning("Test driver did not exit in " + maxWaitTimeMilliseconds + "ms. Timed out");
183+
app.stop(true);
173184
}
185+
186+
Thread.sleep(1000); //give time for openGL is fully released before starting a new test (get random JVM crashes without this)
187+
} catch (InterruptedException e) {
188+
Thread.currentThread().interrupt();
189+
throw new RuntimeException(e);
174190
}
175191

176192
//search the imageTempDir

0 commit comments

Comments
 (0)