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 8743 2012-10-07 03:06:20Z 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    /** Creates a new {@code StructuredFileTest} instance. */
060    public StructuredFileTest()
061    {
062        super();
063    }
064
065    /**
066     * Reads the contents of the {@code StructuredFile} implementation
067     * beeing tested as an array of byte.
068     *
069     * @return contents of the {@code StructuredFile} implementation beeing
070     * tested.
071     */
072    protected abstract byte[] getStructuredData();
073
074    /**
075     * Gets a new instance of the {@code StructuredFile} implementation to test.
076     *
077     * @return a new instance of the {@code StructuredFile} implementation to
078     * test.
079     */
080    protected abstract StructuredFile getStructuredFile();
081
082    //------------------------------------------------------StructuredFileTest--
083    //--Helpermethods-----------------------------------------------------------
084
085    private byte[] getRandomBlock( final int size )
086    {
087        final byte[] random = new byte[ size ];
088        for ( int i = 0; i < random.length; i++ )
089        {
090            random[i] = ( byte ) ( Math.random() * 0xFF );
091        }
092
093        return random;
094    }
095
096    private byte[] getFilledBlock( final int size, final byte fill )
097    {
098        final byte[] filled = new byte[ size ];
099        Arrays.fill( filled, fill );
100        return filled;
101    }
102
103    //-----------------------------------------------------------Helpermethods--
104    //--TestCase----------------------------------------------------------------
105
106    protected void setUp() throws Exception
107    {
108        this.structuredFile = this.getStructuredFile();
109        this.expectedData = new byte[ StructuredFileTest.BLOCK_SIZE ];
110        Arrays.fill( this.expectedData, StructuredFileTest.INIT_CHAR );
111    }
112
113    protected void tearDown() throws Exception
114    {
115        this.structuredFile = null;
116    }
117
118    protected void runTest() throws Throwable
119    {
120        this.testGetBlockSize();
121        this.testGetBlockCount();
122        this.testInsertBlocks();
123        this.testDeleteBlocks();
124        this.testReadWriteBlock();
125    }
126
127    //----------------------------------------------------------------TestCase--
128    //--Tests-------------------------------------------------------------------
129
130    /**
131     * Test of getBlockSize method of class org.jdtaus.common.io.StructuredFile.
132     */
133    public void testGetBlockSize() throws Exception
134    {
135        Assert.assertEquals( StructuredFileTest.BLOCK_SIZE,
136                             this.structuredFile.getBlockSize() );
137
138    }
139
140    /**
141     * Test of getBlockCount method of class org.jdtaus.common.io.StructuredFile.
142     */
143    public void testGetBlockCount() throws Exception
144    {
145        Assert.assertEquals( 0L, this.structuredFile.getBlockCount() );
146    }
147
148    /**
149     * Test of insertBlocks method of class org.jdtaus.common.io.StructuredFile.
150     */
151    public void testInsertBlocks() throws Exception
152    {
153        this.structuredFile.insertBlocks( 0L, 1 );
154        Assert.assertEquals( 1L, this.structuredFile.getBlockCount() );
155    }
156
157    /**
158     * Test of deleteBlocks method of class org.jdtaus.common.io.StructuredFile.
159     */
160    public void testDeleteBlocks() throws Exception
161    {
162        this.structuredFile.deleteBlocks( 0L,
163                                          this.structuredFile.getBlockCount() );
164
165        Assert.assertEquals( 0L, this.structuredFile.getBlockCount() );
166    }
167
168    /**
169     * Test of writeBlock method of class org.jdtaus.common.io.StructuredFile.
170     */
171    public void testReadWriteBlock() throws Exception
172    {
173        final long startTime = System.currentTimeMillis();
174
175        int i;
176        int j;
177        int written;
178        long count;
179        long insertIndex;
180        long writeIndex;
181        long maxIndex;
182        long oldBlocks;
183        byte[] filled;
184        final int blockSize = this.structuredFile.getBlockSize();
185        byte[] newExpectedData = {};
186        byte[] expectedData = {};
187        final byte[] read = new byte[ blockSize ];
188        final byte[] write = new byte[ blockSize ];
189        final byte[] initBlock = new byte[ blockSize ];
190
191        Arrays.fill( initBlock, StructuredFileTest.INIT_CHAR );
192
193        // Creates blocks filled with random data and checks that written
194        // data is read unchanged.
195        for ( i = 0, insertIndex = 0L; i <
196            StructuredFileTest.ITERATIONS; i++, insertIndex++ )
197        {
198
199            count = StructuredFileTest.ITERATIONS - insertIndex;
200            maxIndex = insertIndex + count;
201            filled =
202                this.getFilledBlock( ( int ) count * blockSize, ( byte ) i );
203
204            oldBlocks = this.structuredFile.getBlockCount();
205            this.structuredFile.insertBlocks( insertIndex, count );
206            Assert.assertEquals( oldBlocks + count,
207                                 this.structuredFile.getBlockCount() );
208
209            // Initialize new blocks.
210            for ( j = 0; j < count; j++ )
211            {
212                this.structuredFile.writeBlock( insertIndex + j, 0,
213                                                initBlock );
214
215            }
216            newExpectedData = new byte[ expectedData.length + filled.length ];
217            System.arraycopy( expectedData, 0, newExpectedData, 0,
218                              ( int ) ( insertIndex * blockSize ) );
219
220            System.arraycopy( expectedData, ( int ) ( insertIndex * blockSize ),
221                              newExpectedData, ( int ) ( maxIndex * blockSize ),
222                              ( int ) ( expectedData.length - insertIndex *
223                              blockSize ) );
224
225            Arrays.fill( newExpectedData, ( int ) ( insertIndex * blockSize ),
226                         ( int ) ( ( insertIndex + count ) * blockSize ),
227                         StructuredFileTest.INIT_CHAR );
228
229            expectedData = newExpectedData;
230            Assert.assertEquals( true, Arrays.equals(
231                                 expectedData, this.getStructuredData() ) );
232
233            maxIndex = insertIndex + count;
234            for ( writeIndex = insertIndex, written = 0; writeIndex < maxIndex;
235                writeIndex++, written++ )
236            {
237
238                System.arraycopy( filled, written * blockSize, write, 0,
239                                  blockSize );
240
241                this.structuredFile.writeBlock( writeIndex, 0, write );
242                this.structuredFile.readBlock( writeIndex, 0, read );
243                Assert.assertEquals( true, Arrays.equals( write, read ) );
244
245                System.arraycopy( write, 0, expectedData,
246                                  ( int ) ( writeIndex * blockSize ), blockSize );
247
248            }
249
250            Assert.assertEquals( true, Arrays.equals(
251                                 expectedData, this.getStructuredData() ) );
252
253        }
254
255        Assert.assertEquals( true, Arrays.equals(
256                             expectedData, this.getStructuredData() ) );
257
258        this.structuredFile.deleteBlocks( 0L,
259                                          this.structuredFile.getBlockCount() );
260
261        Assert.assertTrue( this.structuredFile.getBlockCount() == 0L );
262
263    //System.out.println("Ran " + (System.currentTimeMillis() - startTime) +
264    //    " ms.");
265
266    }
267
268    //-------------------------------------------------------------------Tests--
269}