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