001package org.eclipse.aether.transport.classpath;
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.*;
023
024import java.io.File;
025import java.io.FileNotFoundException;
026import java.net.URI;
027import java.nio.charset.StandardCharsets;
028
029import org.eclipse.aether.DefaultRepositorySystemSession;
030import org.eclipse.aether.internal.test.util.TestFileUtils;
031import org.eclipse.aether.internal.test.util.TestLoggerFactory;
032import org.eclipse.aether.internal.test.util.TestUtils;
033import org.eclipse.aether.repository.RemoteRepository;
034import org.eclipse.aether.spi.connector.transport.GetTask;
035import org.eclipse.aether.spi.connector.transport.PeekTask;
036import org.eclipse.aether.spi.connector.transport.PutTask;
037import org.eclipse.aether.spi.connector.transport.Transporter;
038import org.eclipse.aether.spi.connector.transport.TransporterFactory;
039import org.eclipse.aether.transfer.NoTransporterException;
040import org.eclipse.aether.transfer.TransferCancelledException;
041import org.junit.After;
042import org.junit.Before;
043import org.junit.Test;
044
045/**
046 */
047public class ClasspathTransporterTest
048{
049
050    private DefaultRepositorySystemSession session;
051
052    private TransporterFactory factory;
053
054    private Transporter transporter;
055
056    private RemoteRepository newRepo( String url )
057    {
058        return new RemoteRepository.Builder( "test", "default", url ).build();
059    }
060
061    private void newTransporter( String url )
062        throws Exception
063    {
064        if ( transporter != null )
065        {
066            transporter.close();
067            transporter = null;
068        }
069        transporter = factory.newInstance( session, newRepo( url ) );
070    }
071
072    @Before
073    public void setUp()
074        throws Exception
075    {
076        session = TestUtils.newSession();
077        factory = new ClasspathTransporterFactory( new TestLoggerFactory() );
078        newTransporter( "classpath:/repository" );
079    }
080
081    @After
082    public void tearDown()
083    {
084        if ( transporter != null )
085        {
086            transporter.close();
087            transporter = null;
088        }
089        factory = null;
090        session = null;
091    }
092
093    @Test
094    public void testClassify()
095        throws Exception
096    {
097        assertEquals( Transporter.ERROR_OTHER, transporter.classify( new FileNotFoundException() ) );
098        assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( new ResourceNotFoundException( "test" ) ) );
099    }
100
101    @Test
102    public void testPeek()
103        throws Exception
104    {
105        transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
106    }
107
108    @Test
109    public void testPeek_NotFound()
110        throws Exception
111    {
112        try
113        {
114            transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) );
115            fail( "Expected error" );
116        }
117        catch ( ResourceNotFoundException e )
118        {
119            assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) );
120        }
121    }
122
123    @Test
124    public void testPeek_Closed()
125        throws Exception
126    {
127        transporter.close();
128        try
129        {
130            transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) );
131            fail( "Expected error" );
132        }
133        catch ( IllegalStateException e )
134        {
135            assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
136        }
137    }
138
139    @Test
140    public void testGet_ToMemory()
141        throws Exception
142    {
143        RecordingTransportListener listener = new RecordingTransportListener();
144        GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener );
145        transporter.get( task );
146        assertEquals( "test", task.getDataString() );
147        assertEquals( 0L, listener.dataOffset );
148        assertEquals( 4L, listener.dataLength );
149        assertEquals( 1, listener.startedCount );
150        assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
151        assertEquals( task.getDataString(), new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) );
152    }
153
154    @Test
155    public void testGet_ToFile()
156        throws Exception
157    {
158        File file = TestFileUtils.createTempFile( "failure" );
159        RecordingTransportListener listener = new RecordingTransportListener();
160        GetTask task = new GetTask( URI.create( "file.txt" ) ).setDataFile( file ).setListener( listener );
161        transporter.get( task );
162        assertEquals( "test", TestFileUtils.readString( file ) );
163        assertEquals( 0L, listener.dataOffset );
164        assertEquals( 4L, listener.dataLength );
165        assertEquals( 1, listener.startedCount );
166        assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
167        assertEquals( "test", new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) );
168    }
169
170    @Test
171    public void testGet_EmptyResource()
172        throws Exception
173    {
174        File file = TestFileUtils.createTempFile( "failure" );
175        RecordingTransportListener listener = new RecordingTransportListener();
176        GetTask task = new GetTask( URI.create( "empty.txt" ) ).setDataFile( file ).setListener( listener );
177        transporter.get( task );
178        assertEquals( "", TestFileUtils.readString( file ) );
179        assertEquals( 0L, listener.dataOffset );
180        assertEquals( 0L, listener.dataLength );
181        assertEquals( 1, listener.startedCount );
182        assertEquals( 0, listener.progressedCount );
183        assertEquals( "", new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) );
184    }
185
186    @Test
187    public void testGet_EncodedResourcePath()
188        throws Exception
189    {
190        GetTask task = new GetTask( URI.create( "some%20space.txt" ) );
191        transporter.get( task );
192        assertEquals( "space", task.getDataString() );
193    }
194
195    @Test
196    public void testGet_Fragment()
197        throws Exception
198    {
199        GetTask task = new GetTask( URI.create( "file.txt#ignored" ) );
200        transporter.get( task );
201        assertEquals( "test", task.getDataString() );
202    }
203
204    @Test
205    public void testGet_Query()
206        throws Exception
207    {
208        GetTask task = new GetTask( URI.create( "file.txt?ignored" ) );
209        transporter.get( task );
210        assertEquals( "test", task.getDataString() );
211    }
212
213    @Test
214    public void testGet_FileHandleLeak()
215        throws Exception
216    {
217        for ( int i = 0; i < 100; i++ )
218        {
219            File file = TestFileUtils.createTempFile( "failure" );
220            transporter.get( new GetTask( URI.create( "file.txt" ) ).setDataFile( file ) );
221            assertTrue( i + ", " + file.getAbsolutePath(), file.delete() );
222        }
223    }
224
225    @Test
226    public void testGet_NotFound()
227        throws Exception
228    {
229        try
230        {
231            transporter.get( new GetTask( URI.create( "missing.txt" ) ) );
232            fail( "Expected error" );
233        }
234        catch ( ResourceNotFoundException e )
235        {
236            assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) );
237        }
238    }
239
240    @Test
241    public void testGet_Closed()
242        throws Exception
243    {
244        transporter.close();
245        try
246        {
247            transporter.get( new GetTask( URI.create( "file.txt" ) ) );
248            fail( "Expected error" );
249        }
250        catch ( IllegalStateException e )
251        {
252            assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
253        }
254    }
255
256    @Test
257    public void testGet_StartCancelled()
258        throws Exception
259    {
260        RecordingTransportListener listener = new RecordingTransportListener();
261        listener.cancelStart = true;
262        GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener );
263        try
264        {
265            transporter.get( task );
266            fail( "Expected error" );
267        }
268        catch ( TransferCancelledException e )
269        {
270            assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
271        }
272        assertEquals( 0L, listener.dataOffset );
273        assertEquals( 4L, listener.dataLength );
274        assertEquals( 1, listener.startedCount );
275        assertEquals( 0, listener.progressedCount );
276    }
277
278    @Test
279    public void testGet_ProgressCancelled()
280        throws Exception
281    {
282        RecordingTransportListener listener = new RecordingTransportListener();
283        listener.cancelProgress = true;
284        GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener );
285        try
286        {
287            transporter.get( task );
288            fail( "Expected error" );
289        }
290        catch ( TransferCancelledException e )
291        {
292            assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
293        }
294        assertEquals( 0L, listener.dataOffset );
295        assertEquals( 4L, listener.dataLength );
296        assertEquals( 1, listener.startedCount );
297        assertEquals( 1, listener.progressedCount );
298    }
299
300    @Test
301    public void testPut()
302        throws Exception
303    {
304        try
305        {
306            transporter.put( new PutTask( URI.create( "missing.txt" ) ) );
307            fail( "Expected error" );
308        }
309        catch ( UnsupportedOperationException e )
310        {
311            assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
312        }
313    }
314
315    @Test
316    public void testPut_Closed()
317        throws Exception
318    {
319        transporter.close();
320        try
321        {
322            transporter.put( new PutTask( URI.create( "missing.txt" ) ) );
323            fail( "Expected error" );
324        }
325        catch ( IllegalStateException e )
326        {
327            assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
328        }
329    }
330
331    @Test( expected = NoTransporterException.class )
332    public void testInit_BadProtocol()
333        throws Exception
334    {
335        newTransporter( "bad:/void" );
336    }
337
338    @Test
339    public void testInit_CaseInsensitiveProtocol()
340        throws Exception
341    {
342        newTransporter( "classpath:/void" );
343        newTransporter( "CLASSPATH:/void" );
344        newTransporter( "ClassPath:/void" );
345    }
346
347    @Test
348    public void testInit_OpaqueUrl()
349        throws Exception
350    {
351        testInit( "classpath:repository" );
352    }
353
354    @Test
355    public void testInit_OpaqueUrlTrailingSlash()
356        throws Exception
357    {
358        testInit( "classpath:repository/" );
359    }
360
361    @Test
362    public void testInit_OpaqueUrlSpaces()
363        throws Exception
364    {
365        testInit( "classpath:repo%20space" );
366    }
367
368    @Test
369    public void testInit_HierarchicalUrl()
370        throws Exception
371    {
372        testInit( "classpath:/repository" );
373    }
374
375    @Test
376    public void testInit_HierarchicalUrlTrailingSlash()
377        throws Exception
378    {
379        testInit( "classpath:/repository/" );
380    }
381
382    @Test
383    public void testInit_HierarchicalUrlSpaces()
384        throws Exception
385    {
386        testInit( "classpath:/repo%20space" );
387    }
388
389    @Test
390    public void testInit_HierarchicalUrlRoot()
391        throws Exception
392    {
393        testInit( "classpath:/" );
394    }
395
396    @Test
397    public void testInit_HierarchicalUrlNoPath()
398        throws Exception
399    {
400        testInit( "classpath://reserved" );
401    }
402
403    private void testInit( String base )
404        throws Exception
405    {
406        newTransporter( base );
407        GetTask task = new GetTask( URI.create( "file.txt" ) );
408        transporter.get( task );
409        assertEquals( "test", task.getDataString() );
410    }
411
412}