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
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
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
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
169
170 verify(discardablePluginLoader, times(Iterables.size(pluginsToLoad))).discardPlugin(any(Plugin.class));
171 }
172
173 @Test
174 public void loadFoundPluginsWithGoodPluginThenDiscarded() throws Exception
175 {
176
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
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
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
217
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 }