summaryrefslogtreecommitdiffstats
path: root/src/test
diff options
context:
space:
mode:
authorWesley Wolfe <weswolf@aol.com>2012-06-13 21:28:13 -0500
committerWesley Wolfe <weswolf@aol.com>2012-06-13 23:01:03 -0500
commit9e73a8887c5f142abbc7a324df17d167b2427478 (patch)
tree81c8f495b0474b3f77802f9e2f5967c9c4783de1 /src/test
parentef1748ef6823ddc036bbaa64013ec70e7145a63a (diff)
downloadbukkit-9e73a8887c5f142abbc7a324df17d167b2427478.tar
bukkit-9e73a8887c5f142abbc7a324df17d167b2427478.tar.gz
bukkit-9e73a8887c5f142abbc7a324df17d167b2427478.tar.lz
bukkit-9e73a8887c5f142abbc7a324df17d167b2427478.tar.xz
bukkit-9e73a8887c5f142abbc7a324df17d167b2427478.zip
Support asynchronous events; Addresses BUKKIT-1212
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/org/bukkit/TestServer.java48
-rw-r--r--src/test/java/org/bukkit/event/TestEvent.java19
-rw-r--r--src/test/java/org/bukkit/plugin/PluginManagerTest.java118
3 files changed, 185 insertions, 0 deletions
diff --git a/src/test/java/org/bukkit/TestServer.java b/src/test/java/org/bukkit/TestServer.java
new file mode 100644
index 00000000..63e8aeff
--- /dev/null
+++ b/src/test/java/org/bukkit/TestServer.java
@@ -0,0 +1,48 @@
+package org.bukkit;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+
+
+public class TestServer implements InvocationHandler {
+ private static interface MethodHandler {
+ Object handle(TestServer server, Object[] args);
+ }
+ private static final Constructor<? extends Server> constructor;
+ private static final HashMap<Method, MethodHandler> methods = new HashMap<Method, MethodHandler>();
+ static {
+ try {
+ methods.put(Server.class.getMethod("isPrimaryThread"),
+ new MethodHandler() {
+ public Object handle(TestServer server, Object[] args) {
+ return Thread.currentThread().equals(server.creatingThread);
+ }
+ });
+ constructor = Proxy.getProxyClass(Server.class.getClassLoader(), Server.class).asSubclass(Server.class).getConstructor(InvocationHandler.class);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ private Thread creatingThread = Thread.currentThread();
+ private TestServer() {};
+
+ public static Server getInstance() {
+ try {
+ return constructor.newInstance(new TestServer());
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) {
+ MethodHandler handler = methods.get(method);
+ if (handler != null) {
+ return handler.handle(this, args);
+ }
+ throw new UnsupportedOperationException(String.valueOf(method));
+ }
+}
diff --git a/src/test/java/org/bukkit/event/TestEvent.java b/src/test/java/org/bukkit/event/TestEvent.java
new file mode 100644
index 00000000..c06dfe94
--- /dev/null
+++ b/src/test/java/org/bukkit/event/TestEvent.java
@@ -0,0 +1,19 @@
+package org.bukkit.event;
+
+
+public class TestEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+
+ public TestEvent(boolean async) {
+ super(async);
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/test/java/org/bukkit/plugin/PluginManagerTest.java b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
new file mode 100644
index 00000000..b5cb7408
--- /dev/null
+++ b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
@@ -0,0 +1,118 @@
+package org.bukkit.plugin;
+
+import static junit.framework.Assert.*;
+
+import org.bukkit.Server;
+import org.bukkit.TestServer;
+import org.bukkit.command.SimpleCommandMap;
+import org.bukkit.event.Event;
+import org.bukkit.event.TestEvent;
+import org.junit.Test;
+
+public class PluginManagerTest {
+ private class MutableObject {
+ volatile Object value = null;
+ }
+
+ final Server server = TestServer.getInstance();
+ final SimpleCommandMap commandMap = new SimpleCommandMap(server);
+ final PluginManager pm = new SimplePluginManager(server, commandMap);
+ final MutableObject store = new MutableObject();
+
+ @Test
+ public void testAsyncSameThread() {
+ final Event event = new TestEvent(true);
+ try {
+ pm.callEvent(event);
+ } catch (IllegalStateException ex) {
+ assertEquals(event.getEventName() + " cannot be triggered asynchronously from primary server thread.", ex.getMessage());
+ return;
+ }
+ throw new IllegalStateException("No exception thrown");
+ }
+
+ @Test
+ public void testSyncSameThread() {
+ final Event event = new TestEvent(false);
+ pm.callEvent(event);
+ }
+
+ @Test
+ public void testAsyncLocked() throws InterruptedException {
+ final Event event = new TestEvent(true);
+ Thread secondThread = new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ synchronized (pm) {
+ pm.callEvent(event);
+ }
+ } catch (Throwable ex) {
+ store.value = ex;
+ }
+ }});
+ secondThread.start();
+ secondThread.join();
+ assertTrue(store.value instanceof IllegalStateException);
+ assertEquals(event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.", ((Throwable) store.value).getMessage());
+ }
+
+ @Test
+ public void testAsyncUnlocked() throws InterruptedException {
+ final Event event = new TestEvent(true);
+ Thread secondThread = new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ pm.callEvent(event);
+ } catch (Throwable ex) {
+ store.value = ex;
+ }
+ }});
+ secondThread.start();
+ secondThread.join();
+ if (store.value != null) {
+ throw new RuntimeException((Throwable) store.value);
+ }
+ }
+
+ @Test
+ public void testSyncUnlocked() throws InterruptedException {
+ final Event event = new TestEvent(false);
+ Thread secondThread = new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ pm.callEvent(event);
+ } catch (Throwable ex) {
+ store.value = ex;
+ }
+ }});
+ secondThread.start();
+ secondThread.join();
+ if (store.value != null) {
+ throw new RuntimeException((Throwable) store.value);
+ }
+ }
+
+ @Test
+ public void testSyncLocked() throws InterruptedException {
+ final Event event = new TestEvent(false);
+ Thread secondThread = new Thread(
+ new Runnable() {
+ public void run() {
+ try {
+ synchronized (pm) {
+ pm.callEvent(event);
+ }
+ } catch (Throwable ex) {
+ store.value = ex;
+ }
+ }});
+ secondThread.start();
+ secondThread.join();
+ if (store.value != null) {
+ throw new RuntimeException((Throwable) store.value);
+ }
+ }
+}