root/trunk/test/java/org/jcoderz/commons/util/IoUtilTest.java

Revision 1638, 8.5 kB (checked in by mgriffel, 21 months ago)

Added new method IoUtil#skip(). Wraps strange InputStream#skip?() that violates the POLA.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 *
4 * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *    * Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    * Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials
15 *      provided with the distribution.
16 *    * Neither the name of the jCoderZ.org Project nor the names of
17 *      its contributors may be used to endorse or promote products
18 *      derived from this software without specific prior written
19 *      permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33package org.jcoderz.commons.util;
34
35import java.io.BufferedInputStream;
36import java.io.ByteArrayInputStream;
37import java.io.ByteArrayOutputStream;
38import java.io.File;
39import java.io.FileInputStream;
40import java.io.FileOutputStream;
41import java.io.IOException;
42import java.io.InputStream;
43import java.io.OutputStream;
44import java.io.RandomAccessFile;
45import java.io.Reader;
46import java.io.Writer;
47import java.nio.ByteBuffer;
48import java.nio.channels.Channel;
49import java.nio.channels.ReadableByteChannel;
50import java.util.Arrays;
51import java.util.Random;
52
53import junit.framework.TestCase;
54
55
56/**
57 * Unit Tests for the class {@link org.jcoderz.commons.util.IoUtil}.
58 *
59 * @author Michael Griffel
60 */
61public class IoUtilTest
62      extends TestCase
63{
64   private static final Random RANDOM_GENERATOR = new Random();
65   
66   private static final int GAP_SIZE = 10 * 1024;
67
68   /**
69    * Tests the method {@link IoUtil#readFully(InputStream, int)}.
70    * @throws IOException in case of an unexpected I/O error.
71    */
72   public void testReadFully ()
73         throws IOException
74   {
75      read1kBytes();
76      read0Bytes();
77      readAhead();
78      underread();
79   }
80
81   /**
82    * Tests the method {@link IoUtil#close(InputStream)}.
83    */
84   public void testSafeCloseInputStream ()
85   {
86      final InputStream in = new ByteArrayInputStream(new byte[0])
87         {
88            public void close ()
89                  throws IOException
90            {
91               throw new IOException();
92            }
93         };
94
95      IoUtil.close(in);
96      IoUtil.close(in);
97      IoUtil.close((InputStream) null);
98   }
99
100   /**
101    * Tests the method {@link IoUtil#close(OutputStream)}.
102    */
103   public void testSafeCloseOutputStream ()
104   {
105      final OutputStream out = new ByteArrayOutputStream()
106         {
107            public void close ()
108                  throws IOException
109            {
110               throw new IOException();
111            }
112         };
113
114      IoUtil.close(out);
115      IoUtil.close(out);
116      IoUtil.close((OutputStream) null);
117   }
118
119   /**
120    * Tests the method {@link IoUtil#close(Reader)}.
121    */
122   public void testSafeCloseReader ()
123   {
124      final Reader reader = new Reader()
125         {
126            public void close ()
127                  throws IOException
128            {
129               throw new IOException();
130            }
131
132            public int read (char[] cbuf, int off, int len)
133            {
134               return 0;
135            }
136         };
137
138      IoUtil.close(reader);
139      IoUtil.close(reader);
140      IoUtil.close((Reader) null);
141   }
142
143   /**
144    * Tests the method {@link IoUtil#close(Writer)}.
145    */
146   public void testSafeCloseWriter ()
147   {
148      final Writer writer = new Writer()
149         {
150            public void close ()
151                  throws IOException
152            {
153               throw new IOException();
154            }
155
156            public void flush ()
157            {
158                // NOP
159            }
160
161            public void write (char[] cbuf, int off, int len)
162            {
163                // NOP
164            }
165         };
166
167      IoUtil.close(writer);
168      IoUtil.close(writer);
169      IoUtil.close((Writer) null);
170   }
171
172   /**
173    * Tests the method {@link IoUtil#close(RandomAccessFile)}.
174    * @throws Exception in case of an unexpected error.
175    */
176   public void testSafeCloseRandomAccessFile ()
177         throws Exception
178   {
179      final File tmp = File.createTempFile("tmp", "tmp");
180      tmp.deleteOnExit();
181      final RandomAccessFile file = new RandomAccessFile(tmp, "r")
182         {
183            public void close ()
184                  throws IOException
185            {
186               throw new IOException();
187            }
188         };
189
190      IoUtil.close(file);
191      IoUtil.close(file);
192      IoUtil.close((RandomAccessFile) null);
193   }
194
195   /**
196    * Tests the method {@link IoUtil#close(Channel)}.
197    * @throws Exception in case of an unexpected error.
198    */
199   public void testSafeCloseChannel ()
200         throws Exception
201   {
202      final Channel channel = new ChannelImpl();
203      IoUtil.close(channel);
204      IoUtil.close(channel);
205      IoUtil.close((Channel) null);
206   }
207
208   
209   public void testSkip() throws Exception {
210       final File tmp = File.createTempFile("fawkez", "tmp");
211       FileOutputStream out = new FileOutputStream(tmp);
212       out.write(1);
213       out.write(new byte[GAP_SIZE]);
214       out.write(2);
215       out.close();
216       final InputStream in = new BufferedInputStream(new FileInputStream((tmp)));
217       int first = in.read();
218       IoUtil.skip(in, GAP_SIZE); // instead of in.skip(GAP_SIZE);
219       int second = in.read();
220       assertEquals(3, first + second);
221       
222   }
223
224   private void read1kBytes ()
225         throws IOException
226   {
227      final byte[] inData = new byte[Constants.BYTES_PER_KILO_BYTE];
228      final InputStream in = createRandomInputStream(inData);
229      final byte[] outData = IoUtil.readFully(in, inData.length);
230      assertTrue("bytes arrays should be equal",
231            Arrays.equals(inData, outData));
232   }
233
234   private void read0Bytes ()
235         throws IOException
236   {
237      final byte[] inData = new byte[0];
238      final InputStream in = createRandomInputStream(inData);
239      final byte[] outData = IoUtil.readFully(in, inData.length);
240      assertTrue("bytes arrays should be equal",
241            Arrays.equals(inData, outData));
242   }
243
244   private void readAhead ()
245   {
246      final byte[] inData = new byte[Constants.BYTES_PER_KILO_BYTE];
247      final InputStream in = createRandomInputStream(inData);
248      try
249      {
250         IoUtil.readFully(in, inData.length + 1);
251         fail("Expected IOException for reading more bytes than available");
252      }
253      catch (IOException expected)
254      {
255         assertNotNull("Expected a real exception.", expected);
256      }
257   }
258   private void underread ()
259         throws IOException
260   {
261      final byte[] inData = new byte[Constants.BYTES_PER_KILO_BYTE];
262      final InputStream in = createRandomInputStream(inData);
263      final byte[] outData = IoUtil.readFully(in, inData.length - 1);
264      final byte[] strippedInData = new byte[inData.length - 1];
265      System.arraycopy(inData, 0, strippedInData, 0, inData.length - 1);
266      assertTrue("bytes arrays should be equal except the last one",
267            Arrays.equals(strippedInData, outData));
268   }
269
270   private InputStream createRandomInputStream (byte[] inData)
271   {
272      RANDOM_GENERATOR.nextBytes(inData);
273      final InputStream in = new ByteArrayInputStream(inData);
274      return in;
275   }
276
277   private static final class ChannelImpl
278         implements ReadableByteChannel
279   {
280      private boolean mIsOpen = true;
281     
282      /** {@inheritDoc} */
283      public int read (ByteBuffer dst)
284      {
285         return 0;
286      }
287     
288      /** {@inheritDoc} */
289      public void close ()
290            throws IOException
291      {
292         if (mIsOpen)
293         {
294            mIsOpen = false;
295         }
296         else
297         {
298            throw new IOException();
299         }
300      }
301
302      /** {@inheritDoc} */
303      public boolean isOpen ()
304      {
305         return mIsOpen;
306      }
307   }
308
309
310}
Note: See TracBrowser for help on using the browser.