1 /*
2  * Copyright (C) 2013 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.hash;
16 
17 import static org.easymock.EasyMock.aryEq;
18 import static org.easymock.EasyMock.eq;
19 
20 import com.google.common.testing.NullPointerTester;
21 
22 import junit.framework.TestCase;
23 
24 import org.easymock.EasyMock;
25 
26 import java.io.ByteArrayInputStream;
27 import java.util.Arrays;
28 
29 /**
30  * Tests for {@link HashingInputStream}.
31  *
32  * @author Qian Huang
33  */
34 public class HashingInputStreamTest extends TestCase {
35   private Hasher hasher;
36   private HashFunction hashFunction;
37   private static final byte[] testBytes = new byte[] {'y', 'a', 'm', 's'};
38   private ByteArrayInputStream buffer;
39 
setUp()40   @Override protected void setUp() throws Exception {
41     super.setUp();
42     hasher = EasyMock.createMock(Hasher.class);
43     hashFunction = EasyMock.createMock(HashFunction.class);
44     buffer = new ByteArrayInputStream(testBytes);
45 
46     EasyMock.expect(hashFunction.newHasher()).andReturn(hasher).once();
47     EasyMock.replay(hashFunction);
48   }
49 
testRead_putSingleByte()50   public void testRead_putSingleByte() throws Exception {
51     EasyMock.expect(hasher.putByte((byte) 'y')).andReturn(hasher).once();
52     EasyMock.replay(hasher);
53     HashingInputStream in = new HashingInputStream(hashFunction, buffer);
54 
55     int b = in.read();
56     assertEquals('y', b);
57 
58     EasyMock.verify(hashFunction);
59     EasyMock.verify(hasher);
60   }
61 
testRead_putByteArray()62   public void testRead_putByteArray() throws Exception {
63     EasyMock.expect(hasher.putBytes(aryEq(testBytes), eq(0), eq(testBytes.length)))
64         .andReturn(hasher).once();
65     EasyMock.replay(hasher);
66     HashingInputStream in = new HashingInputStream(hashFunction, buffer);
67 
68     byte[] buf = new byte[4];
69     int numOfByteRead = in.read(buf, 0, buf.length);
70     assertEquals(4, numOfByteRead);
71     for (int i = 0; i < testBytes.length; i++) {
72       assertEquals(testBytes[i], buf[i]);
73     }
74 
75     EasyMock.verify(hashFunction);
76     EasyMock.verify(hasher);
77   }
78 
testRead_putByteArrayAtPos()79   public void testRead_putByteArrayAtPos() throws Exception {
80     EasyMock.expect(hasher.putBytes(aryEq(Arrays.copyOfRange(testBytes, 0, 3)), eq(0), eq(3)))
81         .andReturn(hasher).once();
82     EasyMock.replay(hasher);
83     HashingInputStream in = new HashingInputStream(hashFunction, buffer);
84 
85     byte[] buf = new byte[3];
86     int numOfByteRead = in.read(buf, 0, 3);
87     assertEquals(3, numOfByteRead);
88     for (int i = 0; i < numOfByteRead; i++) {
89       assertEquals(testBytes[i], buf[i]);
90     }
91 
92     EasyMock.verify(hashFunction);
93     EasyMock.verify(hasher);
94   }
95 
testRead_putByteArrayOutOfBound()96   public void testRead_putByteArrayOutOfBound() throws Exception {
97     byte[] buf = new byte[100];
98     byte[] expectedBytes = buf.clone();
99     System.arraycopy(testBytes, 0, expectedBytes, 0, testBytes.length);
100 
101     EasyMock.expect(hasher.putBytes(aryEq(expectedBytes), eq(0), eq(4)))
102         .andReturn(hasher).once();
103     EasyMock.replay(hasher);
104     HashingInputStream in = new HashingInputStream(hashFunction, buffer);
105 
106     int numOfByteRead = in.read(buf, 0, 100);
107     assertEquals(4, numOfByteRead);
108     for (int i = 0; i < numOfByteRead; i++) {
109       assertEquals(testBytes[i], buf[i]);
110     }
111 
112     EasyMock.verify(hashFunction);
113     EasyMock.verify(hasher);
114   }
115 
testHash_hashesCorrectly()116   public void testHash_hashesCorrectly() throws Exception {
117     HashCode expectedHash = Hashing.md5().hashBytes(testBytes);
118     HashingInputStream in = new HashingInputStream(Hashing.md5(), buffer);
119 
120     byte[] buf = new byte[4];
121     int numOfByteRead = in.read(buf, 0, buf.length);
122     assertEquals(4, numOfByteRead);
123 
124     assertEquals(expectedHash, in.hash());
125   }
126 
testHash_hashesCorrectlyReadOutOfBound()127   public void testHash_hashesCorrectlyReadOutOfBound() throws Exception {
128     HashCode expectedHash = Hashing.md5().hashBytes(testBytes);
129     HashingInputStream in = new HashingInputStream(Hashing.md5(), buffer);
130 
131     byte[] buf = new byte[100];
132     int numOfByteRead = in.read(buf, 0, buf.length);
133     assertEquals(-1, in.read()); // additional read
134     assertEquals(4, numOfByteRead);
135 
136     assertEquals(expectedHash, in.hash());
137   }
138 
testHash_hashesCorrectlyForSkipping()139   public void testHash_hashesCorrectlyForSkipping() throws Exception {
140     HashCode expectedHash = Hashing.md5().hashBytes(new byte[] {'m', 's'});
141     HashingInputStream in = new HashingInputStream(Hashing.md5(), buffer);
142 
143     long numOfByteSkipped = in.skip(2);
144     assertEquals(2, numOfByteSkipped);
145 
146     byte[] buf = new byte[4];
147     int numOfByteRead = in.read(buf, 0, buf.length);
148     assertEquals(2, numOfByteRead);
149 
150     assertEquals(expectedHash, in.hash());
151   }
152 
testChecksForNull()153   public void testChecksForNull() throws Exception {
154     NullPointerTester tester = new NullPointerTester();
155 
156     tester.testAllPublicInstanceMethods(new HashingInputStream(Hashing.md5(), buffer));
157     tester.testAllPublicStaticMethods(HashingInputStream.class);
158     tester.testAllPublicConstructors(HashingInputStream.class);
159   }
160 }
161