View Javadoc

1   package com.atlassian.plugin.manager;
2   
3   import java.util.Arrays;
4   import java.util.HashSet;
5   import java.util.Set;
6   
7   import com.atlassian.plugin.MockPluginAccessor;
8   import com.atlassian.plugin.Plugin;
9   import com.atlassian.plugin.PluginAccessor;
10  import com.atlassian.plugin.PluginController;
11  import com.atlassian.plugin.PluginException;
12  import com.atlassian.plugin.PluginState;
13  import com.atlassian.plugin.exception.PluginExceptionInterception;
14  import com.atlassian.plugin.impl.StaticPlugin;
15  
16  import org.junit.Before;
17  import org.junit.Rule;
18  import org.junit.Test;
19  import org.junit.contrib.java.lang.system.RestoreSystemProperties;
20  import org.junit.runner.RunWith;
21  import org.mockito.Mock;
22  import org.mockito.runners.MockitoJUnitRunner;
23  
24  import static com.atlassian.plugin.util.PluginUtils.ATLASSIAN_PLUGINS_ENABLE_WAIT;
25  import static org.hamcrest.MatcherAssert.assertThat;
26  import static org.hamcrest.Matchers.is;
27  import static org.hamcrest.Matchers.lessThan;
28  import static org.mockito.Mockito.mock;
29  import static org.mockito.Mockito.verify;
30  import static org.mockito.Mockito.withSettings;
31  
32  @RunWith (MockitoJUnitRunner.class)
33  public class TestPluginEnabler
34  {
35      @Rule public RestoreSystemProperties restoreSystemProperties =
36              new RestoreSystemProperties(ATLASSIAN_PLUGINS_ENABLE_WAIT);
37  
38      @Mock private PluginAccessor pluginAccessor;
39      @Mock private PluginController pluginController;
40      @Mock private PluginExceptionInterception pluginExceptionInterception;
41  
42      private PluginEnabler pluginEnabler;
43  
44      @Before
45      public void setUp()
46      {
47          pluginEnabler = new PluginEnabler(pluginAccessor, pluginController, pluginExceptionInterception);
48      }
49  
50      @Test
51      public void enablePlugin()
52      {
53          final Plugin plugin = new MyPlugin("foo");
54  
55          pluginEnabler.enable(Arrays.asList(plugin));
56          assertThat(plugin.getPluginState(), is(PluginState.ENABLED));
57      }
58  
59      @Test
60      public void enableResolvesResolvablePlugins()
61      {
62          final Plugin resolvablePlugin = mock(Plugin.class, withSettings().extraInterfaces(Plugin.Resolvable.class));
63          pluginEnabler.enable(Arrays.asList(resolvablePlugin));
64          verify((Plugin.Resolvable) resolvablePlugin).resolve();
65          verify(resolvablePlugin).enable();
66      }
67  
68      @Test
69      public void customTimeoutTimesOut()
70      {
71          final Plugin plugin = new MyPlugin("foo")
72          {
73              @Override
74              protected PluginState enableInternal() throws PluginException
75              {
76                  return PluginState.ENABLING;
77              }
78          };
79  
80          System.setProperty(ATLASSIAN_PLUGINS_ENABLE_WAIT, "1");
81          final long start = System.currentTimeMillis();
82          pluginEnabler = new PluginEnabler(mock(PluginAccessor.class), mock(PluginController.class), pluginExceptionInterception);
83          pluginEnabler.enable(Arrays.asList(plugin));
84          final long end = System.currentTimeMillis();
85          assertThat(end - start, lessThan(5000L));
86          assertThat(plugin.getPluginState(), is(PluginState.ENABLING));
87      }
88  
89      @Test
90      public void enableMultiplePluginsWithDependencies()
91      {
92          final Plugin plugin = new MyPlugin("foo", "foo2");
93          final Plugin plugin2 = new MyPlugin("foo2", "foo3");
94          final Plugin plugin3 = new MyPlugin("foo3");
95  
96          pluginEnabler.enable(Arrays.asList(plugin, plugin2, plugin3));
97          assertThat(plugin.getPluginState(), is(PluginState.ENABLED));
98          assertThat(plugin2.getPluginState(), is(PluginState.ENABLED));
99          assertThat(plugin3.getPluginState(), is(PluginState.ENABLED));
100     }
101 
102     @Test
103     public void enablingPluginAlsoEnablesRequiredPluginsTransitively()
104     {
105         final Plugin plugin = new MyPlugin("foo", "foo2");
106         final Plugin plugin2 = new MyPlugin("foo2", "foo3");
107         final Plugin plugin3 = new MyPlugin("foo3");
108         final MockPluginAccessor accessor = new MockPluginAccessor();
109         accessor.addPlugin(plugin);
110         accessor.addPlugin(plugin2);
111         accessor.addPlugin(plugin3);
112 
113         pluginEnabler = new PluginEnabler(accessor, mock(PluginController.class), pluginExceptionInterception);
114 
115         // Enable a single plugin, which will recursively enable all deps
116         pluginEnabler.enableAllRecursively(Arrays.asList(plugin));
117         assertThat(plugin.getPluginState(), is(PluginState.ENABLED));
118         assertThat(plugin2.getPluginState(), is(PluginState.ENABLED));
119         assertThat(plugin3.getPluginState(), is(PluginState.ENABLED));
120     }
121 
122     @Test
123     public void canEnableCircularlyDependentPlugins()
124     {
125         final Plugin plugin = new MyPlugin("foo", "foo2");
126         final Plugin plugin2 = new MyPlugin("foo2", "foo3");
127         final Plugin plugin3 = new MyPlugin("foo3", "foo");
128 
129         pluginEnabler.enable(Arrays.asList(plugin, plugin2, plugin3));
130         assertThat(plugin.getPluginState(), is(PluginState.ENABLED));
131         assertThat(plugin2.getPluginState(), is(PluginState.ENABLED));
132         assertThat(plugin3.getPluginState(), is(PluginState.ENABLED));
133     }
134 
135     @Test
136     public void failedEnableIsPassedToPluginInterception()
137     {
138         final RuntimeException runtimeException = new RuntimeException();
139         final Plugin plugin = new MyPlugin("foo")
140         {
141             @Override
142             protected PluginState enableInternal() throws PluginException
143             {
144                 throw runtimeException;
145             }
146         };
147 
148         pluginEnabler.enable(Arrays.asList(plugin));
149         verify(pluginExceptionInterception).onEnableException(plugin, runtimeException);
150     }
151 
152     public static class MyPlugin extends StaticPlugin
153     {
154         private final Set<String> deps;
155 
156         public MyPlugin(final String key, final String... deps)
157         {
158             setKey(key);
159             this.deps = new HashSet<String>(Arrays.asList(deps));
160             setPluginState(PluginState.DISABLED);
161         }
162 
163         @Override
164         public Set<String> getRequiredPlugins()
165         {
166             return deps;
167         }
168     }
169 }