001package org.apache.maven.repository.legacy;
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 java.io.File;
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.List;
026
027import org.apache.maven.artifact.Artifact;
028import org.apache.maven.artifact.DefaultArtifact;
029import org.apache.maven.artifact.factory.ArtifactFactory;
030import org.apache.maven.artifact.metadata.ArtifactMetadata;
031import org.apache.maven.artifact.repository.ArtifactRepository;
032import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
033import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
034import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
035import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
036import org.apache.maven.artifact.versioning.VersionRange;
037import org.apache.maven.wagon.ResourceDoesNotExistException;
038import org.apache.maven.wagon.TransferFailedException;
039import org.apache.maven.wagon.UnsupportedProtocolException;
040import org.apache.maven.wagon.Wagon;
041import org.apache.maven.wagon.authorization.AuthorizationException;
042import org.apache.maven.wagon.events.TransferEvent;
043import org.apache.maven.wagon.events.TransferListener;
044import org.apache.maven.wagon.observers.AbstractTransferListener;
045import org.apache.maven.wagon.observers.Debug;
046import org.codehaus.plexus.PlexusTestCase;
047import org.codehaus.plexus.util.FileUtils;
048
049/**
050 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
051 */
052public class DefaultWagonManagerTest
053    extends PlexusTestCase
054{
055    private DefaultWagonManager wagonManager;
056
057    private TransferListener transferListener = new Debug();
058
059    private ArtifactFactory artifactFactory;
060
061    private ArtifactRepositoryFactory artifactRepositoryFactory;
062
063    protected void setUp()
064        throws Exception
065    {
066        super.setUp();
067        wagonManager = (DefaultWagonManager) lookup( WagonManager.class );
068        artifactFactory = lookup( ArtifactFactory.class );
069        artifactRepositoryFactory = lookup( ArtifactRepositoryFactory.class );
070    }
071
072    @Override
073    protected void tearDown()
074        throws Exception
075    {
076        wagonManager = null;
077        artifactFactory = null;
078        super.tearDown();
079    }
080
081    public void testUnnecessaryRepositoryLookup()
082        throws Exception
083    {
084        Artifact artifact = createTestPomArtifact( "target/test-data/get-missing-pom" );
085
086        List<ArtifactRepository> repos = new ArrayList<ArtifactRepository>();
087        repos.add( artifactRepositoryFactory.createArtifactRepository( "repo1", "string://url1",
088                                                                       new ArtifactRepositoryLayoutStub(), null, null ) );
089        repos.add( artifactRepositoryFactory.createArtifactRepository( "repo2", "string://url2",
090                                                                       new ArtifactRepositoryLayoutStub(), null, null ) );
091
092        StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
093        wagon.addExpectedContent( repos.get( 0 ).getLayout().pathOf( artifact ), "expected" );
094        wagon.addExpectedContent( repos.get( 1 ).getLayout().pathOf( artifact ), "expected" );
095
096        class TransferListener
097            extends AbstractTransferListener
098        {
099            public List<TransferEvent> events = new ArrayList<TransferEvent>();
100
101            @Override
102            public void transferInitiated( TransferEvent transferEvent )
103            {
104                events.add( transferEvent );
105            }
106        }
107
108        TransferListener listener = new TransferListener();
109        wagonManager.getArtifact( artifact, repos, listener, false );
110        assertEquals( 1, listener.events.size() );
111    }
112
113    public void testGetMissingJar() throws TransferFailedException, UnsupportedProtocolException, IOException
114    {
115        Artifact artifact = createTestArtifact( "target/test-data/get-missing-jar", "jar" );
116
117        ArtifactRepository repo = createStringRepo();
118
119        try
120        {
121            wagonManager.getArtifact( artifact, repo, null, false );
122
123            fail();
124        }
125        catch ( ResourceDoesNotExistException e )
126        {
127            assertTrue( true );
128        }
129
130        assertFalse( artifact.getFile().exists() );
131    }
132
133    public void testGetMissingJarForced() throws TransferFailedException, UnsupportedProtocolException, IOException
134    {
135        Artifact artifact = createTestArtifact( "target/test-data/get-missing-jar", "jar" );
136
137        ArtifactRepository repo = createStringRepo();
138
139        try
140        {
141            wagonManager.getArtifact( artifact, repo, null, false );
142
143            fail();
144        }
145        catch ( ResourceDoesNotExistException e )
146        {
147            assertTrue( true );
148        }
149
150        assertFalse( artifact.getFile().exists() );
151    }
152
153    public void testGetRemoteJar()
154        throws TransferFailedException, ResourceDoesNotExistException, UnsupportedProtocolException, IOException,
155        AuthorizationException
156    {
157        Artifact artifact = createTestArtifact( "target/test-data/get-remote-jar", "jar" );
158
159        ArtifactRepository repo = createStringRepo();
160
161        StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
162        wagon.addExpectedContent( repo.getLayout().pathOf( artifact ), "expected" );
163
164        wagonManager.getArtifact( artifact, repo, null, false );
165
166        assertTrue( artifact.getFile().exists() );
167        assertEquals( "expected", FileUtils.fileRead( artifact.getFile(), "UTF-8" ) );
168    }
169
170    private Artifact createTestPomArtifact( String directory )
171        throws IOException
172    {
173        File testData = getTestFile( directory );
174        FileUtils.deleteDirectory( testData );
175        testData.mkdirs();
176
177        Artifact artifact = artifactFactory.createProjectArtifact( "test", "test", "1.0" );
178        artifact.setFile( new File( testData, "test-1.0.pom" ) );
179        assertFalse( artifact.getFile().exists() );
180        return artifact;
181    }
182
183    private Artifact createTestArtifact( String directory, String type )
184        throws IOException
185    {
186        return createTestArtifact( directory, "1.0", type );
187    }
188
189    private Artifact createTestArtifact( String directory, String version, String type )
190        throws IOException
191    {
192        File testData = getTestFile( directory );
193        FileUtils.deleteDirectory( testData );
194        testData.mkdirs();
195
196        Artifact artifact = artifactFactory.createBuildArtifact( "test", "test", version, type );
197        artifact.setFile( new File( testData, "test-" + version + "." + artifact.getArtifactHandler().getExtension() ) );
198        assertFalse( artifact.getFile().exists() );
199        return artifact;
200    }
201
202    private ArtifactRepository createStringRepo()
203    {
204        return artifactRepositoryFactory.createArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub(), null, null );
205    }
206
207    /**
208     * Build an ArtifactRepository object.
209     *
210     * @param id
211     * @param url
212     * @return
213     */
214    private ArtifactRepository getRepo( String id, String url )
215    {
216        return artifactRepositoryFactory.createArtifactRepository( id, url, new DefaultRepositoryLayout(), null, null );
217    }
218
219    /**
220     * Build an ArtifactRepository object.
221     *
222     * @param id
223     * @return
224     */
225    private ArtifactRepository getRepo( String id )
226    {
227        return getRepo( id, "http://something" );
228    }
229
230    public void testDefaultWagonManager()
231        throws Exception
232    {
233        assertWagon( "a" );
234
235        assertWagon( "b" );
236
237        assertWagon( "c" );
238
239        assertWagon( "string" );
240
241        try
242        {
243            assertWagon( "d" );
244
245            fail( "Expected :" + UnsupportedProtocolException.class.getName() );
246        }
247        catch ( UnsupportedProtocolException e )
248        {
249            // ok
250            assertTrue( true );
251        }
252    }
253
254    /**
255     * Check that transfer listeners are properly removed after getArtifact and putArtifact
256     */
257    public void testWagonTransferListenerRemovedAfterGetArtifactAndPutArtifact()
258        throws Exception
259    {
260        Artifact artifact = createTestArtifact( "target/test-data/transfer-listener", "jar" );
261        ArtifactRepository repo = createStringRepo();
262        StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
263        wagon.addExpectedContent( repo.getLayout().pathOf( artifact ), "expected" );
264
265        /* getArtifact */
266        assertFalse( "Transfer listener is registered before test",
267                     wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
268        wagonManager.getArtifact( artifact, repo, transferListener, false );
269        assertFalse( "Transfer listener still registered after getArtifact",
270                     wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
271
272        /* putArtifact */
273        File sampleFile = getTestFile( "target/test-file" );
274        FileUtils.fileWrite( sampleFile.getAbsolutePath(), "sample file" );
275
276        assertFalse( "Transfer listener is registered before test", wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
277        wagonManager.putArtifact( sampleFile, artifact, repo, transferListener );
278        assertFalse( "Transfer listener still registered after putArtifact", wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
279    }
280
281    /**
282     * Checks the verification of checksums.
283     */
284    public void xtestChecksumVerification()
285        throws Exception
286    {
287        ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
288
289        ArtifactRepository repo = artifactRepositoryFactory.createArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub(), policy, policy );
290
291        Artifact artifact =
292            new DefaultArtifact( "sample.group", "sample-art", VersionRange.createFromVersion( "1.0" ), "scope",
293                                 "jar", "classifier", null );
294        artifact.setFile( getTestFile( "target/sample-art" ) );
295
296        StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
297
298        wagon.clearExpectedContent();
299        wagon.addExpectedContent( "path", "lower-case-checksum" );
300        wagon.addExpectedContent( "path.sha1", "2a25dc564a3b34f68237fc849066cbc7bb7a36a1" );
301
302        try
303        {
304            wagonManager.getArtifact( artifact, repo, null, false );
305        }
306        catch ( ChecksumFailedException e )
307        {
308            fail( "Checksum verification did not pass: " + e.getMessage() );
309        }
310
311        wagon.clearExpectedContent();
312        wagon.addExpectedContent( "path", "upper-case-checksum" );
313        wagon.addExpectedContent( "path.sha1", "B7BB97D7D0B9244398D9B47296907F73313663E6" );
314
315        try
316        {
317            wagonManager.getArtifact( artifact, repo, null, false );
318        }
319        catch ( ChecksumFailedException e )
320        {
321            fail( "Checksum verification did not pass: " + e.getMessage() );
322        }
323
324        wagon.clearExpectedContent();
325        wagon.addExpectedContent( "path", "expected-failure" );
326        wagon.addExpectedContent( "path.sha1", "b7bb97d7d0b9244398d9b47296907f73313663e6" );
327
328        try
329        {
330            wagonManager.getArtifact( artifact, repo, null, false );
331            fail( "Checksum verification did not fail" );
332        }
333        catch ( ChecksumFailedException e )
334        {
335            // expected
336        }
337
338        wagon.clearExpectedContent();
339        wagon.addExpectedContent( "path", "lower-case-checksum" );
340        wagon.addExpectedContent( "path.md5", "50b2cf50a103a965efac62b983035cac" );
341
342        try
343        {
344            wagonManager.getArtifact( artifact, repo, null, false );
345        }
346        catch ( ChecksumFailedException e )
347        {
348            fail( "Checksum verification did not pass: " + e.getMessage() );
349        }
350
351        wagon.clearExpectedContent();
352        wagon.addExpectedContent( "path", "upper-case-checksum" );
353        wagon.addExpectedContent( "path.md5", "842F568FCCFEB7E534DC72133D42FFDC" );
354
355        try
356        {
357            wagonManager.getArtifact( artifact, repo, null, false );
358        }
359        catch ( ChecksumFailedException e )
360        {
361            fail( "Checksum verification did not pass: " + e.getMessage() );
362        }
363
364        wagon.clearExpectedContent();
365        wagon.addExpectedContent( "path", "expected-failure" );
366        wagon.addExpectedContent( "path.md5", "b7bb97d7d0b9244398d9b47296907f73313663e6" );
367
368        try
369        {
370            wagonManager.getArtifact( artifact, repo, null, false );
371            fail( "Checksum verification did not fail" );
372        }
373        catch ( ChecksumFailedException e )
374        {
375            // expected
376        }
377    }
378
379    public void testPerLookupInstantiation()
380        throws Exception
381    {
382        String protocol = "perlookup";
383
384        Wagon one = wagonManager.getWagon( protocol );
385        Wagon two = wagonManager.getWagon( protocol );
386
387        assertNotSame( one, two );
388    }
389
390    private void assertWagon( String protocol )
391        throws Exception
392    {
393        Wagon wagon = wagonManager.getWagon( protocol );
394
395        assertNotNull( "Check wagon, protocol=" + protocol, wagon );
396    }
397
398    private final class ArtifactRepositoryLayoutStub
399        implements ArtifactRepositoryLayout
400    {
401        public String getId()
402        {
403            return "test";
404        }
405
406        public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
407        {
408            return "path";
409        }
410
411        public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
412        {
413            return "path";
414        }
415
416        public String pathOf( Artifact artifact )
417        {
418            return "path";
419        }
420    }
421
422}