001package org.eclipse.aether.internal.impl;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 * 
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 * 
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertFalse;
024import static org.junit.Assert.assertNotNull;
025import static org.junit.Assert.assertNull;
026import static org.junit.Assert.assertTrue;
027import static org.junit.Assert.fail;
028
029import java.io.BufferedReader;
030import java.io.ByteArrayInputStream;
031import java.io.File;
032import java.io.FileReader;
033import java.io.IOException;
034import java.io.InputStream;
035import java.nio.charset.StandardCharsets;
036import java.util.List;
037
038import org.eclipse.aether.DefaultRepositorySystemSession;
039import org.eclipse.aether.RepositoryEvent;
040import org.eclipse.aether.RepositoryEvent.EventType;
041import org.eclipse.aether.artifact.Artifact;
042import org.eclipse.aether.artifact.DefaultArtifact;
043import org.eclipse.aether.installation.InstallRequest;
044import org.eclipse.aether.installation.InstallResult;
045import org.eclipse.aether.installation.InstallationException;
046import org.eclipse.aether.internal.test.util.TestFileProcessor;
047import org.eclipse.aether.internal.test.util.TestFileUtils;
048import org.eclipse.aether.internal.test.util.TestLocalRepositoryManager;
049import org.eclipse.aether.internal.test.util.TestUtils;
050import org.eclipse.aether.metadata.DefaultMetadata;
051import org.eclipse.aether.metadata.Metadata;
052import org.eclipse.aether.metadata.Metadata.Nature;
053import org.eclipse.aether.transform.FileTransformer;
054import org.eclipse.aether.util.artifact.SubArtifact;
055import org.junit.After;
056import org.junit.Before;
057import org.junit.Test;
058
059public class DefaultInstallerTest
060{
061
062    private Artifact artifact;
063
064    private Metadata metadata;
065
066    private DefaultRepositorySystemSession session;
067
068    private String localArtifactPath;
069
070    private String localMetadataPath;
071
072    private DefaultInstaller installer;
073
074    private InstallRequest request;
075
076    private RecordingRepositoryListener listener;
077
078    private File localArtifactFile;
079
080    private TestLocalRepositoryManager lrm;
081
082    @Before
083    public void setup()
084        throws IOException
085    {
086        artifact = new DefaultArtifact( "gid", "aid", "jar", "ver" );
087        artifact = artifact.setFile( TestFileUtils.createTempFile( "artifact".getBytes(), 1 ) );
088        metadata =
089            new DefaultMetadata( "gid", "aid", "ver", "type", Nature.RELEASE_OR_SNAPSHOT,
090                                 TestFileUtils.createTempFile( "metadata".getBytes(), 1 ) );
091
092        session = TestUtils.newSession();
093        localArtifactPath = session.getLocalRepositoryManager().getPathForLocalArtifact( artifact );
094        localMetadataPath = session.getLocalRepositoryManager().getPathForLocalMetadata( metadata );
095
096        localArtifactFile = new File( session.getLocalRepository().getBasedir(), localArtifactPath );
097
098        installer = new DefaultInstaller();
099        installer.setFileProcessor( new TestFileProcessor() );
100        installer.setRepositoryEventDispatcher( new StubRepositoryEventDispatcher() );
101        installer.setSyncContextFactory( new StubSyncContextFactory() );
102        request = new InstallRequest();
103        listener = new RecordingRepositoryListener();
104        session.setRepositoryListener( listener );
105
106        lrm = (TestLocalRepositoryManager) session.getLocalRepositoryManager();
107
108        TestFileUtils.deleteFile( session.getLocalRepository().getBasedir() );
109    }
110
111    @After
112    public void teardown()
113        throws Exception
114    {
115        TestFileUtils.deleteFile( session.getLocalRepository().getBasedir() );
116    }
117
118    @Test
119    public void testSuccessfulInstall()
120        throws InstallationException, IOException
121    {
122        File artifactFile =
123            new File( session.getLocalRepositoryManager().getRepository().getBasedir(), localArtifactPath );
124        File metadataFile =
125            new File( session.getLocalRepositoryManager().getRepository().getBasedir(), localMetadataPath );
126
127        artifactFile.delete();
128        metadataFile.delete();
129
130        request.addArtifact( artifact );
131        request.addMetadata( metadata );
132
133        InstallResult result = installer.install( session, request );
134
135        assertTrue( artifactFile.exists() );
136        assertEquals( "artifact", TestFileUtils.readString( artifactFile ) );
137
138        assertTrue( metadataFile.exists() );
139        assertEquals( "metadata", TestFileUtils.readString( metadataFile ) );
140
141        assertEquals( result.getRequest(), request );
142
143        assertEquals( result.getArtifacts().size(), 1 );
144        assertTrue( result.getArtifacts().contains( artifact ) );
145
146        assertEquals( result.getMetadata().size(), 1 );
147        assertTrue( result.getMetadata().contains( metadata ) );
148
149        assertEquals( 1, lrm.getMetadataRegistration().size() );
150        assertTrue( lrm.getMetadataRegistration().contains( metadata ) );
151        assertEquals( 1, lrm.getArtifactRegistration().size() );
152        assertTrue( lrm.getArtifactRegistration().contains( artifact ) );
153    }
154
155    @Test( expected = InstallationException.class )
156    public void testNullArtifactFile()
157        throws InstallationException
158    {
159        InstallRequest request = new InstallRequest();
160        request.addArtifact( artifact.setFile( null ) );
161
162        installer.install( session, request );
163    }
164
165    @Test( expected = InstallationException.class )
166    public void testNullMetadataFile()
167        throws InstallationException
168    {
169        InstallRequest request = new InstallRequest();
170        request.addMetadata( metadata.setFile( null ) );
171
172        installer.install( session, request );
173    }
174
175    @Test( expected = InstallationException.class )
176    public void testNonExistentArtifactFile()
177        throws InstallationException
178    {
179        InstallRequest request = new InstallRequest();
180        request.addArtifact( artifact.setFile( new File( "missing.txt" ) ) );
181
182        installer.install( session, request );
183    }
184
185    @Test( expected = InstallationException.class )
186    public void testNonExistentMetadataFile()
187        throws InstallationException
188    {
189        InstallRequest request = new InstallRequest();
190        request.addMetadata( metadata.setFile( new File( "missing.xml" ) ) );
191
192        installer.install( session, request );
193    }
194
195    @Test( expected = InstallationException.class )
196    public void testArtifactExistsAsDir()
197        throws InstallationException
198    {
199        String path = session.getLocalRepositoryManager().getPathForLocalArtifact( artifact );
200        File file = new File( session.getLocalRepository().getBasedir(), path );
201        assertFalse( file.getAbsolutePath() + " is a file, not directory", file.isFile() );
202        assertFalse( file.getAbsolutePath() + " already exists", file.exists() );
203        assertTrue( "failed to setup test: could not create " + file.getAbsolutePath(),
204                    file.mkdirs() || file.isDirectory() );
205
206        request.addArtifact( artifact );
207        installer.install( session, request );
208    }
209
210    @Test( expected = InstallationException.class )
211    public void testMetadataExistsAsDir()
212        throws InstallationException
213    {
214        String path = session.getLocalRepositoryManager().getPathForLocalMetadata( metadata );
215        assertTrue( "failed to setup test: could not create " + path,
216                    new File( session.getLocalRepository().getBasedir(), path ).mkdirs() );
217
218        request.addMetadata( metadata );
219        installer.install( session, request );
220    }
221
222    @Test( expected = InstallationException.class )
223    public void testArtifactDestinationEqualsSource()
224        throws Exception
225    {
226        String path = session.getLocalRepositoryManager().getPathForLocalArtifact( artifact );
227        File file = new File( session.getLocalRepository().getBasedir(), path );
228        artifact = artifact.setFile( file );
229        TestFileUtils.writeString( file, "test" );
230
231        request.addArtifact( artifact );
232        installer.install( session, request );
233    }
234
235    @Test( expected = InstallationException.class )
236    public void testMetadataDestinationEqualsSource()
237        throws Exception
238    {
239        String path = session.getLocalRepositoryManager().getPathForLocalMetadata( metadata );
240        File file = new File( session.getLocalRepository().getBasedir(), path );
241        metadata = metadata.setFile( file );
242        TestFileUtils.writeString( file, "test" );
243
244        request.addMetadata( metadata );
245        installer.install( session, request );
246    }
247
248    @Test
249    public void testSuccessfulArtifactEvents()
250        throws InstallationException
251    {
252        InstallRequest request = new InstallRequest();
253        request.addArtifact( artifact );
254
255        installer.install( session, request );
256        checkEvents( "Repository Event problem", artifact, false );
257    }
258
259    @Test
260    public void testSuccessfulMetadataEvents()
261        throws InstallationException
262    {
263        InstallRequest request = new InstallRequest();
264        request.addMetadata( metadata );
265
266        installer.install( session, request );
267        checkEvents( "Repository Event problem", metadata, false );
268    }
269
270    @Test
271    public void testFailingEventsNullArtifactFile()
272    {
273        checkFailedEvents( "null artifact file", this.artifact.setFile( null ) );
274    }
275
276    @Test
277    public void testFailingEventsNullMetadataFile()
278    {
279        checkFailedEvents( "null metadata file", this.metadata.setFile( null ) );
280    }
281
282    @Test
283    public void testFailingEventsArtifactExistsAsDir()
284    {
285        String path = session.getLocalRepositoryManager().getPathForLocalArtifact( artifact );
286        assertTrue( "failed to setup test: could not create " + path,
287                    new File( session.getLocalRepository().getBasedir(), path ).mkdirs() );
288        checkFailedEvents( "target exists as dir", artifact );
289    }
290
291    @Test
292    public void testFailingEventsMetadataExistsAsDir()
293    {
294        String path = session.getLocalRepositoryManager().getPathForLocalMetadata( metadata );
295        assertTrue( "failed to setup test: could not create " + path,
296                    new File( session.getLocalRepository().getBasedir(), path ).mkdirs() );
297        checkFailedEvents( "target exists as dir", metadata );
298    }
299
300    private void checkFailedEvents( String msg, Metadata metadata )
301    {
302        InstallRequest request = new InstallRequest().addMetadata( metadata );
303        msg = "Repository events problem (case: " + msg + ")";
304
305        try
306        {
307            installer.install( session, request );
308            fail( "expected exception" );
309        }
310        catch ( InstallationException e )
311        {
312            checkEvents( msg, metadata, true );
313        }
314
315    }
316
317    private void checkEvents( String msg, Metadata metadata, boolean failed )
318    {
319        List<RepositoryEvent> events = listener.getEvents();
320        assertEquals( msg, 2, events.size() );
321        RepositoryEvent event = events.get( 0 );
322        assertEquals( msg, EventType.METADATA_INSTALLING, event.getType() );
323        assertEquals( msg, metadata, event.getMetadata() );
324        assertNull( msg, event.getException() );
325
326        event = events.get( 1 );
327        assertEquals( msg, EventType.METADATA_INSTALLED, event.getType() );
328        assertEquals( msg, metadata, event.getMetadata() );
329        if ( failed )
330        {
331            assertNotNull( msg, event.getException() );
332        }
333        else
334        {
335            assertNull( msg, event.getException() );
336        }
337    }
338
339    private void checkFailedEvents( String msg, Artifact artifact )
340    {
341        InstallRequest request = new InstallRequest().addArtifact( artifact );
342        msg = "Repository events problem (case: " + msg + ")";
343
344        try
345        {
346            installer.install( session, request );
347            fail( "expected exception" );
348        }
349        catch ( InstallationException e )
350        {
351            checkEvents( msg, artifact, true );
352        }
353    }
354
355    private void checkEvents( String msg, Artifact artifact, boolean failed )
356    {
357        List<RepositoryEvent> events = listener.getEvents();
358        assertEquals( msg, 2, events.size() );
359        RepositoryEvent event = events.get( 0 );
360        assertEquals( msg, EventType.ARTIFACT_INSTALLING, event.getType() );
361        assertEquals( msg, artifact, event.getArtifact() );
362        assertNull( msg, event.getException() );
363        
364        event = events.get( 1 );
365        assertEquals( msg, EventType.ARTIFACT_INSTALLED, event.getType() );
366        assertEquals( msg, artifact, event.getArtifact() );
367        if ( failed )
368        {
369            assertNotNull( msg + " > expected exception", event.getException() );
370        }
371        else
372        {
373            assertNull( msg + " > " + event.getException(), event.getException() );
374        }
375    }
376
377    @Test
378    public void testDoNotUpdateUnchangedArtifact()
379        throws InstallationException
380    {
381        request.addArtifact( artifact );
382        installer.install( session, request );
383
384        installer.setFileProcessor( new DefaultFileProcessor()
385        {
386            @Override
387            public long copy( File src, File target, ProgressListener listener )
388                throws IOException
389            {
390                throw new IOException( "copy called" );
391            }
392        } );
393
394        request = new InstallRequest();
395        request.addArtifact( artifact );
396        installer.install( session, request );
397    }
398
399    @Test
400    public void testSetArtifactTimestamps()
401        throws InstallationException
402    {
403        artifact.getFile().setLastModified( artifact.getFile().lastModified() - 60000 );
404
405        request.addArtifact( artifact );
406
407        installer.install( session, request );
408
409        assertEquals( "artifact timestamp was not set to src file", artifact.getFile().lastModified(),
410                      localArtifactFile.lastModified() );
411
412        request = new InstallRequest();
413
414        request.addArtifact( artifact );
415
416        artifact.getFile().setLastModified( artifact.getFile().lastModified() - 60000 );
417
418        installer.install( session, request );
419
420        assertEquals( "artifact timestamp was not set to src file", artifact.getFile().lastModified(),
421                      localArtifactFile.lastModified() );
422    }
423    
424    @Test
425    public void testFileTransformer() throws Exception
426    {
427        final Artifact transformedArtifact = new SubArtifact( artifact, null, "raj" );
428        FileTransformer transformer = new FileTransformer()
429        {
430            @Override
431            public InputStream transformData( File file )
432            {
433                return new ByteArrayInputStream( "transformed data".getBytes( StandardCharsets.UTF_8 ) );
434            }
435            
436            @Override
437            public Artifact transformArtifact( Artifact artifact )
438            {
439                return transformedArtifact;
440            }
441        };
442        
443        StubFileTransformerManager fileTransformerManager = new StubFileTransformerManager();
444        fileTransformerManager.addFileTransformer( "jar", transformer );
445        session.setFileTransformerManager( fileTransformerManager );
446        
447        request = new InstallRequest();
448        request.addArtifact( artifact );
449        installer.install( session, request );
450        
451        assertFalse( localArtifactFile.exists() );
452        
453        String transformedArtifactPath = session.getLocalRepositoryManager().getPathForLocalArtifact( transformedArtifact );
454        File transformedArtifactFile = new File( session.getLocalRepository().getBasedir(), transformedArtifactPath );
455        assertTrue( transformedArtifactFile.exists() );
456        
457        try ( BufferedReader r = new BufferedReader( new FileReader( transformedArtifactFile ) ) )
458        {
459            assertEquals( "transformed data", r.readLine() );
460        }
461    }
462}