View Javadoc
1   package com.atlassian.plugin.manager;
2   
3   import com.atlassian.plugin.event.PluginEventManager;
4   import com.atlassian.plugin.event.events.PluginTransactionStartEvent;
5   import com.atlassian.plugin.event.events.PluginTransactionEndEvent;
6   import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
7   import com.atlassian.plugin.event.listeners.RecordingListener;
8   import com.google.common.base.Predicates;
9   import org.junit.Before;
10  import org.junit.Test;
11  
12  import java.util.concurrent.atomic.AtomicBoolean;
13  import java.util.concurrent.atomic.AtomicInteger;
14  
15  import static junit.framework.TestCase.assertTrue;
16  import static org.hamcrest.MatcherAssert.assertThat;
17  import static org.hamcrest.Matchers.contains;
18  import static org.hamcrest.Matchers.equalTo;
19  import static org.hamcrest.Matchers.is;
20  
21  
22  public class TestPluginTransactionContext {
23  
24      private PluginTransactionContext pluginTransactionContext;
25      private RecordingListener listener;
26  
27      @Before
28      public void setUp() throws Exception {
29          listener = new RecordingListener(
30                  PluginTransactionStartEvent.class,
31                  PluginTransactionEndEvent.class
32          );
33          final PluginEventManager pluginEventManager = new DefaultPluginEventManager();
34          pluginEventManager.register(listener);
35          this.pluginTransactionContext = new PluginTransactionContext(pluginEventManager);
36      }
37  
38      private static class SomeEventFoo {}
39  
40      private static class SomeEventBar {}
41  
42      private static class SomeEventBaz {}
43  
44      @Test
45      public void testStartStopLevelAndEvents() {
46          final SomeEventBaz beforeTransaction = new SomeEventBaz();
47          final SomeEventBar inTransaction1 = new SomeEventBar();
48          final SomeEventFoo inTransaction2 = new SomeEventFoo();
49          final SomeEventFoo inTransaction3 = new SomeEventFoo();
50          final SomeEventBaz afterTransaction = new SomeEventBaz();
51  
52          pluginTransactionContext.addEvent(beforeTransaction);
53          assertThat(pluginTransactionContext.getLevel(), equalTo(0));
54          pluginTransactionContext.start();
55          assertThat(pluginTransactionContext.getLevel(), equalTo(1));
56          pluginTransactionContext.addEvent(inTransaction1);
57          pluginTransactionContext.start();
58          assertThat(pluginTransactionContext.getLevel(), equalTo(2));
59          pluginTransactionContext.addEvent(inTransaction2);
60          pluginTransactionContext.stop();
61          assertThat(pluginTransactionContext.getLevel(), equalTo(1));
62          pluginTransactionContext.addEvent(inTransaction3);
63          pluginTransactionContext.stop();
64          assertThat(pluginTransactionContext.getLevel(), equalTo(0));
65          pluginTransactionContext.addEvent(afterTransaction);
66  
67          assertThat(listener.getEventClasses(), contains(
68                  PluginTransactionStartEvent.class,
69                  PluginTransactionEndEvent.class));
70  
71          final PluginTransactionEndEvent pluginTransactionStopEvent = (PluginTransactionEndEvent)listener.getEvents().get(1);
72          assertThat(pluginTransactionStopEvent.numberOfEvents(), equalTo(3));
73          assertTrue(pluginTransactionStopEvent.hasAnyEventOfTypeMatching(SomeEventBar.class, someEventBar -> someEventBar.equals(inTransaction1)));
74          assertTrue(pluginTransactionStopEvent.hasAnyEventOfTypeMatching(SomeEventFoo.class, someEventFoo -> someEventFoo.equals(inTransaction2)));
75          assertTrue(pluginTransactionStopEvent.hasAnyEventOfTypeMatching(SomeEventFoo.class, someEventFoo -> someEventFoo.equals(inTransaction3)));
76      }
77  
78      @Test
79      public void testNestedWrap() {
80          final AtomicInteger callbackRuns = new AtomicInteger(0);
81          assertThat(pluginTransactionContext.getLevel(), equalTo(0));
82          pluginTransactionContext.wrap(() -> {
83              assertThat(pluginTransactionContext.getLevel(), equalTo(1));
84              pluginTransactionContext.wrap(() -> {
85                  assertThat(pluginTransactionContext.getLevel(), equalTo(2));
86                  callbackRuns.incrementAndGet();
87              });
88              assertThat(pluginTransactionContext.getLevel(), equalTo(1));
89              callbackRuns.incrementAndGet();
90          });
91          assertThat(callbackRuns.get(), equalTo(2));
92      }
93  
94      @Test
95      public void testTransactionsInThreadContext() throws Exception {
96          assertThat(pluginTransactionContext.getLevel(), equalTo(0));
97          pluginTransactionContext.start();
98          assertThat(pluginTransactionContext.getLevel(), equalTo(1));
99          pluginTransactionContext.addEvent(new SomeEventFoo());
100         pluginTransactionContext.addEvent(new SomeEventFoo());
101         pluginTransactionContext.start();
102         assertThat(pluginTransactionContext.getLevel(), equalTo(2));
103         final AtomicBoolean threadRunWithNoException = new AtomicBoolean(false);
104         final Thread t = new Thread(() -> {
105             assertThat(pluginTransactionContext.getLevel(), equalTo(0));
106             pluginTransactionContext.start();
107             assertThat(pluginTransactionContext.getLevel(), equalTo(1));
108             pluginTransactionContext.addEvent(new SomeEventBar());
109             pluginTransactionContext.addEvent(new SomeEventBar());
110             pluginTransactionContext.stop();
111             assertThat(pluginTransactionContext.getLevel(), equalTo(0));
112             threadRunWithNoException.set(true);
113         });
114         t.start();
115         t.join();
116         assertThat(threadRunWithNoException.get(), is(true));
117         pluginTransactionContext.stop();
118         pluginTransactionContext.stop();
119 
120         assertThat(listener.getEventClasses(), contains(
121                 PluginTransactionStartEvent.class,
122                 PluginTransactionStartEvent.class,
123                 PluginTransactionEndEvent.class,
124                 PluginTransactionEndEvent.class));
125 
126         final PluginTransactionEndEvent pluginTransactionStopEventOtherThread = (PluginTransactionEndEvent) listener.getEvents().get(2);
127         final PluginTransactionEndEvent pluginTransactionStopEventCurrentThread = (PluginTransactionEndEvent) listener.getEvents().get(3);
128 
129         assertThat(pluginTransactionStopEventOtherThread.threadId(), equalTo(t.getId()));
130         assertThat(pluginTransactionStopEventCurrentThread.threadId(), equalTo(Thread.currentThread().getId()));
131 
132         assertThat(pluginTransactionStopEventOtherThread.hasAnyEventOfTypeMatching(SomeEventBar.class, Predicates.alwaysTrue()), equalTo(true));
133         assertThat(pluginTransactionStopEventOtherThread.hasAnyEventOfTypeMatching(SomeEventFoo.class, Predicates.alwaysTrue()), equalTo(false));
134         assertThat(pluginTransactionStopEventCurrentThread.hasAnyEventOfTypeMatching(SomeEventFoo.class, Predicates.alwaysTrue()), equalTo(true));
135         assertThat(pluginTransactionStopEventCurrentThread.hasAnyEventOfTypeMatching(SomeEventBar.class, Predicates.alwaysTrue()), equalTo(false));
136     }
137 }