View Javadoc
1   package org.apache.maven.wrapper;
2   
3   import static org.junit.Assert.assertTrue;
4   import static org.junit.Assert.fail;
5   
6   /*
7    * Licensed to the Apache Software Foundation (ASF) under one
8    * or more contributor license agreements.  See the NOTICE file
9    * distributed with this work for additional information
10   * regarding copyright ownership.  The ASF licenses this file
11   * to you under the Apache License, Version 2.0 (the
12   * "License"); you may not use this file except in compliance
13   * with the License.  You may obtain a copy of the License at
14   *
15   *  http://www.apache.org/licenses/LICENSE-2.0
16   *
17   * Unless required by applicable law or agreed to in writing,
18   * software distributed under the License is distributed on an
19   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20   * KIND, either express or implied.  See the License for the
21   * specific language governing permissions and limitations
22   * under the License.
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   * @author Hans Dockter
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     // download.download(new URI("http://some/test"), distributionDir);
150     // verify(download).download(new URI("http://some/test"), distributionDir);
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     // download.download(new URI("http://some/test"), distributionDir);
221     // verify(download).download(new URI("http://some/test"), distributionDir);
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     // Creating a ZipOutputStream by wrapping a OutputStream
248     try ( OutputStream fos = Files.newOutputStream( zipFile ); ZipOutputStream zos = new ZipOutputStream( fos ) )
249     {
250       // Walk the tree structure using WalkFileTree method
251       Files.walkFileTree( directoryToZip, new SimpleFileVisitor<Path>()
252       {
253         @Override
254         // Before visiting the directory create the directory in zip archive
255         public FileVisitResult preVisitDirectory( final Path dir, final BasicFileAttributes attrs )
256           throws IOException
257         {
258           // Don't create dir for root folder as it is already created with .zip name
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         // For each visited file add it to zip entry
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 }