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