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