View Javadoc
1   package com.atlassian.plugin.loaders;
2   
3   import com.atlassian.plugin.JarPluginArtifact;
4   import com.atlassian.plugin.ModuleDescriptorFactory;
5   import com.atlassian.plugin.Plugin;
6   import com.atlassian.plugin.PluginArtifact;
7   import com.atlassian.plugin.PluginArtifactFactory;
8   import com.atlassian.plugin.event.PluginEventManager;
9   import com.atlassian.plugin.factories.PluginFactory;
10  import com.google.common.collect.ImmutableList;
11  import org.junit.After;
12  import org.junit.Before;
13  import org.junit.Rule;
14  import org.junit.Test;
15  import org.junit.contrib.java.lang.system.RestoreSystemProperties;
16  import org.junit.runner.RunWith;
17  import org.mockito.ArgumentCaptor;
18  import org.mockito.Captor;
19  import org.mockito.Mock;
20  import org.mockito.runners.MockitoJUnitRunner;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.net.URI;
25  import java.util.List;
26  
27  import static com.atlassian.plugin.loaders.RosterFilePluginLoader.getReferenceModePropertyName;
28  import static com.atlassian.plugin.loaders.TestRosterFileScanner.backdateFile;
29  import static com.atlassian.plugin.loaders.TestRosterFileScanner.writeRosterFile;
30  import static com.atlassian.plugin.test.Matchers.uriWithPath;
31  import static com.atlassian.plugin.test.PluginTestUtils.createTempDirectory;
32  import static com.google.common.collect.Iterables.getOnlyElement;
33  import static org.apache.commons.io.FileUtils.deleteQuietly;
34  import static org.hamcrest.MatcherAssert.assertThat;
35  import static org.hamcrest.Matchers.contains;
36  import static org.hamcrest.Matchers.instanceOf;
37  import static org.hamcrest.Matchers.is;
38  import static org.mockito.Matchers.any;
39  import static org.mockito.Matchers.argThat;
40  import static org.mockito.Matchers.same;
41  import static org.mockito.Mockito.mock;
42  import static org.mockito.Mockito.verify;
43  import static org.mockito.Mockito.when;
44  
45  @RunWith(MockitoJUnitRunner.class)
46  public class TestRosterFilePluginLoader {
47      @Rule
48      public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
49  
50      @Mock
51      private PluginFactory pluginFactory;
52      @Mock
53      private PluginArtifactFactory pluginArtifactFactory;
54      @Mock
55      private PluginEventManager pluginEventManager;
56      @Mock
57      private ModuleDescriptorFactory moduleDescriptorFactory;
58  
59      @Captor
60      private ArgumentCaptor<PluginArtifact> pluginArtifactCaptor;
61  
62      private File temporaryDirectory;
63      private File rosterFile;
64      private List<PluginFactory> pluginFactories;
65  
66      RosterFilePluginLoader rosterFilePluginLoader;
67  
68      @Before
69      public void setUp() throws Exception {
70          temporaryDirectory = createTempDirectory(TestRosterFilePluginLoader.class);
71          rosterFile = new File(temporaryDirectory, "rosterFile.list");
72          pluginFactories = ImmutableList.of(pluginFactory);
73          rosterFilePluginLoader = new RosterFilePluginLoader(rosterFile, pluginFactories, pluginArtifactFactory, pluginEventManager);
74      }
75  
76      @After
77      public void tearDown() throws Exception {
78          deleteQuietly(temporaryDirectory);
79      }
80  
81      @Test
82      public void rosterFileUsedToLoadAllPlugins() throws Exception {
83          final String pluginKey = "someKey";
84          final String jarName = "somePlugin.jar";
85          final File jarFile = getOnlyElement(writeRosterFile(rosterFile, jarName));
86          final PluginArtifact pluginArtifact = mock(PluginArtifact.class);
87          final Plugin plugin = mock(Plugin.class);
88  
89          final ArgumentCaptor<URI> uriCaptor = ArgumentCaptor.forClass(URI.class);
90          when(pluginArtifactFactory.create(uriCaptor.capture())).thenReturn(pluginArtifact);
91          configurePluginFactory(pluginKey, plugin, pluginArtifact);
92  
93          final Iterable<Plugin> plugins = rosterFilePluginLoader.loadAllPlugins(moduleDescriptorFactory);
94  
95          assertThat(plugins, contains(plugin));
96          final URI uri = uriCaptor.getValue();
97          assertThat(uri, uriWithPath(jarFile.getPath()));
98          verify(pluginFactory).canCreate(pluginArtifact);
99      }
100 
101     @Test
102     public void removePluginResultsInPluginUninstall() throws Exception {
103         final String pluginKey = "someKey";
104         final String oldJarName = "oldPlugin.jar";
105         final File oldJarFile = getOnlyElement(writeRosterFile(rosterFile, oldJarName));
106         // Since we need to scan again, backdate the file to ensure it appears new when rewritten
107         backdateFile(rosterFile);
108         final PluginArtifact oldPluginArtifact = mock(PluginArtifact.class);
109         final Plugin oldPlugin = mock(Plugin.class);
110         when(oldPlugin.isUninstallable()).thenReturn(true);
111 
112         when(pluginArtifactFactory.create(argThat(uriWithPath(oldJarFile.getPath())))).thenReturn(oldPluginArtifact);
113         configurePluginFactory(pluginKey, oldPlugin, oldPluginArtifact);
114 
115         rosterFilePluginLoader.loadAllPlugins(moduleDescriptorFactory);
116 
117         final String newJarName = "newPlugin.jar";
118         writeRosterFile(rosterFile, newJarName);
119 
120         // The plugin system calls PluginLoader#removePlugin when upgrading plugins, so it has to work in this scenario
121         rosterFilePluginLoader.loadFoundPlugins(moduleDescriptorFactory);
122         rosterFilePluginLoader.removePlugin(oldPlugin);
123 
124         verify(oldPlugin).uninstall();
125     }
126 
127     @Test
128     public void defaultRosterFilePluginLoaderForbidsReference() throws Exception {
129         final JarPluginArtifact jarPluginArtifact = obtainPluginArtifactFromRosterFilesDefaultFactory();
130 
131         assertThat(jarPluginArtifact.allowsReference(), is(false));
132     }
133 
134     @Test
135     public void propertyCanSetRosterFilePluginLoaderToAllowReference() throws Exception {
136         System.setProperty(getReferenceModePropertyName(), "PERMIT_REFERENCE");
137         final JarPluginArtifact jarPluginArtifact = obtainPluginArtifactFromRosterFilesDefaultFactory();
138 
139         assertThat(jarPluginArtifact.allowsReference(), is(true));
140     }
141 
142 
143     private JarPluginArtifact obtainPluginArtifactFromRosterFilesDefaultFactory() throws IOException {
144         final String pluginKey = "someKey";
145         final String jarName = "oldPlugin.jar";
146         final Plugin plugin = mock(Plugin.class);
147 
148         writeRosterFile(rosterFile, jarName);
149         when(pluginFactory.canCreate(any(PluginArtifact.class))).thenReturn(pluginKey);
150         when(pluginFactory.create(pluginArtifactCaptor.capture(), same(moduleDescriptorFactory))).thenReturn(plugin);
151 
152         rosterFilePluginLoader = new RosterFilePluginLoader(rosterFile, pluginFactories, pluginEventManager);
153         rosterFilePluginLoader.loadAllPlugins(moduleDescriptorFactory);
154 
155         final PluginArtifact pluginArtifact = pluginArtifactCaptor.getValue();
156         assertThat(pluginArtifact, instanceOf(JarPluginArtifact.class));
157         return (JarPluginArtifact) pluginArtifact;
158     }
159 
160     private void configurePluginFactory(final String pluginKey, final Plugin plugin, final PluginArtifact pluginArtifact) {
161         when(pluginFactory.canCreate(pluginArtifact)).thenReturn(pluginKey);
162         when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
163     }
164 }