View Javadoc

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 }