    1   /* RecordingOutputStreamTest
    2    *
    3    * $Id: RecordingOutputStreamTest.java 1388 2004-02-18 00:11:36Z stack-sf $
    4    *
    5    * Created on Jan 21, 2004
    6    *
    7    * Copyright (C) 2004 Internet Archive.
    8    *
    9    * This file is part of the Heritrix web crawler (crawler.archive.org).
    10   *
    11   * Heritrix is free software; you can redistribute it and/or modify
    12   * it under the terms of the GNU Lesser Public License as published by
    13   * the Free Software Foundation; either version 2.1 of the License, or
    14   * any later version.
    15   *
    16   * Heritrix is distributed in the hope that it will be useful,
    17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19   * GNU Lesser Public License for more details.
    20   *
    21   * You should have received a copy of the GNU Lesser Public License
    22   * along with Heritrix; if not, write to the Free Software
    23   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24   */
    25  package org.archive.io;
    26
    27  import java.io.File;
    28  import java.io.FileInputStream;
    29  import java.io.FileOutputStream;
    30  import java.io.IOException;
    31
    32  import org.archive.util.TmpDirTestCase;
    33
    34
    35  /***
    36   * Test casesfor RecordingOutputStream.
    37   *
    38   * @author stack
    39   */
    40  public class RecordingOutputStreamTest extends TmpDirTestCase
    41  {
    42      /***
    43       * Size of buffer used in tests.
    44       */
    45      private static final int BUFFER_SIZE = 5;
    46
    47      /***
    48       * How much to write total to testing RecordingOutputStream.
    49       */
    50      private static final int WRITE_TOTAL = 10;
    51
    52
    53      /*
    54       * @see TmpDirTestCase#setUp()
    55       */
    56      protected void setUp() throws Exception
    57      {
    58          super.setUp();
    59      }
    60
    61      /***
    62       * Test reusing instance of RecordingOutputStream.
    63       *
    64       * @throws IOException Failed open of backing file or opening of
    65       * input streams verifying recording.
    66       */
    67      public void testReuse()
    68          throws IOException
    69      {
    70          final String BASENAME = "testReuse";
    71          cleanUpOldFiles(BASENAME);
    72          RecordingOutputStream ros = new RecordingOutputStream(BUFFER_SIZE,
    73              (new File(getTmpDir(), BASENAME + "Bkg.txt")).getAbsolutePath());
    74          for (int i = 0; i < 3; i++)
    75          {
    76              reuse(BASENAME, ros, i);
    77          }
    78      }
    79
    80      private void reuse(String baseName, RecordingOutputStream ros, int index)
    81          throws IOException
    82      {
    83          final String BASENAME = baseName + Integer.toString(index);
    84          File f = writeIntRecordedFile(ros, BASENAME, WRITE_TOTAL);
    85          verifyRecording(ros, f, WRITE_TOTAL);
    86          // Do again to test that I can get a new ReplayInputStream on same
    87          // RecordingOutputStream.
    88          verifyRecording(ros, f, WRITE_TOTAL);
    89      }
    90
    91      /***
    92       * Method to test for void write(int).
    93       *
    94       * Uses small buffer size and small write size.  Test mark and reset too.
    95       *
    96       * @throws IOException Failed open of backing file or opening of
    97       * input streams verifying recording.
    98       */
    99      public void testWriteint()
    100         throws IOException
    101     {
    102         final String BASENAME = "testWriteint";
    103         cleanUpOldFiles(BASENAME);
    104         RecordingOutputStream ros = new RecordingOutputStream(BUFFER_SIZE,
    105            (new File(getTmpDir(), BASENAME + "Backing.txt")).getAbsolutePath());
    106         File f = writeIntRecordedFile(ros, BASENAME, WRITE_TOTAL);
    107         verifyRecording(ros, f, WRITE_TOTAL);
    108         // Do again to test that I can get a new ReplayInputStream on same
    109         // RecordingOutputStream.
    110         verifyRecording(ros, f, WRITE_TOTAL);
    111     }
    112
    113     /***
    114      * Method to test for void write(byte []).
    115      *
    116      * Uses small buffer size and small write size.
    117      *
    118      * @throws IOException Failed open of backing file or opening of
    119      * input streams verifying recording.
    120      */
    121     public void testWritebytearray()
    122         throws IOException
    123     {
    124         final String BASENAME = "testWritebytearray";
    125         cleanUpOldFiles(BASENAME);
    126         RecordingOutputStream ros = new RecordingOutputStream(BUFFER_SIZE,
    127            (new File(getTmpDir(), BASENAME + "Backing.txt")).getAbsolutePath());
    128         File f = writeByteRecordedFile(ros, BASENAME, WRITE_TOTAL);
    129         verifyRecording(ros, f, WRITE_TOTAL);
    130         // Do again to test that I can get a new ReplayInputStream on same
    131         // RecordingOutputStream.
    132         verifyRecording(ros, f, WRITE_TOTAL);
    133     }
    134
    135     /***
    136      * Test mark and reset.
    137      * @throws IOException
    138      */
    139     public void testMarkReset() throws IOException
    140     {
    141         final String BASENAME = "testMarkReset";
    142         cleanUpOldFiles(BASENAME);
    143         RecordingOutputStream ros = new RecordingOutputStream(BUFFER_SIZE,
    144                 (new File(getTmpDir(), BASENAME + "Backing.txt")).getAbsolutePath());
    145         File f = writeByteRecordedFile(ros, BASENAME, WRITE_TOTAL);
    146         verifyRecording(ros, f, WRITE_TOTAL);
    147         ReplayInputStream ris = ros.getReplayInputStream();
    148         ris.mark(10 /*Arbitrary value*/);
    149         // Read from the stream.
    150         ris.read();
    151         ris.read();
    152         ris.read();
    153         // Reset it.  It should be back at zero.
    154         ris.reset();
    155         assertEquals("Reset to zero", ris.read(), 0);
    156         assertEquals("Reset to zero char 1", ris.read(), 1);
    157         assertEquals("Reset to zero char 2", ris.read(), 2);
    158         // Mark stream.  Here.  Next character should be '3'.
    159         ris.mark(10 /* Arbitrary value*/);
    160         ris.read();
    161         ris.read();
    162         ris.reset();
    163         assertEquals("Reset to zero char 3", ris.read(), 3);
    164     }
    165
    166     /***
    167      * Record a file write.
    168      *
    169      * Write a file w/ characters that start at null and ascend to
    170      * <code>filesize</code>.  Record the writing w/ passed <code>ros</code>
    171      * recordingoutputstream. Return the file recorded as result of method.
    172      * The file  output stream that is recorded is named
    173      * <code>basename</code> + ".txt".
    174      *
    175      * <p>This method writes a character at a time.
    176      *
    177      * @param ros RecordingOutputStream to record with.
    178      * @param basename Basename of file.
    179      * @param size How many characters to write.
    180      * @return Recorded output stream.
    181      */
    182     private File writeIntRecordedFile(RecordingOutputStream ros,
    183             String basename, int size)
    184         throws IOException
    185     {
    186         File f = new File(getTmpDir(), basename + ".txt");
    187         FileOutputStream fos = new FileOutputStream(f);
    188         ros.open(fos);
    189         for (int i = 0; i < WRITE_TOTAL; i++)
    190         {
    191             ros.write(i);
    192         }
    193         ros.close();
    194         fos.close();
    195         assertEquals("Content-Length test", size,
    196             ros.getResponseContentLength());
    197         return f;
    198     }
    199
    200     /***
    201      * Record a file byte array write.
    202      *
    203      * Write a file w/ characters that start at null and ascend to
    204      * <code>filesize</code>.  Record the writing w/ passed <code>ros</code>
    205      * recordingoutputstream. Return the file recorded as result of method.
    206      * The file  output stream that is recorded is named
    207      * <code>basename</code> + ".txt".
    208      *
    209      * <p>This method writes using a byte array.
    210      *
    211      * @param ros RecordingOutputStream to record with.
    212      * @param basename Basename of file.
    213      * @param size How many characters to write.
    214      * @return Recorded output stream.
    215      */
    216     private File writeByteRecordedFile(RecordingOutputStream ros,
    217             String basename, int size)
    218     throws IOException
    219     {
    220         File f = new File(getTmpDir(), basename + ".txt");
    221         FileOutputStream fos = new FileOutputStream(f);
    222         ros.open(fos);
    223         byte [] b = new byte[size];
    224         for (int i = 0; i < size; i++)
    225         {
    226             b[i] = (byte)i;
    227         }
    228         ros.write(b);
    229         ros.close();
    230         fos.close();
    231         assertEquals("Content-Length test", size,
    232                 ros.getResponseContentLength());
    233         return f;
    234     }
    235
    236     /***
    237      * Verify what was written is both in the file written to and in the
    238      * recording stream.
    239      *
    240      * @param ros Stream to check.
    241      * @param f File that was recorded.  Stream should have its content
    242      * exactly.
    243      * @param size Amount of bytes written.
    244      *
    245      * @exception IOException Failure reading streams.
    246      */
    247     private void verifyRecording(RecordingOutputStream ros, File f,
    248          int size) throws IOException
    249     {
    250         assertEquals("Recorded file size.", size, f.length());
    251         FileInputStream fis = new FileInputStream(f);
    252         assertNotNull("FileInputStream not null", fis);
    253         ReplayInputStream ris = ros.getReplayInputStream();
    254         assertNotNull("ReplayInputStream not null", ris);
    255         for (int i = 0; i < size; i++)
    256         {
    257             assertEquals("ReplayInputStream content verification", i,
    258                     ris.read());
    259             assertEquals("Recorded file content verification", i,
    260                     fis.read());
    261         }
    262         assertEquals("ReplayInputStream at EOF", -1, ris.read());
    263         fis.close();
    264         ris.close();
    265     }
    266 }