/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.internal.serialization.impl; import com.hazelcast.internal.serialization.InternalSerializationService; import com.hazelcast.nio.serialization.Data; import com.hazelcast.test.annotation.ParallelTest; import com.hazelcast.test.annotation.QuickTest; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.lang.reflect.Field; import java.nio.ByteOrder; import java.util.Arrays; import java.util.Random; import static java.nio.ByteOrder.BIG_ENDIAN; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.spy; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) @PrepareForTest({ObjectDataInputStream.class}) @Category({QuickTest.class, ParallelTest.class}) public class ObjectDataInputStreamFinalMethodsTest { static final byte[] INIT_DATA = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; private InternalSerializationService mockSerializationService; private ObjectDataInputStream in; private DataInputStream dataInputSpy; private InitableByteArrayInputStream inputStream; private ByteOrder byteOrder; @Before public void before() throws Exception { byteOrder = BIG_ENDIAN; mockSerializationService = mock(InternalSerializationService.class); when(mockSerializationService.getByteOrder()).thenReturn(byteOrder); inputStream = new InitableByteArrayInputStream(INIT_DATA); in = new ObjectDataInputStream(inputStream, mockSerializationService); Field field = ObjectDataInputStream.class.getDeclaredField("dataInput"); field.setAccessible(true); DataInputStream dataInput = (DataInputStream) field.get(in); dataInputSpy = spy(dataInput); field.set(in, dataInputSpy); } @Test public void testRead() throws Exception { in.read(); verify(dataInputSpy).readByte(); } @Test public void testReadB() throws Exception { byte[] someInput = new byte[0]; in.read(someInput); verify(dataInputSpy).read(someInput); } @Test public void testReadForBOffLen() throws Exception { byte[] someInput = new byte[1]; in.read(someInput, 0, 1); verify(dataInputSpy).read(someInput, 0, 1); } @Test public void testReadFullyB() throws Exception { byte[] someInput = new byte[1]; in.readFully(someInput); verify(dataInputSpy).readFully(someInput); } @Test public void testReadFullyForBOffLen() throws Exception { byte[] someInput = new byte[1]; in.readFully(someInput, 0, 1); verify(dataInputSpy).readFully(someInput, 0, 1); } @Test public void testSkipBytes() throws Exception { int someInput = new Random().nextInt(); in.skipBytes(someInput); verify(dataInputSpy).skipBytes(someInput); } @Test public void testReadBoolean() throws Exception { in.readBoolean(); verify(dataInputSpy).readBoolean(); } @Test public void testReadByte() throws Exception { in.readByte(); verify(dataInputSpy).readByte(); } @Test public void testReadUnsignedByte() throws Exception { in.readUnsignedByte(); verify(dataInputSpy).readUnsignedByte(); } @Test public void testReadUnsignedShort() throws Exception { in.readUnsignedShort(); verify(dataInputSpy).readUnsignedShort(); } @Test public void testReadByteArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 1, 9, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, (byte) 1, 9, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(10); byte[] theNullArray = in.readByteArray(); inputStream.position(0); byte[] theZeroLenghtArray = in.readByteArray(); inputStream.position(4); byte[] bytes = in.readByteArray(); assertNull(theNullArray); assertArrayEquals(new byte[0], theZeroLenghtArray); assertArrayEquals(new byte[]{1}, bytes); } @Test public void testReadBooleanArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 1, 9, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 9, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(10); boolean[] theNullArray = in.readBooleanArray(); inputStream.position(0); boolean[] theZeroLenghtArray = in.readBooleanArray(); inputStream.position(4); boolean[] booleanArray = in.readBooleanArray(); assertNull(theNullArray); assertArrayEquals(new boolean[0], theZeroLenghtArray); assertTrue(Arrays.equals(new boolean[]{true}, booleanArray)); } @Test public void testReadCharArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(10); char[] theNullArray = in.readCharArray(); inputStream.position(0); char[] theZeroLenghtArray = in.readCharArray(); inputStream.position(4); char[] booleanArray = in.readCharArray(); assertNull(theNullArray); assertArrayEquals(new char[0], theZeroLenghtArray); assertArrayEquals(new char[]{1}, booleanArray); } @Test public void testReadIntArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(12); int[] theNullArray = in.readIntArray(); inputStream.position(0); int[] theZeroLenghtArray = in.readIntArray(); inputStream.position(4); int[] bytes = in.readIntArray(); assertNull(theNullArray); assertArrayEquals(new int[0], theZeroLenghtArray); assertArrayEquals(new int[]{1}, bytes); } @Test public void testReadLongArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(bytesLE.length - 4); long[] theNullArray = in.readLongArray(); inputStream.position(0); long[] theZeroLenghtArray = in.readLongArray(); inputStream.position(4); long[] bytes = in.readLongArray(); assertNull(theNullArray); assertArrayEquals(new long[0], theZeroLenghtArray); assertArrayEquals(new long[]{1}, bytes); } @Test public void testReadDoubleArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(bytesLE.length - 4); double[] theNullArray = in.readDoubleArray(); inputStream.position(0); double[] theZeroLenghtArray = in.readDoubleArray(); inputStream.position(4); double[] doubles = in.readDoubleArray(); assertNull(theNullArray); assertArrayEquals(new double[0], theZeroLenghtArray, 0); assertArrayEquals(new double[]{Double.longBitsToDouble(1)}, doubles, 0); } @Test public void testReadFloatArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(bytesLE.length - 4); float[] theNullArray = in.readFloatArray(); inputStream.position(0); float[] theZeroLenghtArray = in.readFloatArray(); inputStream.position(4); float[] floats = in.readFloatArray(); assertNull(theNullArray); assertArrayEquals(new float[0], theZeroLenghtArray, 0); assertArrayEquals(new float[]{Float.intBitsToFloat(1)}, floats, 0); } @Test public void testReadShortArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(bytesLE.length - 4); short[] theNullArray = in.readShortArray(); inputStream.position(0); short[] theZeroLenghtArray = in.readShortArray(); inputStream.position(4); short[] booleanArray = in.readShortArray(); assertNull(theNullArray); assertArrayEquals(new short[0], theZeroLenghtArray); assertArrayEquals(new short[]{1}, booleanArray); } @Test public void testReadUTFArray() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 32, 9, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 32, 9, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(bytesLE.length - 4); String[] theNullArray = in.readUTFArray(); inputStream.position(0); String[] theZeroLenghtArray = in.readUTFArray(); inputStream.position(4); String[] bytes = in.readUTFArray(); assertNull(theNullArray); assertArrayEquals(new String[0], theZeroLenghtArray); assertArrayEquals(new String[]{" "}, bytes); } @Test public void testReadLine() throws Exception { in.readLine(); verify(dataInputSpy).readLine(); } @Test public void testReadObject() throws Exception { in.readObject(); verify(mockSerializationService).readObject(in); } @Test public void testReadData() throws Exception { byte[] bytesBE = {0, 0, 0, 0, 0, 0, 0, 8, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, -1, -1, -1, -1}; byte[] bytesLE = {0, 0, 0, 0, 8, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, -1, -1, -1, -1}; inputStream.init((byteOrder == BIG_ENDIAN ? bytesBE : bytesLE), 0); inputStream.position(bytesLE.length - 4); Data nullData = in.readData(); inputStream.position(0); Data theZeroLenghtArray = in.readData(); inputStream.position(4); Data data = in.readData(); assertNull(nullData); assertEquals(0, theZeroLenghtArray.getType()); assertArrayEquals(new byte[0], theZeroLenghtArray.toByteArray()); assertArrayEquals(new byte[]{-1, -1, -1, -1, 0, 0, 0, 0}, data.toByteArray()); } @Test public void testGetClassLoader() throws Exception { in.getClassLoader(); verify(mockSerializationService).getClassLoader(); } @Test public void testGetByteOrder() throws Exception { ByteOrder byteOrderActual = in.getByteOrder(); assertEquals(byteOrder, byteOrderActual); } private class InitableByteArrayInputStream extends ByteArrayInputStream { public InitableByteArrayInputStream(byte[] buf) { super(buf); } public void init(byte[] buf, int offset) { this.buf = buf; this.count = buf != null ? buf.length : 0; this.pos = offset; } public final void position(int newPos) { if ((newPos > count) || (newPos < 0)) { throw new IllegalArgumentException(); } pos = newPos; if (mark > pos) { mark = -1; } } } }