1 package org.apache.maven.wrapper;
2
3 import static org.junit.Assert.assertTrue;
4 import static org.junit.Assert.fail;
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.when;
27
28 import java.io.BufferedWriter;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.net.URI;
32 import java.net.URISyntaxException;
33 import java.net.URL;
34 import java.nio.charset.StandardCharsets;
35 import java.nio.file.FileVisitResult;
36 import java.nio.file.Files;
37 import java.nio.file.Path;
38 import java.nio.file.Paths;
39 import java.nio.file.SimpleFileVisitor;
40 import java.nio.file.attribute.BasicFileAttributes;
41 import java.nio.file.attribute.FileTime;
42 import java.util.jar.JarOutputStream;
43 import java.util.jar.Manifest;
44 import java.util.zip.ZipEntry;
45 import java.util.zip.ZipException;
46 import java.util.zip.ZipOutputStream;
47
48 import org.junit.Assert;
49 import org.junit.Before;
50 import org.junit.Rule;
51 import org.junit.Test;
52 import org.junit.rules.TemporaryFolder;
53
54
55
56
57 public class InstallerTest
58 {
59 @Rule
60 public TemporaryFolder tempFolder = TemporaryFolder.builder().assureDeletion().build();
61
62 private Path testDir;
63
64 private Installer install;
65
66 private Path distributionDir;
67
68 private Path zipStore;
69
70 private Path mavenHomeDir;
71
72 private Path zipDestination;
73
74 private WrapperConfiguration configuration = new WrapperConfiguration();
75
76 private Downloader download;
77
78 private PathAssembler pathAssembler;
79
80 private PathAssembler.LocalDistribution localDistribution;
81
82 @Before
83 public void setup()
84 throws Exception
85 {
86 testDir = tempFolder.getRoot().toPath();
87
88 configuration.setZipBase( PathAssembler.PROJECT_STRING );
89 configuration.setZipPath( Paths.get( "someZipPath" ) );
90 configuration.setDistributionBase( PathAssembler.MAVEN_USER_HOME_STRING );
91 configuration.setDistributionPath( Paths.get( "someDistPath" ) );
92 configuration.setDistribution( new URI( "http://server/maven-0.9.zip" ) );
93 configuration.setAlwaysDownload( false );
94 configuration.setAlwaysUnpack( false );
95 distributionDir = testDir.resolve( "someDistPath" );
96 mavenHomeDir = distributionDir.resolve( "maven-0.9" );
97 zipStore = testDir.resolve( "zips" );
98 zipDestination = zipStore.resolve( "maven-0.9.zip" );
99
100 download = mock( Downloader.class );
101 pathAssembler = mock( PathAssembler.class );
102 localDistribution = mock( PathAssembler.LocalDistribution.class );
103
104 when( localDistribution.getZipFile() ).thenReturn( zipDestination );
105 when( localDistribution.getDistributionDir() ).thenReturn( distributionDir );
106 when( pathAssembler.getDistribution( configuration ) ).thenReturn( localDistribution );
107
108 install = new Installer( download, pathAssembler );
109 }
110
111 private void createTestZip( Path zipDestination )
112 throws Exception
113 {
114 Path explodedZipDir = testDir.resolve( "explodedZip" );
115 Files.createDirectories( explodedZipDir );
116 Files.createDirectories( zipDestination.getParent() );
117 Path mavenScript = explodedZipDir.resolve( "maven-0.9/bin/mvn" );
118 Path mavenLib = explodedZipDir.resolve( "maven-0.9/lib/maven-core-0.9.jar" );
119 Files.createDirectories( mavenScript.getParent() );
120 Files.createDirectories( mavenLib.getParent() );
121 try ( BufferedWriter writer = Files.newBufferedWriter( mavenScript, StandardCharsets.UTF_8 ) )
122 {
123 writer.write( "something" );
124 }
125 try ( OutputStream os = Files.newOutputStream( mavenLib );
126 JarOutputStream jar = new JarOutputStream( os, new Manifest() ) )
127 {
128 jar.putNextEntry( new ZipEntry( "test" ) );
129 jar.closeEntry();
130 }
131
132 zipTo( explodedZipDir, zipDestination );
133 }
134
135 public void testCreateDist()
136 throws Exception
137 {
138 Path homeDir = install.createDist( configuration );
139
140 Assert.assertEquals( mavenHomeDir, homeDir );
141 Assert.assertTrue( Files.isDirectory( homeDir ) );
142 Assert.assertTrue( Files.exists( homeDir.resolve( "bin/mvn" ) ) );
143 Assert.assertTrue( Files.exists( zipDestination ) );
144
145 Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
146 Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
147 Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
148
149
150
151 }
152
153 @Test
154 public void testCreateDistWithExistingDistribution()
155 throws Exception
156 {
157
158 createTestZip( zipDestination );
159 Files.createDirectories( mavenHomeDir );
160 Path someFile = mavenHomeDir.resolve( "some-file" );
161 touchFile( someFile );
162
163 Path homeDir = install.createDist( configuration );
164
165 Assert.assertEquals( mavenHomeDir, homeDir );
166 Assert.assertTrue( Files.isDirectory( mavenHomeDir ) );
167 Assert.assertTrue( Files.exists( homeDir.resolve( "some-file" ) ) );
168 Assert.assertTrue( Files.exists( zipDestination ) );
169
170 Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
171 Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
172 Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
173 }
174
175 @Test
176 public void testCreateDistWithExistingDistAndZipAndAlwaysUnpackTrue()
177 throws Exception
178 {
179
180 createTestZip( zipDestination );
181 Files.createDirectories( mavenHomeDir );
182 Path garbage = mavenHomeDir.resolve( "garbage" );
183 touchFile( garbage );
184 configuration.setAlwaysUnpack( true );
185
186 Path homeDir = install.createDist( configuration );
187
188 Assert.assertEquals( mavenHomeDir, homeDir );
189 Assert.assertTrue( Files.isDirectory( mavenHomeDir ) );
190 Assert.assertFalse( Files.exists( homeDir.resolve( "garbage" ) ) );
191 Assert.assertTrue( Files.exists( zipDestination ) );
192
193 Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
194 Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
195 Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
196 }
197
198 @Test
199 public void testCreateDistWithExistingZipAndDistAndAlwaysDownloadTrue()
200 throws Exception
201 {
202
203 createTestZip( zipDestination );
204 Path garbage = mavenHomeDir.resolve( "garbage" );
205 touchFile( garbage );
206 configuration.setAlwaysUnpack( true );
207
208 Path homeDir = install.createDist( configuration );
209
210 Assert.assertEquals( mavenHomeDir, homeDir );
211 Assert.assertTrue( Files.isDirectory( mavenHomeDir ) );
212 Assert.assertTrue( Files.exists( homeDir.resolve( "bin/mvn" ) ) );
213 Assert.assertFalse( Files.exists( homeDir.resolve( "garbage" ) ) );
214 Assert.assertTrue( Files.exists( zipDestination ) );
215
216 Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
217 Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
218 Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
219
220
221
222 }
223
224 @Test
225 public void testZipSlip()
226 throws URISyntaxException
227 {
228 URL resource = getClass().getClassLoader().getResource( "zip-slip.zip" );
229 Path zipSlip = Paths.get( resource.toURI() );
230 when( localDistribution.getZipFile() ).thenReturn( zipSlip );
231 configuration.setAlwaysUnpack( true );
232
233 try
234 {
235 install.createDist( configuration );
236 fail( "Should fail as it contains a zip slip." );
237 }
238 catch ( Exception ex )
239 {
240 assertTrue( ex instanceof ZipException );
241 }
242 }
243
244 public void zipTo( final Path directoryToZip, final Path zipFile )
245 throws IOException
246 {
247
248 try ( OutputStream fos = Files.newOutputStream( zipFile ); ZipOutputStream zos = new ZipOutputStream( fos ) )
249 {
250
251 Files.walkFileTree( directoryToZip, new SimpleFileVisitor<Path>()
252 {
253 @Override
254
255 public FileVisitResult preVisitDirectory( final Path dir, final BasicFileAttributes attrs )
256 throws IOException
257 {
258
259 if ( !directoryToZip.equals( dir ) )
260 {
261 zos.putNextEntry( new ZipEntry( directoryToZip.relativize( dir ).toString() + "/" ) );
262 zos.closeEntry();
263 }
264 return FileVisitResult.CONTINUE;
265 }
266
267 @Override
268
269 public FileVisitResult visitFile( final Path file, final BasicFileAttributes attrs )
270 throws IOException
271 {
272 zos.putNextEntry( new ZipEntry( directoryToZip.relativize( file ).toString() ) );
273 Files.copy( file, zos );
274 zos.closeEntry();
275 return FileVisitResult.CONTINUE;
276 }
277 } );
278 }
279 }
280
281 private void touchFile( Path file )
282 throws IOException
283 {
284 if ( Files.notExists( file ) )
285 {
286 Files.createDirectories( file.getParent() );
287 Files.createFile( file );
288 }
289 Files.setLastModifiedTime( file, FileTime.fromMillis( System.currentTimeMillis() ) );
290 }
291
292 }