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/**
19* @author Alexander Y. Kleymenov
20*/
21
22package javax.crypto;
23
24import java.io.BufferedOutputStream;
25import java.io.ByteArrayOutputStream;
26import java.io.OutputStream;
27import java.util.Arrays;
28import javax.crypto.NullCipher;
29
30import junit.framework.TestCase;
31
32/**
33 */
34
35public class CipherOutputStreamTest extends TestCase {
36
37    private static class TestOutputStream extends ByteArrayOutputStream {
38        private boolean closed = false;
39
40        public void close() {
41            closed = true;
42        }
43
44        public boolean wasClosed() {
45            return closed;
46        }
47    }
48
49    /**
50     * CipherOutputStream(OutputStream os) method testing. Tests that
51     * CipherOutputStream uses NullCipher if Cipher is not specified
52     * in the constructor.
53     */
54    public void testCipherOutputStream() throws Exception {
55        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
56        TestOutputStream tos = new TestOutputStream();
57        CipherOutputStream cos = new CipherOutputStream(tos);
58        cos.write(data);
59        cos.flush();
60        byte[] result = tos.toByteArray();
61        if (!Arrays.equals(result, data)) {
62            fail("NullCipher should be used " + "if Cipher is not specified.");
63        }
64    }
65
66    /**
67     * write(int b) method testing. Tests that method writes correct values to
68     * the underlying output stream.
69     */
70    public void testWrite1() throws Exception {
71        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
72        TestOutputStream tos = new TestOutputStream();
73        CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
74        for (int i = 0; i < data.length; i++) {
75            cos.write(data[i]);
76        }
77        cos.flush();
78        byte[] result = tos.toByteArray();
79        if (!Arrays.equals(result, data)) {
80            fail("CipherOutputStream wrote incorrect data.");
81        }
82    }
83
84    /**
85     * write(byte[] b) method testing. Tests that method writes correct values
86     * to the underlying output stream.
87     */
88    public void testWrite2() throws Exception {
89        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
90        TestOutputStream tos = new TestOutputStream();
91        CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
92        cos.write(data);
93        cos.flush();
94        byte[] result = tos.toByteArray();
95        if (!Arrays.equals(result, data)) {
96            fail("CipherOutputStream wrote incorrect data.");
97        }
98    }
99
100    /**
101     * write(byte[] b, int off, int len) method testing.
102     */
103    public void testWrite3() throws Exception {
104        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
105        TestOutputStream tos = new TestOutputStream();
106        CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
107        for (int i = 0; i < data.length; i++) {
108            cos.write(data, i, 1);
109        }
110        cos.flush();
111        byte[] result = tos.toByteArray();
112        if (!Arrays.equals(result, data)) {
113            fail("CipherOutputStream wrote incorrect data.");
114        }
115    }
116
117    /**
118     * @tests write(byte[] b, int off, int len)
119     */
120    public void testWrite4() throws Exception {
121	    //Regression for HARMONY-758
122    	try {
123    		new CipherOutputStream(new BufferedOutputStream((OutputStream) null), new NullCipher()).write(new byte[] {0}, 1, Integer.MAX_VALUE);
124    	} catch (IllegalArgumentException e) {
125    	}
126    }
127
128    /**
129     * @tests write(byte[] b, int off, int len)
130     */
131    public void testWrite5() throws Exception {
132	    //Regression for HARMONY-758
133        Cipher cf = Cipher.getInstance("DES/CBC/PKCS5Padding");
134        NullCipher nc = new NullCipher();
135        CipherOutputStream stream1 = new CipherOutputStream(new BufferedOutputStream((OutputStream) null), nc);
136        CipherOutputStream stream2 = new CipherOutputStream(stream1, cf);
137        CipherOutputStream stream3 = new CipherOutputStream(stream2, nc);
138        stream3.write(new byte[] {0}, 0, 0);
139   		//no exception expected
140    }
141
142    /**
143     * flush() method testing. Tests that method flushes the data to the
144     * underlying output stream.
145     */
146    public void testFlush() throws Exception {
147        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
148        TestOutputStream tos = new TestOutputStream();
149        CipherOutputStream cos = new CipherOutputStream(tos);
150        cos.write(data);
151        cos.flush();
152        byte[] result = tos.toByteArray();
153        if (!Arrays.equals(result, data)) {
154            fail("CipherOutputStream did not flush the data.");
155        }
156    }
157
158    /**
159     * close() method testing. Tests that the method calls the close() method of
160     * the underlying input stream.
161     */
162    public void testClose() throws Exception {
163        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
164        TestOutputStream tos = new TestOutputStream();
165        CipherOutputStream cos = new CipherOutputStream(tos);
166        cos.write(data);
167        cos.close();
168        byte[] result = tos.toByteArray();
169        if (!Arrays.equals(result, data)) {
170            fail("CipherOutputStream did not flush the data.");
171        }
172        assertTrue("The close() method should call the close() method "
173                + "of its underlying output stream.", tos.wasClosed());
174    }
175}
176
177