From 86cce351a15fd5725264c7b4a044cc4cda76b00d Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:23:33 -0700 Subject: [PATCH 1/3] chore: make runUntil/runWhile return values consistent --- .../ModuleTestingEnvironment.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java b/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java index ee56eeb..8a74f07 100644 --- a/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java +++ b/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java @@ -215,7 +215,7 @@ public Set getDependencies() { * Setting dependencies for using by {@link ModuleTestingEnvironment}. * * @param dependencies the set of module names to load - * @throws IllegalStateException if you try'd setWorldGeneratorUrl after {@link + * @throws IllegalStateException if you tried setWorldGeneratorUrl after {@link * ModuleTestingEnvironment#setup()} */ void setDependencies(Set dependencies) { @@ -277,9 +277,10 @@ public void forceAndWaitForGeneration(Vector3ic blockPos) { /** * Runs tick() on the engine until f evaluates to true or DEFAULT_GAME_TIME_TIMEOUT milliseconds have passed in game time + * @return true if execution timed out */ - public void runUntil(Supplier f) { - runWhile(() -> !f.get()); + public boolean runUntil(Supplier f) { + return runWhile(() -> !f.get()); } /** @@ -293,9 +294,10 @@ public boolean runUntil(long gameTimeTimeoutMs, Supplier f) { /** * Runs tick() on the engine while f evaluates to true or until DEFAULT_GAME_TIME_TIMEOUT milliseconds have passed + * @return true if execution timed out */ - public void runWhile(Supplier f) { - runWhile(DEFAULT_GAME_TIME_TIMEOUT, f); + public boolean runWhile(Supplier f) { + return runWhile(DEFAULT_GAME_TIME_TIMEOUT, f); } /** From 148e66480950128df35a1860618f9eab0a00be3d Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:24:24 -0700 Subject: [PATCH 2/3] fix(runWhile): check for thread interruption and host shutdown --- .../ModuleTestingEnvironment.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java b/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java index 8a74f07..ef5f986 100644 --- a/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java +++ b/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java @@ -5,11 +5,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.common.util.concurrent.UncheckedTimeoutException; import org.joml.Vector3f; import org.joml.Vector3i; import org.joml.Vector3ic; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -313,18 +313,28 @@ public boolean runWhile(long gameTimeTimeoutMs, Supplier f) { while (f.get() && !timedOut) { Thread.yield(); + if (Thread.currentThread().isInterrupted()) { + throw new RuntimeException(String.format("Thread %s interrupted while waiting for %s.", + Thread.currentThread(), f)); + } for (TerasologyEngine terasologyEngine : engines) { - terasologyEngine.tick(); + boolean keepRunning = terasologyEngine.tick(); + if (!keepRunning && terasologyEngine == host) { + throw new RuntimeException("Host has shut down: " + host.getStatus()); + } } // handle safety timeout if (System.currentTimeMillis() - startRealTime > safetyTimeoutMs) { timedOut = true; - Assertions.assertTrue(false, "MTE Safety timeout exceeded. See setSafetyTimeoutMs()"); + // If we've passed the _safety_ timeout, throw an exception. + throw new UncheckedTimeoutException("MTE Safety timeout exceeded. See setSafetyTimeoutMs()"); } // handle game time timeout if (hostTime.getGameTimeInMs() - startGameTime > gameTimeTimeoutMs) { + // If we've passed the user-specified timeout but are still under the + // safety threshold, set timed-out status without throwing. timedOut = true; } } From 97503a67d247821545ac5653e310218524c004fa Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:37:00 -0700 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20lint=20=F0=9F=9A=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModuleTestingEnvironment.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java b/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java index ef5f986..2ce3b74 100644 --- a/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java +++ b/src/main/java/org/terasology/moduletestingenvironment/ModuleTestingEnvironment.java @@ -152,6 +152,10 @@ public class ModuleTestingEnvironment { public static final long DEFAULT_SAFETY_TIMEOUT = 60000; public static final long DEFAULT_GAME_TIME_TIMEOUT = 30000; private static final Logger logger = LoggerFactory.getLogger(ModuleTestingEnvironment.class); + + PathManager pathManager; + PathManagerProvider.Cleaner pathManagerCleaner; + private final Set dependencies = Sets.newHashSet("engine"); private String worldGeneratorUri = "moduletestingenvironment:dummy"; private boolean doneLoading; @@ -160,9 +164,6 @@ public class ModuleTestingEnvironment { private final List engines = Lists.newArrayList(); private long safetyTimeoutMs = DEFAULT_SAFETY_TIMEOUT; - PathManager pathManager; - PathManagerProvider.Cleaner pathManagerCleaner; - /** * Set up and start the engine as configured via this environment. *

@@ -434,9 +435,10 @@ private TerasologyEngine createEngine(TerasologyEngineBuilder terasologyEngineBu System.setProperty(ModuleManager.LOAD_CLASSPATH_MODULES_PROPERTY, "true"); // create temporary home paths so the MTE engines don't overwrite config/save files in your real home path + // FIXME: Collisions when attempting to do multiple simultaneous createEngines. + // (PathManager will need to be set in Context, not a process-wide global.) Path path = Files.createTempDirectory("terasology-mte-engine"); - PathManager pathManager = PathManager.getInstance(); - pathManager.useOverrideHomePath(path); + PathManager.getInstance().useOverrideHomePath(path); logger.info("Created temporary engine home path: {}", path); // JVM will delete these on normal termination but not exceptions.