Tests for shutdown and delay tasks

This commit is contained in:
jglrxavpok 2021-02-03 19:35:59 +01:00
parent c8e311855f
commit c9d2edef3a
2 changed files with 17 additions and 5 deletions

View File

@ -316,7 +316,7 @@ public class MinestomRootClassLoader extends HierarchyClassLoader {
* Tries to know which extension created this object, based on the classloader of the object. This can only check that the class of the object has been loaded * Tries to know which extension created this object, based on the classloader of the object. This can only check that the class of the object has been loaded
* by an extension. * by an extension.
* *
* While not perfect, this should detect any callback created extension code. * While not perfect, this should detect any callback created via extension code.
* It is possible this current version of the implementation might struggle with callbacks created through external * It is possible this current version of the implementation might struggle with callbacks created through external
* libraries, but as libraries are loaded separately for each extension, this *should not*(tm) be a problem. * libraries, but as libraries are loaded separately for each extension, this *should not*(tm) be a problem.
* *

View File

@ -3,7 +3,6 @@ package improveextensions.unloadcallbacks;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.event.EventCallback; import net.minestom.server.event.EventCallback;
import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.event.GlobalEventHandler;
import net.minestom.server.event.handler.EventHandler;
import net.minestom.server.event.instance.InstanceTickEvent; import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.extensions.Extension; import net.minestom.server.extensions.Extension;
import net.minestom.server.extras.selfmodification.MinestomRootClassLoader; import net.minestom.server.extras.selfmodification.MinestomRootClassLoader;
@ -11,6 +10,8 @@ import net.minestom.server.utils.time.TimeUnit;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.opentest4j.AssertionFailedError; import org.opentest4j.AssertionFailedError;
import java.util.concurrent.atomic.AtomicBoolean;
public class UnloadCallbacksExtension extends Extension { public class UnloadCallbacksExtension extends Extension {
private boolean ticked1 = false; private boolean ticked1 = false;
@ -62,18 +63,29 @@ public class UnloadCallbacksExtension extends Extension {
tickedScheduledNonTransient = false; tickedScheduledNonTransient = false;
tickedScheduledTransient = false; tickedScheduledTransient = false;
// TODO: set to transient task to avoid losing the task on termination AtomicBoolean executedDelayTaskAfterTerminate = new AtomicBoolean(false);
// because terminate is called just before unscheduling and removing event callbacks,
// the following task will never be executed, because it is not transient
MinecraftServer.getSchedulerManager().buildTask(() -> { MinecraftServer.getSchedulerManager().buildTask(() -> {
// Make sure callback is disabled executedDelayTaskAfterTerminate.set(true);
}).delay(100L, TimeUnit.MILLISECOND).schedule();
// this shutdown tasks will not be executed because it is not transient
MinecraftServer.getSchedulerManager().buildShutdownTask(() -> Assertions.fail("This shutdown task should be unloaded when the extension is")).schedule();
MinecraftServer.getSchedulerManager().buildTask(() -> {
// Make sure callbacks are disabled
try { try {
Assertions.assertFalse(ticked1, "ticked1 should be false because the callback has been unloaded"); Assertions.assertFalse(ticked1, "ticked1 should be false because the callback has been unloaded");
Assertions.assertFalse(ticked2, "ticked2 should be false because the callback has been unloaded"); Assertions.assertFalse(ticked2, "ticked2 should be false because the callback has been unloaded");
Assertions.assertFalse(tickedScheduledNonTransient, "tickedScheduledNonTransient should be false because the callback has been unloaded"); Assertions.assertFalse(tickedScheduledNonTransient, "tickedScheduledNonTransient should be false because the callback has been unloaded");
Assertions.assertTrue(tickedScheduledTransient, "tickedScheduledNonTransient should be true because the callback has NOT been unloaded"); Assertions.assertTrue(tickedScheduledTransient, "tickedScheduledNonTransient should be true because the callback has NOT been unloaded");
Assertions.assertFalse(executedDelayTaskAfterTerminate.get(), "executedDelayTaskAfterTerminate should be false because the callback has been unloaded before executing");
System.out.println("All tests passed.");
} catch (AssertionFailedError e) { } catch (AssertionFailedError e) {
e.printStackTrace(); e.printStackTrace();
} }
MinecraftServer.stopCleanly(); MinecraftServer.stopCleanly(); // TODO: fix deadlock which happens because stopCleanly waits on completion of scheduler tasks
}).delay(1L, TimeUnit.SECOND).makeTransient().schedule(); }).delay(1L, TimeUnit.SECOND).makeTransient().schedule();
} }
} }