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.util.Arrays;
024import junit.framework.Assert;
025import junit.framework.TestCase;
026import org.jdtaus.core.io.StructuredFile;
027
028/**
029 * Testcase for {@code StructuredFile} implementations.
030 *
031 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
032 * @version $JDTAUS: StructuredFileTest.java 8641 2012-09-27 06:45:17Z schulte $
033 */
034public abstract class StructuredFileTest extends TestCase
035{
036    //--Constants---------------------------------------------------------------
037
038    /** Value for property {@code blockSize} the tests are run with. */
039    public static final int BLOCK_SIZE = 1;
040
041    /** Number of iterations to test. */
042    private static final int ITERATIONS = 20;
043
044    /** Value to initialize new blocks with. */
045    private static final byte INIT_CHAR = ( byte ) ' ';
046
047    //---------------------------------------------------------------Constants--
048    //--Fields------------------------------------------------------------------
049
050    /** The implementation to test. */
051    private StructuredFile structuredFile;
052
053    /** Expected data to read for known written data. */
054    private byte[] expectedData;
055
056    //------------------------------------------------------------------Fields--
057    //--StructuredFileTest------------------------------------------------------
058
059    /**
060     * Reads the contents of the {@code StructuredFile} implementation
061     * beeing tested as an array of byte.
062     *
063     * @return contents of the {@code StructuredFile} implementation beeing
064     * tested.
065     */
066    protected abstract byte[] getStructuredData();
067
068    /**
069     * Gets a new instance of the {@code StructuredFile} implementation to test.
070     *
071     * @return a new instance of the {@code StructuredFile} implementation to
072     * test.
073     */
074    protected abstract StructuredFile getStructuredFile();
075
076    //------------------------------------------------------StructuredFileTest--
077    //--Helpermethods-----------------------------------------------------------
078
079    private byte[] getRandomBlock( final int size )
080    {
081        final byte[] random = new byte[ size ];
082        for ( int i = 0; i < random.length; i++ )
083        {
084            random[i] = ( byte ) ( Math.random() * 0xFF );
085        }
086
087        return random;
088    }
089
090    private byte[] getFilledBlock( final int size, final byte fill )
091    {
092        final byte[] filled = new byte[ size ];
093        Arrays.fill( filled, fill );
094        return filled;
095    }
096
097    //-----------------------------------------------------------Helpermethods--
098    //--TestCase----------------------------------------------------------------
099
100    protected void setUp() throws Exception
101    {
102        this.structuredFile = this.getStructuredFile();
103        this.expectedData = new byte[ StructuredFileTest.BLOCK_SIZE ];
104        Arrays.fill( this.expectedData, StructuredFileTest.INIT_CHAR );
105    }
106
107    protected void tearDown() throws Exception
108    {
109        this.structuredFile = null;
110    }
111
112    protected void runTest() throws Throwable
113    {
114        this.testGetBlockSize();
115        this.testGetBlockCount();
116        this.testInsertBlocks();
117        this.testDeleteBlocks();
118        this.testReadWriteBlock();
119    }
120
121    //----------------------------------------------------------------TestCase--
122    //--Tests-------------------------------------------------------------------
123
124    /**
125     * Test of getBlockSize method of class org.jdtaus.common.io.StructuredFile.
126     */
127    public void testGetBlockSize() throws Exception
128    {
129        Assert.assertEquals( StructuredFileTest.BLOCK_SIZE,
130                             this.structuredFile.getBlockSize() );
131
132    }
133
134    /**
135     * Test of getBlockCount method of class org.jdtaus.common.io.StructuredFile.
136     */
137    public void testGetBlockCount() throws Exception
138    {
139        Assert.assertEquals( 0L, this.structuredFile.getBlockCount() );
140    }
141
142    /**
143     * Test of insertBlocks method of class org.jdtaus.common.io.StructuredFile.
144     */
145    public void testInsertBlocks() throws Exception
146    {
147        this.structuredFile.insertBlocks( 0L, 1 );
148        Assert.assertEquals( 1L, this.structuredFile.getBlockCount() );
149    }
150
151    /**
152     * Test of deleteBlocks method of class org.jdtaus.common.io.StructuredFile.
153     */
154    public void testDeleteBlocks() throws Exception
155    {
156        this.structuredFile.deleteBlocks( 0L,
157                                          this.structuredFile.getBlockCount() );
158
159        Assert.assertEquals( 0L, this.structuredFile.getBlockCount() );
160    }
161
162    /**
163     * Test of writeBlock method of class org.jdtaus.common.io.StructuredFile.
164     */
165    public void testReadWriteBlock() throws Exception
166    {
167        final long startTime = System.currentTimeMillis();
168
169        int i;
170        int j;
171        int written;
172        long count;
173        long insertIndex;
174        long writeIndex;
175        long maxIndex;
176        long oldBlocks;
177        byte[] filled;
178        final int blockSize = this.structuredFile.getBlockSize();
179        byte[] newExpectedData = {};
180        byte[] expectedData = {};
181        final byte[] read = new byte[ blockSize ];
182        final byte[] write = new byte[ blockSize ];
183        final byte[] initBlock = new byte[ blockSize ];
184
185        Arrays.fill( initBlock, StructuredFileTest.INIT_CHAR );
186
187        // Creates blocks filled with random data and checks that written
188        // data is read unchanged.
189        for ( i = 0, insertIndex = 0L; i <
190            StructuredFileTest.ITERATIONS; i++, insertIndex++ )
191        {
192
193            count = StructuredFileTest.ITERATIONS - insertIndex;
194            maxIndex = insertIndex + count;
195            filled =
196                this.getFilledBlock( ( int ) count * blockSize, ( byte ) i );
197
198            oldBlocks = this.structuredFile.getBlockCount();
199            this.structuredFile.insertBlocks( insertIndex, count );
200            Assert.assertEquals( oldBlocks + count,
201                                 this.structuredFile.getBlockCount() );
202
203            // Initialize new blocks.
204            for ( j = 0; j < count; j++ )
205            {
206                this.structuredFile.writeBlock( insertIndex + j, 0,
207                                                initBlock );
208
209            }
210            newExpectedData = new byte[ expectedData.length + filled.length ];
211            System.arraycopy( expectedData, 0, newExpectedData, 0,
212                              ( int ) ( insertIndex * blockSize ) );
213
214            System.arraycopy( expectedData, ( int ) ( insertIndex * blockSize ),
215                              newExpectedData, ( int ) ( maxIndex * blockSize ),
216                              ( int ) ( expectedData.length - insertIndex *
217                              blockSize ) );
218
219            Arrays.fill( newExpectedData, ( int ) ( insertIndex * blockSize ),
220                         ( int ) ( ( insertIndex + count ) * blockSize ),
221                         StructuredFileTest.INIT_CHAR );
222
223            expectedData = newExpectedData;
224            Assert.assertEquals( true, Arrays.equals(
225                                 expectedData, this.getStructuredData() ) );
226
227            maxIndex = insertIndex + count;
228            for ( writeIndex = insertIndex, written = 0; writeIndex < maxIndex;
229                writeIndex++, written++ )
230            {
231
232                System.arraycopy( filled, written * blockSize, write, 0,
233                                  blockSize );
234
235                this.structuredFile.writeBlock( writeIndex, 0, write );
236                this.structuredFile.readBlock( writeIndex, 0, read );
237                Assert.assertEquals( true, Arrays.equals( write, read ) );
238
239                System.arraycopy( write, 0, expectedData,
240                                  ( int ) ( writeIndex * blockSize ), blockSize );
241
242            }
243
244            Assert.assertEquals( true, Arrays.equals(
245                                 expectedData, this.getStructuredData() ) );
246
247        }
248
249        Assert.assertEquals( true, Arrays.equals(
250                             expectedData, this.getStructuredData() ) );
251
252        this.structuredFile.deleteBlocks( 0L,
253                                          this.structuredFile.getBlockCount() );
254
255        Assert.assertTrue( this.structuredFile.getBlockCount() == 0L );
256
257    //System.out.println("Ran " + (System.currentTimeMillis() - startTime) +
258    //    " ms.");
259
260    }
261
262    //-------------------------------------------------------------------Tests--
263}