View Javadoc
1   package com.atlassian.plugin.loaders;
2   
3   import com.atlassian.plugin.loaders.classloading.DeploymentUnit;
4   import com.atlassian.plugin.loaders.classloading.DirectoryPluginLoaderUtils;
5   import com.atlassian.plugin.loaders.classloading.Scanner;
6   import com.atlassian.plugin.test.PluginTestUtils;
7   import org.apache.commons.io.FileUtils;
8   import org.apache.commons.lang3.SystemUtils;
9   import org.junit.Assume;
10  import org.junit.Before;
11  import org.junit.Test;
12  
13  import java.io.File;
14  import java.io.IOException;
15  import java.util.Collection;
16  import java.util.Iterator;
17  
18  import static com.atlassian.plugin.loaders.classloading.DirectoryPluginLoaderUtils.PADDINGTON_JAR;
19  import static com.atlassian.plugin.loaders.classloading.DirectoryPluginLoaderUtils.POOH_JAR;
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNotNull;
23  import static org.junit.Assert.assertTrue;
24  
25  public class TestDirectoryScanner {
26      private File pluginsTestDir;
27  
28      @Before
29      public void createFillAndCleanTempPluginDirectory() throws IOException {
30          final DirectoryPluginLoaderUtils.ScannerDirectories directories = DirectoryPluginLoaderUtils.createFillAndCleanTempPluginDirectory();
31          pluginsTestDir = directories.pluginsTestDir;
32      }
33  
34      @Test
35      public void testNormalOperation() throws Exception {
36          File pluginsDirectory = pluginsTestDir;
37          Scanner scanner = new DirectoryScanner(pluginsDirectory);
38          scanner.scan();
39          Collection<DeploymentUnit> deployedUnits = scanner.getDeploymentUnits();
40          assertEquals(2, deployedUnits.size());
41  
42          // units should be returned ordered alphabetically
43          Iterator iterator = deployedUnits.iterator();
44          DeploymentUnit unit = (DeploymentUnit) iterator.next();
45          assertEquals(PADDINGTON_JAR, unit.getPath().getName());
46  
47          unit = (DeploymentUnit) iterator.next();
48          assertEquals(POOH_JAR, unit.getPath().getName());
49      }
50  
51      @Test
52      public void testSkipDot() throws Exception {
53          File pluginsDirectory = pluginsTestDir;
54          assertNotNull(File.createTempFile(".asdf", ".jar", pluginsDirectory));
55          Scanner scanner = new DirectoryScanner(pluginsDirectory);
56          scanner.scan();
57          Collection<DeploymentUnit> deployedUnits = scanner.getDeploymentUnits();
58          assertEquals(2, deployedUnits.size());
59  
60          // units should be returned ordered alphabetically
61          Iterator iterator = deployedUnits.iterator();
62          DeploymentUnit unit = (DeploymentUnit) iterator.next();
63          assertEquals(PADDINGTON_JAR, unit.getPath().getName());
64  
65          unit = (DeploymentUnit) iterator.next();
66          assertEquals(POOH_JAR, unit.getPath().getName());
67      }
68  
69      @Test
70      public void testRemove() {
71          File pluginsDirectory = pluginsTestDir;
72          File paddington = new File(pluginsDirectory, PADDINGTON_JAR);
73  
74          assertTrue(paddington.exists());
75  
76          DirectoryScanner scanner = new DirectoryScanner(pluginsDirectory);
77          scanner.scan();
78          assertEquals(2, scanner.getDeploymentUnits().size());
79          DeploymentUnit paddingtonUnit = scanner.locateDeploymentUnit(paddington);
80          scanner.remove(paddingtonUnit);
81  
82          assertFalse(paddington.exists());
83          assertEquals(1, scanner.getDeploymentUnits().size());
84      }
85  
86      @Test
87      public void testRemoveFromReadOnlySource() {
88          // Windows does not support read only directories
89          Assume.assumeTrue(!SystemUtils.IS_OS_WINDOWS);
90  
91          File pluginsDirectory = pluginsTestDir;
92          File paddington = new File(pluginsDirectory, PADDINGTON_JAR);
93          try {
94              // Disallow deleting of the file.
95              paddington.getParentFile().setWritable(false);
96  
97              assertTrue(paddington.exists());
98  
99              DirectoryScanner scanner = new DirectoryScanner(pluginsDirectory);
100             scanner.scan();
101             assertEquals(2, scanner.getDeploymentUnits().size());
102 
103             DeploymentUnit paddingtonUnit = scanner.locateDeploymentUnit(paddington);
104             scanner.remove(paddingtonUnit);
105 
106             // The file should still exist!
107             assertTrue(paddington.exists());
108             assertEquals(1, scanner.getDeploymentUnits().size());
109         } finally {
110             // Reset to writable when we are done
111             paddington.getParentFile().setWritable(true);
112         }
113     }
114 
115     @Test
116     public void testRemoveNoErrorWhenNotExist() {
117         File pluginsDirectory = pluginsTestDir;
118         File paddington = new File(pluginsDirectory, PADDINGTON_JAR);
119 
120         assertTrue(paddington.exists());
121 
122         DirectoryScanner scanner = new DirectoryScanner(pluginsDirectory);
123         scanner.scan();
124         assertEquals(2, scanner.getDeploymentUnits().size());
125         DeploymentUnit paddingtonUnit = scanner.locateDeploymentUnit(paddington);
126         assertTrue(paddington.exists());
127         assertTrue(paddington.delete());
128         scanner.remove(paddingtonUnit);
129 
130         assertFalse(paddington.exists());
131         assertEquals(1, scanner.getDeploymentUnits().size());
132     }
133 
134     @Test
135     public void testAddAndRemoveJarFromOutsideScanner() throws Exception {
136         File pluginsDirectory = pluginsTestDir;
137         File paddington = new File(pluginsDirectory, PADDINGTON_JAR);
138         File duplicate = new File(pluginsDirectory, "duplicate-test-plugin.jar");
139 
140         // make sure it's not there already from a bad test
141         if (duplicate.canRead())
142             duplicate.delete();
143 
144         // should be 2 to start with
145         Scanner scanner = new DirectoryScanner(pluginsDirectory);
146         scanner.scan();
147         assertEquals(2, scanner.getDeploymentUnits().size());
148 
149         // copy and scan - should have 3 files
150         FileUtils.copyFile(paddington, duplicate);
151         scanner.scan();
152         assertEquals(3, scanner.getDeploymentUnits().size());
153 
154         // delete and we should have 2!
155         duplicate.delete();
156         scanner.scan();
157         assertEquals(2, scanner.getDeploymentUnits().size());
158     }
159 
160     @Test
161     public void testModifyJar() throws Exception {
162         // Note windows is a piece of shit (can't modify files in the classpath) so
163         // we need to create a temporary directory outside the classpath where we can modify files freely.
164         File pluginsDirectory = pluginsTestDir;
165         File paddington = new File(pluginsDirectory, PADDINGTON_JAR);
166 
167         File testTempDirectory = PluginTestUtils.createTempDirectory(TestDirectoryScanner.class);
168 
169         File newPaddington = new File(testTempDirectory, PADDINGTON_JAR);
170         FileUtils.copyFile(paddington, newPaddington);
171 
172         // set the original mod date - must be a multiple of 1000 on most (all?) file systems
173         long originalModification = System.currentTimeMillis();
174         originalModification = originalModification - (originalModification % 1000) - 3000;
175         newPaddington.setLastModified(originalModification);
176         assertEquals(originalModification, newPaddington.lastModified());
177 
178         // should be 2 to start with
179         DirectoryScanner scanner = new DirectoryScanner(testTempDirectory);
180         scanner.scan();
181         assertEquals(1, scanner.getDeploymentUnits().size());
182 
183         DeploymentUnit newPaddingtonUnit = scanner.locateDeploymentUnit(newPaddington);
184         assertEquals(originalModification, newPaddingtonUnit.lastModified());
185 
186         // modify the JAR file
187         long secondModification = originalModification + 2000;
188         newPaddington.setLastModified(secondModification);
189         scanner.scan();
190 
191         newPaddingtonUnit = scanner.locateDeploymentUnit(newPaddington);
192         assertEquals(secondModification, newPaddingtonUnit.lastModified());
193     }
194 
195 }