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 8692 2012-10-01 14:16:57Z schulte $
034 */
035public class FileOperationsTest extends TestCase
036{
037    //--FileOperationsTest------------------------------------------------------
038
039    /** The implementation to test. */
040    private FileOperations fileOperations;
041
042    /**
043     * Gets the {@code FileOperations} implementation tests are performed with.
044     *
045     * @return the {@code FileOperations} implementation tests are performed
046     * with.
047     */
048    public FileOperations getFileOperations()
049    {
050        return this.fileOperations;
051    }
052
053    /**
054     * Sets the {@code FileOperations} implementation to test.
055     *
056     * @param value the {@code FileOperations} implementation to test.
057     */
058    public final void setFileOperations( final FileOperations value )
059    {
060        this.fileOperations = value;
061    }
062
063    /**
064     * Gets a testfile resource.
065     *
066     * @return an {@code InputStream} for reading the testfile content from.
067     */
068    protected InputStream getTestFile()
069    {
070        final InputStream ret = Thread.currentThread().getContextClassLoader().
071            getResourceAsStream( "org/jdtaus/core/io/it/testfile" );
072
073        Assert.assertNotNull( ret );
074        return ret;
075    }
076
077    /**
078     * Checks that a given {@code String} contains exactly the same contents
079     * as the content of {@code getTestFile()}.
080     *
081     * @throws RuntimeException if {@code testfile} does not hold the same
082     * characters than the contents of the testfile.
083     *
084     * @see #getTestFile()
085     */
086    protected void assertValidTestFile( final String testfile )
087    {
088        Assert.assertEquals( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", testfile );
089    }
090
091    //------------------------------------------------------FileOperationsTest--
092    //--TestCase----------------------------------------------------------------
093
094    protected void runTest() throws Throwable
095    {
096        this.testGetLength();
097        this.testSetLength();
098        this.testSetLengthUpdatesFilePointer();
099        this.testWriteBeyondIncreasesLength();
100        this.testEndOfFile();
101        this.testRead();
102        this.testWrite();
103    }
104
105    //----------------------------------------------------------------TestCase--
106    //--Tests-------------------------------------------------------------------
107
108    /**
109     * Tests the {@link FileOperations#getLength()} method.
110     * <p><ol>
111     * <li>Tests that the length of the provided {@code FileOperations}
112     * implementation is {@code 0}.</li></ol></p>
113     */
114    public void testGetLength() throws Exception
115    {
116        Assert.assertEquals( 0L, this.getFileOperations().getLength() );
117    }
118
119    /**
120     * Tests the {@link FileOperations#setLength(long)} method.
121     * <p><ol>
122     * <li>Sets the length of the provided {@code FileOperations} implementation
123     * to {@code 100L} and checks that the corresponding {@code getLength()}
124     * method returns {@code 100L} afterwars.</li>
125     * <li>Sets the length of the provided {@code FileOperations} implementation
126     * to {@code 0L} and checks that the corresponding {@code getLength()}
127     * method returns {@code 0L} afterwars.</li>
128     * <li>Sets the length to a negative value and checks for an
129     * {@code IllegalArgumentException} to be thrown.</li>
130     * </ol></p>
131     */
132    public void testSetLength() throws Exception
133    {
134        final FileOperations ops = this.getFileOperations();
135        ops.setLength( 100L );
136        Assert.assertEquals( 100L, ops.getLength() );
137        ops.setLength( 0L );
138        Assert.assertEquals( 0L, ops.getLength() );
139
140        try
141        {
142            ops.setLength( Long.MIN_VALUE );
143            throw new AssertionError( String.valueOf( Long.MIN_VALUE ) );
144        }
145        catch ( IllegalArgumentException e )
146        {
147            Assert.assertNotNull( e.getMessage() );
148            System.out.println( e.toString() );
149        }
150    }
151
152    /**
153     * Tests the {@link FileOperations#setLength(long)} method to correctly
154     * position the file pointer on truncating the file.
155     */
156    public void testSetLengthUpdatesFilePointer() throws Exception
157    {
158        final FileOperations ops = this.getFileOperations();
159
160        ops.setLength( 10000L );
161        ops.setFilePointer( 0L );
162        ops.setLength( 100L );
163        Assert.assertEquals( 0L, ops.getFilePointer() );
164        ops.setFilePointer( 50L );
165        ops.setLength( 10L );
166        Assert.assertEquals( 10L, ops.getFilePointer() );
167        ops.setLength( 0L );
168    }
169
170    /**
171     * Tests the {@link FileOperations#write(byte[],int,int)} method to
172     * correctly increase the length when writing beyond the current length.
173     */
174    public void testWriteBeyondIncreasesLength() throws Exception
175    {
176        final FileOperations ops = this.getFileOperations();
177
178        ops.setLength( 0L );
179        ops.setFilePointer( 0L );
180        ops.write( new byte[] { ( byte ) 1 }, 0, 1 );
181        Assert.assertEquals( 1L, ops.getLength() );
182        ops.setLength( 0L );
183
184        ops.setLength( 10L );
185        ops.setFilePointer( 10L );
186        ops.write( new byte[] { ( byte ) 1 }, 0, 1 );
187        Assert.assertEquals( 11L, ops.getLength() );
188        ops.setLength( 0L );
189
190        ops.setLength( 0L );
191        ops.setFilePointer( 0L );
192        ops.write( new byte[] {}, 0, 0 );
193        Assert.assertEquals( 0L, ops.getLength() );
194        ops.setLength( 0L );
195        ops.setFilePointer( 0L );
196
197        ops.write( new byte[ 0 ], 0, 0 );
198        Assert.assertEquals( 0L, ops.getLength() );
199        Assert.assertEquals( 0L, ops.getFilePointer() );
200
201        ops.setLength( 0L );
202    }
203
204    /**
205     * Tests the {@link FileOperations#read} method.
206     * <ol>
207     * <li>Sets the length to {@code 1} and the filepointer to {@code 1} and
208     * tries to read {@code 1} byte checking for EOF.</li>
209     * </ol>
210     */
211    public void testEndOfFile() throws Exception
212    {
213        final FileOperations ops = this.getFileOperations();
214        ops.setLength( 1L );
215        ops.setFilePointer( 1L );
216
217        Assert.assertEquals( 0, ops.read( new byte[ 0 ], 0, 0 ) );
218        Assert.assertEquals( FileOperations.EOF,
219                             ops.read( new byte[ 1 ], 0, 1 ) );
220
221        ops.setLength( 100000L );
222        ops.setFilePointer( 100000L );
223        Assert.assertEquals( 0, ops.read( new byte[ 0 ], 0, 0 ) );
224        Assert.assertEquals( FileOperations.EOF,
225                             ops.read( new byte[ 1 ], 0, 1 ) );
226
227        ops.setLength( 0L );
228    }
229
230    /**
231     * Tests the {@link FileOperations#read} method.
232     * <p><ol>
233     * <li>Reads {@code 101} byte from a buffer of {@code 100} byte and checks
234     * that the method returns {@code EOF} for end of file.</li>
235     * <li>Writes some digits to the file and checks that property
236     * {@code length} matches the expected value after writing.</li>
237     * <li>Sets the file pointer to the middle of the file and reads more bytes
238     * than available in the file checking to get the expected number of read
239     * bytes returned from the method.</li>
240     * <li>Reads one more byte and checks that the method returns {@code EOF}
241     * for end of file.</li>
242     * <li>Reads all written data and checks that the read data matches the
243     * written data.</li>
244     * </ol></p>
245     */
246    public void testRead() throws Exception
247    {
248        final FileOperations ops = this.getFileOperations();
249        final byte[] digits = new byte[ 100 ]; // Muss durch 2 teilbar sein.
250        final byte[] buf = new byte[ digits.length ];
251        Arrays.fill( digits, ( byte ) '1' );
252
253        int toRead = 0;
254        int totalRead = 0;
255        int read = 0;
256
257        // EOF
258        Assert.assertEquals( FileOperations.EOF,
259                             ops.read( new byte[ 100 ], 0, 100 ) );
260
261        ops.setFilePointer( 0L );
262        ops.write( digits, 0, digits.length );
263        Assert.assertEquals( digits.length, ops.getLength() );
264
265        // Rest before EOF
266        ops.setFilePointer( digits.length / 2 );
267
268        toRead = digits.length;
269        do
270        {
271            read = ops.read( buf, totalRead, toRead );
272            if ( read != FileOperations.EOF )
273            {
274                totalRead += read;
275                toRead -= read;
276            }
277        }
278        while ( totalRead < digits.length && read != FileOperations.EOF );
279
280        Assert.assertEquals( digits.length / 2, totalRead );
281        Assert.assertEquals( FileOperations.EOF,
282                             ops.read( buf, buf.length - 1, 1 ) );
283
284        // Read the written data.
285        ops.setFilePointer( 0L );
286        toRead = digits.length;
287        totalRead = 0;
288        do
289        {
290            read = ops.read( buf, totalRead, toRead );
291            if ( read != FileOperations.EOF )
292            {
293                totalRead += read;
294                toRead -= read;
295            }
296        }
297        while ( totalRead < digits.length && read != FileOperations.EOF );
298
299        Assert.assertEquals( digits.length, totalRead );
300        Assert.assertTrue( Arrays.equals( digits, buf ) );
301        ops.setLength( 0 );
302    }
303
304    /**
305     * Tests the {@link FileOperations#write} method.
306     * <p><ol>
307     * <li>Writes some digits to the file and checks that property
308     * {@code length} matches the expected value after writing.</li>
309     * <li>Sets the file pointer after the end of the file and writes some
310     * digits to the file checking that property {@code length} matches the
311     * expected value after writing.</li>
312     * <li>Reads the written data and checks that the read data matches the
313     * written data.</li>
314     * </ol></p>
315     */
316    public void testWrite() throws Exception
317    {
318        final long off;
319        final FileOperations ops = this.getFileOperations();
320        final byte[] digits = new byte[ 100 ]; // Muss durch 2 teilbar sein.
321        final byte[] buf = new byte[ digits.length ];
322        int totalRead = 0;
323        int toRead = 0;
324        int read = 0;
325        Arrays.fill( digits, ( byte ) '1' );
326
327        ops.setFilePointer( 0L );
328        ops.write( digits, 0, 100 );
329        Assert.assertEquals( digits.length, ops.getLength() );
330
331        off = ops.getLength() * 2;
332        ops.setFilePointer( off );
333        ops.write( digits, 0, 100 );
334        ops.setFilePointer( off );
335
336        toRead = digits.length;
337        do
338        {
339            read = ops.read( buf, totalRead, toRead );
340            if ( read != FileOperations.EOF )
341            {
342                totalRead += read;
343                toRead -= read;
344            }
345        }
346        while ( totalRead < digits.length && read != FileOperations.EOF );
347        Assert.assertEquals( digits.length, totalRead );
348        Assert.assertTrue( Arrays.equals( digits, buf ) );
349        ops.setLength( 0 );
350    }
351
352    //-------------------------------------------------------------------Tests--
353}