Home | History | Annotate | Download | only in testframework
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.testframework;
     19 
     20 import junit.framework.Assert;
     21 import junit.framework.TestCase;
     22 import junit.framework.TestSuite;
     23 
     24 import java.io.IOException;
     25 import java.io.OutputStream;
     26 import java.util.Arrays;
     27 import java.util.Random;
     28 
     29 /**
     30  * Tests behaviour common to all implementations of {@link OutputStream}. This
     31  * adapts streams that collects untransformed bytes so that they may be tested.
     32  */
     33 public abstract class SinkTester {
     34 
     35     private boolean throwsExceptions = true;
     36 
     37     /**
     38      * Creates a new output stream ready to receive an arbitrary number of
     39      * bytes. Each time this method is invoked, any previously returned output
     40      * streams may be discarded.
     41      */
     42     public abstract OutputStream create() throws Exception;
     43 
     44     /**
     45      * Returns the current set of bytes written to the output stream last
     46      * returned by {@link #create}, and releases any resources held by that
     47      * stream.
     48      */
     49     public abstract byte[] getBytes() throws Exception;
     50 
     51     /**
     52      * Configures whether the stream is expected to throw exceptions when an
     53      * error is encountered. Classes like {@code PrintStream} report errors via
     54      * an API method instead.
     55      */
     56     public SinkTester setThrowsExceptions(boolean throwsExceptions) {
     57         this.throwsExceptions = throwsExceptions;
     58         return this;
     59     }
     60 
     61     public final TestSuite createTests() {
     62         TestSuite result = new TestSuite();
     63         result.addTest(new SinkTestCase("sinkTestNoWriting"));
     64         result.addTest(new SinkTestCase("sinkTestWriteZeroBytes"));
     65         result.addTest(new SinkTestCase("sinkTestWriteByteByByte"));
     66         result.addTest(new SinkTestCase("sinkTestWriteArray"));
     67         result.addTest(new SinkTestCase("sinkTestWriteOffset"));
     68         result.addTest(new SinkTestCase("sinkTestWriteLargeArray"));
     69 
     70         if (throwsExceptions) {
     71             result.addTest(new SinkTestCase("sinkTestWriteAfterClose"));
     72         } else {
     73             result.addTest(new SinkTestCase("sinkTestWriteAfterCloseSuppressed"));
     74         }
     75 
     76         return result;
     77     }
     78 
     79     @Override
     80     public String toString() {
     81         return getClass().getName();
     82     }
     83 
     84     private static void assertArrayEquals(byte[] expected, byte[] actual) {
     85         Assert.assertEquals(Arrays.toString(expected), Arrays.toString(actual));
     86     }
     87 
     88     public class SinkTestCase extends TestCase {
     89 
     90         private SinkTestCase(String name) {
     91             super(name);
     92         }
     93 
     94         public void sinkTestNoWriting() throws Exception {
     95             byte[] expected = new byte[] { };
     96 
     97             OutputStream out = create();
     98             out.close();
     99             assertArrayEquals(expected, getBytes());
    100         }
    101 
    102         public void sinkTestWriteZeroBytes() throws Exception {
    103             byte[] expected = new byte[] { };
    104 
    105             OutputStream out = create();
    106             byte[] a = new byte[1024];
    107             out.write(a, 1000, 0);
    108             out.write(a, 0, 0);
    109             out.write(new byte[] { });
    110 
    111             out.close();
    112             assertArrayEquals(expected, getBytes());
    113         }
    114 
    115         public void sinkTestWriteByteByByte() throws Exception {
    116             byte[] expected = new byte[] { 5, 6, 7, 3, 4, 5, 3, 2, 1 };
    117 
    118             OutputStream out = create();
    119             for (byte b : expected) {
    120                 out.write(b);
    121             }
    122 
    123             out.close();
    124             assertArrayEquals(expected, getBytes());
    125         }
    126 
    127         public void sinkTestWriteArray() throws Exception {
    128             byte[] expected = new byte[] {
    129                     5, 6,
    130                     7, 3, 4, 5,
    131                     3, 2, 1
    132             };
    133 
    134             OutputStream out = create();
    135 
    136             byte[] a = new byte[] { 5, 6 };
    137             out.write(a);
    138 
    139             byte[] b = new byte[] { 7, 3, 4, 5 };
    140             out.write(b);
    141 
    142             byte[] c = new byte[] { 3, 2, 1 };
    143             out.write(c);
    144 
    145             out.close();
    146             assertArrayEquals(expected, getBytes());
    147         }
    148 
    149         public void sinkTestWriteOffset() throws Exception {
    150             byte[] expected = new byte[] {
    151                     5, 6,
    152                     7, 3, 4, 5,
    153                     3, 2, 1
    154             };
    155 
    156             OutputStream out = create();
    157 
    158             byte[] a = new byte[1024];
    159             a[1000] = 5;
    160             a[1001] = 6;
    161             out.write(a, 1000, 2);
    162 
    163             byte[] b = new byte[1024];
    164             b[1020] = 7;
    165             b[1021] = 3;
    166             b[1022] = 4;
    167             b[1023] = 5;
    168             out.write(b, 1020, 4);
    169 
    170             byte[] c = new byte[1024];
    171             c[0] = 3;
    172             c[1] = 2;
    173             c[2] = 1;
    174             out.write(c, 0, 3);
    175 
    176             out.close();
    177             assertArrayEquals(expected, getBytes());
    178         }
    179 
    180         public void sinkTestWriteLargeArray() throws Exception {
    181             byte[] expected = new byte[(1024 * 1024) + 1]; // 1 MB + 1 byte
    182             new Random().nextBytes(expected);
    183 
    184             OutputStream out = create();
    185             out.write(expected);
    186             out.close();
    187 
    188             assertArrayEquals(expected, getBytes());
    189         }
    190 
    191         public void sinkTestWriteAfterClose() throws Exception {
    192             byte[] expectedBytes = { 5, 6 };
    193             OutputStream out = create();
    194 
    195             out.write(expectedBytes);
    196             out.close();
    197 
    198             try {
    199                 out.write(new byte[] { 7, 3, 4, 5 });
    200                 fail("expected already closed exception");
    201             } catch (IOException expected) {
    202             }
    203 
    204             assertArrayEquals(expectedBytes, getBytes());
    205         }
    206 
    207         public void sinkTestWriteAfterCloseSuppressed() throws Exception {
    208             OutputStream out = create();
    209             out.write(new byte[] { 5, 6 });
    210             out.close();
    211             out.write(new byte[] { 7, 3, 4, 5 }); // no exception expected!
    212         }
    213 
    214         // adding a new test? Don't forget to update createTests().
    215 
    216         @Override
    217         public String getName() {
    218             return SinkTester.this.toString() + ":" + super.getName();
    219         }
    220     }
    221 }
    222