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