001/*
002 *  jDTAUS Core Test Suite
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.core.io.it;
022
023import java.io.InputStream;
024import java.util.Arrays;
025import junit.framework.Assert;
026import junit.framework.TestCase;
027import org.jdtaus.core.io.FileOperations;
028
029/**
030 * Testcase for {@code FileOperations} implementations.
031 *
032 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
033 * @version $JDTAUS: FileOperationsTest.java 8743 2012-10-07 03:06:20Z schulte $
034 */
035public class FileOperationsTest extends TestCase
036{
037    //--FileOperationsTest------------------------------------------------------
038
039    /** The implementation to test. */
040    private FileOperations fileOperations;
041
042    /** Creates a new {@code FileOperationsTest} instance. */
043    public FileOperationsTest()
044    {
045        super();
046    }
047
048    /**
049     * Gets the {@code FileOperations} implementation tests are performed with.
050     *
051     * @return the {@code FileOperations} implementation tests are performed
052     * with.
053     */
054    public FileOperations getFileOperations()
055    {
056        return this.fileOperations;
057    }
058
059    /**
060     * Sets the {@code FileOperations} implementation to test.
061     *
062     * @param value the {@code FileOperations} implementation to test.
063     */
064    public final void setFileOperations( final FileOperations value )
065    {
066        this.fileOperations = value;
067    }
068
069    /**
070     * Gets a testfile resource.
071     *
072     * @return an {@code InputStream} for reading the testfile content from.
073     */
074    protected InputStream getTestFile()
075    {
076        final InputStream ret = Thread.currentThread().getContextClassLoader().
077            getResourceAsStream( "org/jdtaus/core/io/it/testfile" );
078
079        Assert.assertNotNull( ret );
080        return ret;
081    }
082
083    /**
084     * Checks that a given {@code String} contains exactly the same contents
085     * as the content of {@code getTestFile()}.
086     *
087     * @param testfile The string to test.
088     *
089     * @throws RuntimeException if {@code testfile} does not hold the same
090     * characters than the contents of the testfile.
091     *
092     * @see #getTestFile()
093     */
094    protected void assertValidTestFile( final String testfile )
095    {
096        Assert.assertEquals( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", testfile );
097    }
098
099    //------------------------------------------------------FileOperationsTest--
100    //--TestCase----------------------------------------------------------------
101
102    protected void runTest() throws Throwable
103    {
104        this.testGetLength();
105        this.testSetLength();
106        this.testSetLengthUpdatesFilePointer();
107        this.testWriteBeyondIncreasesLength();
108        this.testEndOfFile();
109        this.testRead();
110        this.testWrite();
111    }
112
113    //----------------------------------------------------------------TestCase--
114    //--Tests-------------------------------------------------------------------
115
116    /**
117     * Tests the {@link FileOperations#getLength()} method.
118     * <p><ol>
119     * <li>Tests that the length of the provided {@code FileOperations}
120     * implementation is {@code 0}.</li></ol></p>
121     */
122    public void testGetLength() throws Exception
123    {
124        Assert.assertEquals( 0L, this.getFileOperations().getLength() );
125    }
126
127    /**
128     * Tests the {@link FileOperations#setLength(long)} method.
129     * <p><ol>
130     * <li>Sets the length of the provided {@code FileOperations} implementation
131     * to {@code 100L} and checks that the corresponding {@code getLength()}
132     * method returns {@code 100L} afterwars.</li>
133     * <li>Sets the length of the provided {@code FileOperations} implementation
134     * to {@code 0L} and checks that the corresponding {@code getLength()}
135     * method returns {@code 0L} afterwars.</li>
136     * <li>Sets the length to a negative value and checks for an
137     * {@code IllegalArgumentException} to be thrown.</li>
138     * </ol></p>
139     */
140    public void testSetLength() throws Exception
141    {
142        final FileOperations ops = this.getFileOperations();
143        ops.setLength( 100L );
144        Assert.assertEquals( 100L, ops.getLength() );
145        ops.setLength( 0L );
146        Assert.assertEquals( 0L, ops.getLength() );
147
148        try
149        {
150            ops.setLength( Long.MIN_VALUE );
151            throw new AssertionError( String.valueOf( Long.MIN_VALUE ) );
152        }
153        catch ( final IllegalArgumentException e )
154        {
155            Assert.assertNotNull( e.getMessage() );
156            System.out.println( e.toString() );
157        }
158    }
159
160    /**
161     * Tests the {@link FileOperations#setLength(long)} method to correctly
162     * position the file pointer on truncating the file.
163     */
164    public void testSetLengthUpdatesFilePointer() throws Exception
165    {
166        final FileOperations ops = this.getFileOperations();
167
168        ops.setLength( 10000L );
169        ops.setFilePointer( 0L );
170        ops.setLength( 100L );
171        Assert.assertEquals( 0L, ops.getFilePointer() );
172        ops.setFilePointer( 50L );
173        ops.setLength( 10L );
174        Assert.assertEquals( 10L, ops.getFilePointer() );
175        ops.setLength( 0L );
176    }
177
178    /**
179     * Tests the {@link FileOperations#write(byte[],int,int)} method to
180     * correctly increase the length when writing beyond the current length.
181     */
182    public void testWriteBeyondIncreasesLength() throws Exception
183    {
184        final FileOperations ops = this.getFileOperations();
185
186        ops.setLength( 0L );
187        ops.setFilePointer( 0L );
188        ops.write( new byte[] { ( byte ) 1 }, 0, 1 );
189        Assert.assertEquals( 1L, ops.getLength() );
190        ops.setLength( 0L );
191
192        ops.setLength( 10L );
193        ops.setFilePointer( 10L );
194        ops.write( new byte[] { ( byte ) 1 }, 0, 1 );
195        Assert.assertEquals( 11L, ops.getLength() );
196        ops.setLength( 0L );
197
198        ops.setLength( 0L );
199        ops.setFilePointer( 0L );
200        ops.write( new byte[] {}, 0, 0 );
201        Assert.assertEquals( 0L, ops.getLength() );
202        ops.setLength( 0L );
203        ops.setFilePointer( 0L );
204
205        ops.write( new byte[ 0 ], 0, 0 );
206        Assert.assertEquals( 0L, ops.getLength() );
207        Assert.assertEquals( 0L, ops.getFilePointer() );
208
209        ops.setLength( 0L );
210    }
211
212    /**
213     * Tests the {@link FileOperations#read} method.
214     * <ol>
215     * <li>Sets the length to {@code 1} and the filepointer to {@code 1} and
216     * tries to read {@code 1} byte checking for EOF.</li>
217     * </ol>
218     */
219    public void testEndOfFile() throws Exception
220    {
221        final FileOperations ops = this.getFileOperations();
222        ops.setLength( 1L );
223        ops.setFilePointer( 1L );
224
225        Assert.assertEquals( 0, ops.read( new byte[ 0 ], 0, 0 ) );
226        Assert.assertEquals( FileOperations.EOF,
227                             ops.read( new byte[ 1 ], 0, 1 ) );
228
229        ops.setLength( 100000L );
230        ops.setFilePointer( 100000L );
231        Assert.assertEquals( 0, ops.read( new byte[ 0 ], 0, 0 ) );
232        Assert.assertEquals( FileOperations.EOF,
233                             ops.read( new byte[ 1 ], 0, 1 ) );
234
235        ops.setLength( 0L );
236    }
237
238    /**
239     * Tests the {@link FileOperations#read} method.
240     * <p><ol>
241     * <li>Reads {@code 101} byte from a buffer of {@code 100} byte and checks
242     * that the method returns {@code EOF} for end of file.</li>
243     * <li>Writes some digits to the file and checks that property
244     * {@code length} matches the expected value after writing.</li>
245     * <li>Sets the file pointer to the middle of the file and reads more bytes
246     * than available in the file checking to get the expected number of read
247     * bytes returned from the method.</li>
248     * <li>Reads one more byte and checks that the method returns {@code EOF}
249     * for end of file.</li>
250     * <li>Reads all written data and checks that the read data matches the
251     * written data.</li>
252     * </ol></p>
253     */
254    public void testRead() throws Exception
255    {
256        final FileOperations ops = this.getFileOperations();
257        final byte[] digits = new byte[ 100 ]; // Muss durch 2 teilbar sein.
258        final byte[] buf = new byte[ digits.length ];
259        Arrays.fill( digits, ( byte ) '1' );
260
261        int toRead = 0;
262        int totalRead = 0;
263        int read = 0;
264
265        // EOF
266        Assert.assertEquals( FileOperations.EOF,
267                             ops.read( new byte[ 100 ], 0, 100 ) );
268
269        ops.setFilePointer( 0L );
270        ops.write( digits, 0, digits.length );
271        Assert.assertEquals( digits.length, ops.getLength() );
272
273        // Rest before EOF
274        ops.setFilePointer( digits.length / 2 );
275
276        toRead = digits.length;
277        do
278        {
279            read = ops.read( buf, totalRead, toRead );
280            if ( read != FileOperations.EOF )
281            {
282                totalRead += read;
283                toRead -= read;
284            }
285        }
286        while ( totalRead < digits.length && read != FileOperations.EOF );
287
288        Assert.assertEquals( digits.length / 2, totalRead );
289        Assert.assertEquals( FileOperations.EOF,
290                             ops.read( buf, buf.length - 1, 1 ) );
291
292        // Read the written data.
293        ops.setFilePointer( 0L );
294        toRead = digits.length;
295        totalRead = 0;
296        do
297        {
298            read = ops.read( buf, totalRead, toRead );
299            if ( read != FileOperations.EOF )
300            {
301                totalRead += read;
302                toRead -= read;
303            }
304        }
305        while ( totalRead < digits.length && read != FileOperations.EOF );
306
307        Assert.assertEquals( digits.length, totalRead );
308        Assert.assertTrue( Arrays.equals( digits, buf ) );
309        ops.setLength( 0 );
310    }
311
312    /**
313     * Tests the {@link FileOperations#write} method.
314     * <p><ol>
315     * <li>Writes some digits to the file and checks that property
316     * {@code length} matches the expected value after writing.</li>
317     * <li>Sets the file pointer after the end of the file and writes some
318     * digits to the file checking that property {@code length} matches the
319     * expected value after writing.</li>
320     * <li>Reads the written data and checks that the read data matches the
321     * written data.</li>
322     * </ol></p>
323     */
324    public void testWrite() throws Exception
325    {
326        final long off;
327        final FileOperations ops = this.getFileOperations();
328        final byte[] digits = new byte[ 100 ]; // Muss durch 2 teilbar sein.
329        final byte[] buf = new byte[ digits.length ];
330        int totalRead = 0;
331        int toRead = 0;
332        int read = 0;
333        Arrays.fill( digits, ( byte ) '1' );
334
335        ops.setFilePointer( 0L );
336        ops.write( digits, 0, 100 );
337        Assert.assertEquals( digits.length, ops.getLength() );
338
339        off = ops.getLength() * 2;
340        ops.setFilePointer( off );
341        ops.write( digits, 0, 100 );
342        ops.setFilePointer( off );
343
344        toRead = digits.length;
345        do
346        {
347            read = ops.read( buf, totalRead, toRead );
348            if ( read != FileOperations.EOF )
349            {
350                totalRead += read;
351                toRead -= read;
352            }
353        }
354        while ( totalRead < digits.length && read != FileOperations.EOF );
355        Assert.assertEquals( digits.length, totalRead );
356        Assert.assertTrue( Arrays.equals( digits, buf ) );
357        ops.setLength( 0 );
358    }
359
360    //-------------------------------------------------------------------Tests--
361}