View Javadoc

1   package com.atlassian.plugin.loaders;
2   
3   import com.atlassian.plugin.*;
4   import com.atlassian.plugin.impl.UnloadablePlugin;
5   import com.google.common.collect.ImmutableList;
6   import com.google.common.collect.ImmutableSet;
7   import com.google.common.collect.Iterables;
8   
9   import org.junit.Before;
10  import org.junit.Test;
11  import org.junit.runner.RunWith;
12  import org.mockito.Mock;
13  import org.mockito.runners.MockitoJUnitRunner;
14  
15  import java.util.Set;
16  
17  import static org.hamcrest.Matchers.instanceOf;
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertSame;
20  import static org.junit.Assert.assertThat;
21  import static org.junit.Assert.assertTrue;
22  import static org.mockito.Matchers.any;
23  import static org.mockito.Mockito.doThrow;
24  import static org.mockito.Mockito.mock;
25  import static org.mockito.Mockito.times;
26  import static org.mockito.Mockito.verify;
27  import static org.mockito.Mockito.when;
28  
29  @RunWith(MockitoJUnitRunner.class)
30  public final class PermissionCheckingPluginLoaderTest
31  {
32      private PermissionCheckingPluginLoader permissionCheckingPluginLoader;
33  
34      @Mock
35      private PluginLoader pluginLoader;
36  
37      @Mock
38      private ModuleDescriptorFactory moduleDescriptorFactory;
39  
40      @Before
41      public void setUp()
42      {
43          permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(pluginLoader);
44      }
45  
46      @Test
47      public void loadAllPluginsWithEmptyCollectionOfPlugins()
48      {
49          when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of());
50          final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
51          assertTrue(Iterables.isEmpty(plugins));
52      }
53  
54      @Test
55      public void loadFoundPluginsWithEmptyCollectionOfPlugins()
56      {
57          when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of());
58          final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
59          assertTrue(Iterables.isEmpty(plugins));
60      }
61  
62      @Test
63      public void loadFoundPluginsWithPluginWithoutExecuteJavaPermissionAndNoJava()
64      {
65          final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), false, false);
66  
67          when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
68          final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
69  
70          assertEquals(1, Iterables.size(plugins));
71          assertSame(plugin, Iterables.get(plugins, 0));
72      }
73  
74      @Test
75      public void loadAllPluginsWithPluginWithoutExecuteJavaPermissionAndNoJava()
76      {
77          final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), false, false);
78  
79          when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
80          final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
81  
82          assertEquals(1, Iterables.size(plugins));
83          assertSame(plugin, Iterables.get(plugins, 0));
84      }
85  
86      @Test
87      public void loadFoundPluginsWithPluginWithoutExecuteJavaPermissionAndSomeJava()
88      {
89          final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, false);
90  
91          when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
92          final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
93  
94          assertEquals(1, Iterables.size(plugins));
95          assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
96      }
97  
98      @Test
99      public void loadAllPluginsWithPluginWithoutExecuteJavaPermissionAndSomeJava()
100     {
101         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, false);
102 
103         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
104         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
105 
106         assertEquals(1, Iterables.size(plugins));
107         assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
108     }
109 
110     @Test
111     public void loadAllPluginsWithUnloadablePluginThenRemoved()
112     {
113         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, false);
114 
115         doThrow(new PluginException("cannot find plugin")).when(pluginLoader).removePlugin(any(Plugin.class));
116         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
117         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
118 
119         assertEquals(1, Iterables.size(plugins));
120         Plugin loadedPlugin = Iterables.get(plugins, 0);
121         assertTrue(loadedPlugin instanceof UnloadablePlugin);
122         permissionCheckingPluginLoader.removePlugin(loadedPlugin);
123     }
124 
125     @Test
126     public void loadAllPluginsWithGoodPluginThenDiscarded() throws Exception
127     {
128         // We need to replace the object under test with a discardable loader. This could be structured better.
129         final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
130         permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
131 
132         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, true);
133 
134         when(discardablePluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
135         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
136         permissionCheckingPluginLoader.discardPlugin(plugin);
137         verify(discardablePluginLoader).discardPlugin(plugin);
138     }
139 
140     @Test
141     public void loadAllPluginsWithUnloadablePluginThenDiscarded()
142     {
143         // We need to replace the object under test with a discardable loader. This could be structured better.
144         final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
145         permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
146 
147         final PluginArtifactBackedPlugin containsJavaButNoPermission = newPlugin(ImmutableSet.<String>of(), true, false);
148         final PluginArtifactBackedPlugin hasSystemButNoPermission = newPlugin(ImmutableSet.<String>of(), false, false);
149         addModuleDescriptor(hasSystemButNoPermission, true);
150 
151 
152         final Iterable<Plugin> pluginsToLoad = ImmutableList.<Plugin>of(containsJavaButNoPermission, hasSystemButNoPermission);
153         when(discardablePluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(pluginsToLoad);
154 
155         final Iterable<Plugin> loadedPlugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
156         // The actual plugin should be discarded when loadAllPlugins ignores it
157         for(final Plugin plugin: pluginsToLoad)
158         {
159             verify(discardablePluginLoader).discardPlugin(plugin);
160         }
161 
162         assertEquals(Iterables.size(loadedPlugins), Iterables.size(pluginsToLoad));
163         for(final Plugin plugin : loadedPlugins)
164         {
165             assertThat(plugin, instanceOf(UnloadablePlugin.class));
166             permissionCheckingPluginLoader.discardPlugin(plugin);
167         }
168         // I know .times() is frowned on, but i can't find another good way to do this in Mockito - i want to say
169         // the only discard calls were from the loadAllPlugins() above.
170         verify(discardablePluginLoader, times(Iterables.size(pluginsToLoad))).discardPlugin(any(Plugin.class));
171     }
172 
173     @Test
174     public void loadFoundPluginsWithGoodPluginThenDiscarded() throws Exception
175     {
176         // We need to replace the object under test with a discardable loader. This could be structured better.
177         final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
178         permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
179 
180         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, true);
181 
182         when(discardablePluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
183         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
184         permissionCheckingPluginLoader.discardPlugin(plugin);
185         verify(discardablePluginLoader).discardPlugin(plugin);
186     }
187 
188     @Test
189     public void loadFoundPluginsWithUnloadablePluginThenDiscarded()
190     {
191         // We need to replace the object under test with a discardable loader. This could be structured better.
192         final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
193         permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
194 
195         final PluginArtifactBackedPlugin containsJavaButNoPermission = newPlugin(ImmutableSet.<String>of(), true, false);
196         final PluginArtifactBackedPlugin hasSystemButNoPermission = newPlugin(ImmutableSet.<String>of(), false, false);
197         addModuleDescriptor(hasSystemButNoPermission, true);
198 
199 
200         final Iterable<Plugin> pluginsToLoad = ImmutableList.<Plugin>of(containsJavaButNoPermission, hasSystemButNoPermission);
201         when(discardablePluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(pluginsToLoad);
202 
203         final Iterable<Plugin> loadedPlugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
204         // The actual plugin should be discarded when loadFoundPlugins ignores it
205         for(final Plugin plugin: pluginsToLoad)
206         {
207             verify(discardablePluginLoader).discardPlugin(plugin);
208         }
209 
210         assertEquals(Iterables.size(loadedPlugins), Iterables.size(pluginsToLoad));
211         for(final Plugin plugin : loadedPlugins)
212         {
213             assertThat(plugin, instanceOf(UnloadablePlugin.class));
214             permissionCheckingPluginLoader.discardPlugin(plugin);
215         }
216         // I know .times() is frowned on, but i can't find another good way to do this in Mockito - i want to say
217         // the only discard calls were from the loadFoundPlugins() above.
218         verify(discardablePluginLoader, times(Iterables.size(pluginsToLoad))).discardPlugin(any(Plugin.class));
219     }
220 
221     @Test
222     public void loadAllPluginsWithPluginWithNoPermissionsAndSystemModules() throws Exception
223     {
224         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), false, false);
225 
226         addModuleDescriptor(plugin, true);
227 
228         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
229         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
230 
231         assertEquals(1, Iterables.size(plugins));
232         assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
233     }
234 
235     @Test
236     public void loadAllPluginsWithPluginWithNoPermissionsAndNoSystemModules() throws Exception
237     {
238         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), false, false);
239 
240         addModuleDescriptor(plugin, false);
241 
242         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
243         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
244 
245         assertEquals(1, Iterables.size(plugins));
246         assertSame(plugin, Iterables.get(plugins, 0));
247     }
248 
249     @Test
250     public void loadFoundPluginsWithPluginWithJavaPermissionAndSomeJava() throws Exception
251     {
252         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(Permissions.EXECUTE_JAVA), true, false);
253 
254         when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
255         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
256 
257         assertEquals(1, Iterables.size(plugins));
258         assertSame(plugin, Iterables.get(plugins, 0));
259     }
260 
261     @Test
262     public void loadAllPluginsWithPluginWithCreateSystemModulePermissionsAndSystemModules() throws Exception
263     {
264         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(Permissions.CREATE_SYSTEM_MODULES), false, false);
265 
266         addModuleDescriptor(plugin, true);
267 
268         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
269         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
270 
271         assertEquals(1, Iterables.size(plugins));
272         assertSame(plugin, Iterables.get(plugins, 0));
273     }
274 
275     @Test
276     public void loadAllPluginsWithPluginWithCreateSystemModulePermissionsAndNoSystemModules() throws Exception
277     {
278         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(Permissions.CREATE_SYSTEM_MODULES), false, false);
279 
280         addModuleDescriptor(plugin, false);
281 
282         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
283         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
284 
285         assertEquals(1, Iterables.size(plugins));
286         assertSame(plugin, Iterables.get(plugins, 0));
287     }
288 
289     @Test
290     public void loadFoundPluginsWithPluginWithJavaPermissionAndNoJava() throws Exception
291     {
292         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(Permissions.EXECUTE_JAVA), false, false);
293 
294         when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
295         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
296 
297         assertEquals(1, Iterables.size(plugins));
298         assertSame(plugin, Iterables.get(plugins, 0));
299     }
300 
301     @Test
302     public void loadAllPluginsWithPluginWithJavaPermissionAndNoJava() throws Exception
303     {
304         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(Permissions.EXECUTE_JAVA), false, false);
305 
306         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
307         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
308 
309         assertEquals(1, Iterables.size(plugins));
310         assertSame(plugin, Iterables.get(plugins, 0));
311     }
312 
313     @Test
314     public void loadFoundPluginsWithPluginWithAllPermissionsAndSomeJava() throws Exception
315     {
316         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, true);
317 
318         when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
319         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
320 
321         assertEquals(1, Iterables.size(plugins));
322         assertSame(plugin, Iterables.get(plugins, 0));
323     }
324 
325     @Test
326     public void loadAllPluginsWithPluginWithAllPermissionsAndSomeJava() throws Exception
327     {
328         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), true, true);
329 
330         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
331         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
332 
333         assertEquals(1, Iterables.size(plugins));
334         assertSame(plugin, Iterables.get(plugins, 0));
335     }
336 
337     @Test
338     public void loadAllPluginsWithPluginWithAllPermissionsAndSystemModules() throws Exception
339     {
340         final PluginArtifactBackedPlugin plugin = newPlugin(ImmutableSet.<String>of(), false, true);
341         addModuleDescriptor(plugin, true);
342 
343         when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.<Plugin>of(plugin));
344         final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
345 
346         assertEquals(1, Iterables.size(plugins));
347         assertSame(plugin, Iterables.get(plugins, 0));
348     }
349 
350     private void addModuleDescriptor(PluginArtifactBackedPlugin plugin, boolean system)
351     {
352         ModuleDescriptor descriptor = mock(ModuleDescriptor.class);
353         when(descriptor.getKey()).thenReturn("foo");
354         when(descriptor.isSystemModule()).thenReturn(system);
355         when(plugin.getModuleDescriptors()).thenReturn(ImmutableList.<ModuleDescriptor<?>>of(descriptor));
356     }
357 
358     private PluginArtifactBackedPlugin newPlugin(Set<String> permissions, boolean hasJava, boolean hasAllPermissions)
359     {
360         final PluginArtifactBackedPlugin plugin = mockPlugin(PluginArtifactBackedPlugin.class);
361         final PluginArtifact pluginArtifact = mock(PluginArtifact.class);
362         when(plugin.hasAllPermissions()).thenReturn(hasAllPermissions);
363         when(plugin.getActivePermissions()).thenReturn(permissions);
364         when(plugin.getPluginArtifact()).thenReturn(pluginArtifact);
365         when(pluginArtifact.containsJavaExecutableCode()).thenReturn(hasJava);
366         return plugin;
367     }
368 
369     private <P extends Plugin> P mockPlugin(Class<P> type)
370     {
371         P mock = mock(type);
372         when(mock.getKey()).thenReturn("test-plugin-key");
373         when(mock.getName()).thenReturn("Test Plugin");
374         PluginInformation pluginInformation = mock(PluginInformation.class);
375         when(mock.getPluginInformation()).thenReturn(pluginInformation);
376         return mock;
377     }
378 }