| /* |
| * Copyright 2017 HugeGraph Authors |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with this |
| * work for additional information regarding copyright ownership. The ASF |
| * licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package com.baidu.hugegraph.unit.event; |
| |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import com.baidu.hugegraph.event.Event; |
| import com.baidu.hugegraph.event.EventHub; |
| import com.baidu.hugegraph.event.EventListener; |
| import com.baidu.hugegraph.testutil.Assert; |
| import com.baidu.hugegraph.unit.BaseUnitTest; |
| import com.google.common.collect.ImmutableList; |
| |
| public class EventHubTest extends BaseUnitTest { |
| |
| private static final int THREADS_NUM = 8; |
| |
| private EventHub eventHub = null; |
| |
| @BeforeClass |
| public static void init() { |
| EventHub.init(THREADS_NUM); |
| } |
| |
| @AfterClass |
| public static void clear() throws InterruptedException { |
| EventHub.destroy(30); |
| } |
| |
| @Before |
| public void setup() { |
| this.eventHub = new EventHub("test"); |
| Assert.assertEquals("test", this.eventHub.name()); |
| } |
| |
| @After |
| public void teardown() { |
| this.eventHub = null; |
| } |
| |
| private void wait100ms() { |
| try { |
| Thread.sleep(100); |
| } catch (InterruptedException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| @Test |
| public void testEventGetListenerNonResult() { |
| Assert.assertFalse(this.eventHub.containsListener("not-exist")); |
| Assert.assertEquals(0, this.eventHub.listeners("not-exist").size()); |
| } |
| |
| @Test |
| public void testEventAddListener() { |
| final String event = "event-test"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(1, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); |
| } |
| |
| @Test |
| public void testEventAddListenerTwice() { |
| final String event = "event-test"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener); |
| this.eventHub.listen(event, listener); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(2, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(1)); |
| } |
| |
| @Test |
| public void testEventRemoveListener() { |
| final String event = "event-test"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(1, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); |
| |
| Assert.assertEquals(1, this.eventHub.unlisten(event, listener)); |
| |
| Assert.assertFalse(this.eventHub.containsListener(event)); |
| Assert.assertEquals(0, this.eventHub.listeners(event).size()); |
| } |
| |
| @Test |
| public void testEventRemoveListenerButNonResult() { |
| final String event = "event-test"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(1, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); |
| |
| Assert.assertEquals(0, this.eventHub.unlisten(event, null)); |
| Assert.assertEquals(0, this.eventHub.unlisten("event-fake", listener)); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(1, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); |
| } |
| |
| @Test |
| public void testEventRemoveListenerOfOneInTwo() { |
| final String event1 = "event-test1"; |
| final String event2 = "event-test2"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event1, listener); |
| this.eventHub.listen(event2, listener); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event1)); |
| Assert.assertEquals(1, this.eventHub.listeners(event1).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event1).get(0)); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event2)); |
| Assert.assertEquals(1, this.eventHub.listeners(event2).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event2).get(0)); |
| |
| Assert.assertEquals(1, this.eventHub.unlisten(event1, listener)); |
| |
| Assert.assertFalse(this.eventHub.containsListener(event1)); |
| Assert.assertFalse(this.eventHub.containsListener(event1)); |
| Assert.assertEquals(0, this.eventHub.listeners(event1).size()); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event2)); |
| Assert.assertEquals(1, this.eventHub.listeners(event2).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event2).get(0)); |
| } |
| |
| @Test |
| public void testEventRemoveListenerByEvent() { |
| final String event = "event-test"; |
| |
| EventListener listener1 = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| EventListener listener2 = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener1); |
| this.eventHub.listen(event, listener2); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(2, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener1, this.eventHub.listeners(event).get(0)); |
| Assert.assertEquals(listener2, this.eventHub.listeners(event).get(1)); |
| |
| Assert.assertEquals(2, this.eventHub.unlisten(event).size()); |
| |
| Assert.assertFalse(this.eventHub.containsListener(event)); |
| Assert.assertEquals(0, this.eventHub.listeners(event).size()); |
| } |
| |
| @Test |
| public void testEventRemoveListenerByEventButNonResult() { |
| final String event = "event-test"; |
| |
| EventListener listener1 = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| EventListener listener2 = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener1); |
| this.eventHub.listen(event, listener2); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(2, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener1, this.eventHub.listeners(event).get(0)); |
| Assert.assertEquals(listener2, this.eventHub.listeners(event).get(1)); |
| |
| Assert.assertEquals(0, this.eventHub.unlisten("event-fake").size()); |
| |
| Assert.assertEquals(2, this.eventHub.listeners(event).size()); |
| } |
| |
| @Test |
| public void testEventRemoveListenerByEventOf2SameListener() { |
| final String event = "event-test"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event arg0) { |
| return null; |
| } |
| }; |
| |
| this.eventHub.listen(event, listener); |
| this.eventHub.listen(event, listener); |
| |
| Assert.assertTrue(this.eventHub.containsListener(event)); |
| Assert.assertEquals(2, this.eventHub.listeners(event).size()); |
| Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); |
| |
| Assert.assertEquals(2, this.eventHub.unlisten(event, listener)); |
| |
| Assert.assertFalse(this.eventHub.containsListener(event)); |
| Assert.assertEquals(0, this.eventHub.listeners(event).size()); |
| } |
| |
| @Test |
| public void testEventCallWithoutArg() { |
| final String call = "event-call"; |
| |
| this.eventHub.listen(call, event -> { |
| Assert.assertEquals(call, event.name()); |
| Assert.assertEquals(0, event.args().length); |
| return "fake-event-result"; |
| }); |
| |
| Assert.assertEquals("fake-event-result", this.eventHub.call(call)); |
| } |
| |
| @Test |
| public void testEventCallWithArg1() { |
| final String call = "event-call"; |
| |
| this.eventHub.listen(call, event -> { |
| Assert.assertEquals(call, event.name()); |
| |
| event.checkArgs(Float.class); |
| |
| Object[] args = event.args(); |
| Assert.assertEquals(1, args.length); |
| Assert.assertEquals(3.14f, args[0]); |
| |
| return "fake-event-result"; |
| }); |
| |
| Assert.assertEquals("fake-event-result", |
| this.eventHub.call(call, 3.14f)); |
| } |
| |
| @Test |
| public void testEventCallWithArg2() { |
| final String call = "event-call"; |
| |
| this.eventHub.listen(call, event -> { |
| Assert.assertEquals(call, event.name()); |
| |
| event.checkArgs(String.class, Integer.class); |
| |
| Object[] args = event.args(); |
| Assert.assertEquals(2, args.length); |
| Assert.assertEquals("fake-arg0", args[0]); |
| Assert.assertEquals(123, args[1]); |
| |
| return "fake-event-result"; |
| }); |
| |
| Assert.assertEquals("fake-event-result", |
| this.eventHub.call(call, "fake-arg0", 123)); |
| } |
| |
| @Test |
| public void testEventCallWithArg2ButArgNotMatched() { |
| final String call = "event-call"; |
| |
| this.eventHub.listen(call, event -> { |
| Assert.assertEquals(call, event.name()); |
| |
| event.checkArgs(String.class, Integer.class); |
| |
| Object[] args = event.args(); |
| Assert.assertEquals(2, args.length); |
| Assert.assertEquals("fake-arg0", args[0]); |
| Assert.assertEquals(123, args[1]); |
| |
| return "fake-event-result"; |
| }); |
| |
| Assert.assertThrows(IllegalArgumentException.class, () -> { |
| this.eventHub.call(call, "fake-arg0"); |
| }); |
| |
| Assert.assertThrows(IllegalArgumentException.class, () -> { |
| this.eventHub.call(call, "fake-arg0", 123, "456"); |
| }); |
| |
| Assert.assertThrows(IllegalArgumentException.class, () -> { |
| this.eventHub.call(call, 123, "fake-arg0"); |
| }); |
| |
| Assert.assertThrows(IllegalArgumentException.class, () -> { |
| this.eventHub.call(call, "fake-arg0", 123f); |
| }); |
| |
| Assert.assertThrows(IllegalArgumentException.class, () -> { |
| this.eventHub.call(call, "fake-arg0", "123"); |
| }); |
| } |
| |
| @Test |
| public void testEventNotify() { |
| final String notify = "event-notify"; |
| AtomicInteger count = new AtomicInteger(); |
| |
| this.eventHub.listen(notify, event -> { |
| Assert.assertEquals(notify, event.name()); |
| Assert.assertEquals(0, event.args().length); |
| count.incrementAndGet(); |
| return true; |
| }); |
| |
| this.eventHub.notify(notify); |
| |
| // Maybe should improve |
| this.wait100ms(); |
| |
| Assert.assertEquals(1, count.get()); |
| } |
| |
| @Test |
| public void testEventNotifyAny() { |
| AtomicInteger count = new AtomicInteger(); |
| |
| this.eventHub.listen(EventHub.ANY_EVENT, event -> { |
| Assert.assertTrue(ImmutableList.of("event1", "event2") |
| .contains(event.name())); |
| Assert.assertEquals(0, event.args().length); |
| count.incrementAndGet(); |
| return true; |
| }); |
| |
| this.eventHub.notify("event1"); |
| this.eventHub.notify("event2"); |
| |
| // Maybe should improve |
| this.wait100ms(); |
| |
| Assert.assertEquals(2, count.get()); |
| } |
| |
| @Test |
| public void testEventNotifyWithArg2() { |
| final String notify = "event-notify"; |
| AtomicInteger count = new AtomicInteger(); |
| |
| this.eventHub.listen(notify, event -> { |
| Assert.assertEquals(notify, event.name()); |
| |
| event.checkArgs(String.class, Integer.class); |
| |
| Object[] args = event.args(); |
| Assert.assertEquals("fake-arg0", args[0]); |
| Assert.assertEquals(123, args[1]); |
| |
| count.incrementAndGet(); |
| return true; |
| }); |
| |
| this.eventHub.notify(notify, "fake-arg0", 123); |
| |
| // Maybe should improve |
| this.wait100ms(); |
| |
| Assert.assertEquals(1, count.get()); |
| } |
| |
| @Test |
| public void testEventNotifyWithMultiThreads() throws InterruptedException { |
| final String notify = "event-notify"; |
| |
| EventListener listener1 = new EventListener() { |
| @Override |
| public Object event(Event event) { |
| Assert.assertEquals(notify, event.name()); |
| event.checkArgs(Integer.class); |
| return null; |
| } |
| }; |
| |
| EventListener listener2 = new EventListener() { |
| @Override |
| public Object event(Event event) { |
| Assert.assertEquals(notify, event.name()); |
| |
| event.checkArgs(Integer.class); |
| int i = (int) event.args()[0]; |
| if (i % 10000 == 0) { |
| System.out.println("On event '" + notify + "': " + i); |
| } |
| return null; |
| } |
| }; |
| |
| Thread listenerUpdateThread = new Thread(() -> { |
| // This will cost about 1s |
| for (int i = 0; i < 10; i++) { |
| this.eventHub.listen(notify, listener1); |
| if (!this.eventHub.listeners(notify).contains(listener2)) { |
| this.eventHub.listen(notify, listener2); |
| } |
| |
| this.wait100ms(); |
| |
| if (i % 2 == 0) { |
| this.eventHub.unlisten(notify); |
| } else { |
| this.eventHub.unlisten(notify, listener1); |
| } |
| } |
| }); |
| listenerUpdateThread.start(); |
| |
| runWithThreads(THREADS_NUM, () -> { |
| // This will cost about 1s ~ 2s |
| for (int i = 0; i < 10000 * 10; i++) { |
| this.eventHub.notify(notify, i); |
| Thread.yield(); |
| } |
| }); |
| |
| listenerUpdateThread.join(); |
| } |
| |
| @Test |
| public void testEventCallWithMultiThreads() { |
| final String call = "event-call"; |
| |
| EventListener listener = new EventListener() { |
| @Override |
| public Object event(Event event) { |
| Assert.assertEquals(call, event.name()); |
| |
| event.checkArgs(Integer.class); |
| int i = (int) event.args()[0]; |
| return i; |
| } |
| }; |
| |
| this.eventHub.listen(call, listener); |
| |
| runWithThreads(THREADS_NUM, () -> { |
| for (int i = 0; i < 10000 * 1000; i++) { |
| Assert.assertEquals(i, this.eventHub.call(call, i)); |
| } |
| }); |
| } |
| } |