/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.imagepipeline.memory; import java.util.Arrays; import com.facebook.common.references.CloseableReference; import com.facebook.imagepipeline.testing.FakeNativeMemoryChunkPool; import com.facebook.testing.robolectric.v2.WithTestDefaultsRunner; import com.google.common.collect.ImmutableMap; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; /** * Tests for NativePooledByteBufferOutputStream */ @RunWith(WithTestDefaultsRunner.class) public class NativePooledByteBufferOutputStreamTest { private NativeMemoryChunkPool mPool; private byte[] mData; private PoolStats<byte[]> mStats; @Before public void setup() { mPool = new FakeNativeMemoryChunkPool(); mStats = new PoolStats(mPool); mData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; } // write out the contents of data into the output stream private NativePooledByteBuffer doWrite(NativePooledByteBufferOutputStream os, byte[] data) throws Exception { for (int i = 0; i < data.length; i++) { os.write(data, i, 1); } return os.toByteBuffer(); } // assert that the first 'length' bytes of expected are the same as those in 'actual' private void assertArrayEquals(byte[] expected, byte[] actual, int length) { Assert.assertTrue(expected.length >= length); Assert.assertTrue(actual.length >= length); for (int i = 0; i < length; i++) { Assert.assertEquals(expected[i], actual[i]); } } private byte[] getBytes(NativePooledByteBuffer bb) { byte[] bytes = new byte[bb.size()]; bb.mBufRef.get().read(0, bytes, 0, bytes.length); return bytes; } @Test public void testBasic_1() throws Exception { NativePooledByteBufferOutputStream os1 = new NativePooledByteBufferOutputStream(mPool); NativePooledByteBuffer sb1 = doWrite(os1, mData); Assert.assertEquals(16, sb1.mBufRef.get().getSize()); assertArrayEquals(mData, getBytes(sb1), mData.length); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(0, 0), 16, new IntPair(1, 0), 8, new IntPair(0, 1), 4, new IntPair(0, 1)), mStats.mBucketStats); } @Test public void testBasic_2() throws Exception { NativePooledByteBufferOutputStream os2 = new NativePooledByteBufferOutputStream(mPool, 8); NativePooledByteBuffer sb2 = doWrite(os2, mData); Assert.assertEquals(16, sb2.mBufRef.get().getSize()); assertArrayEquals(mData, getBytes(sb2), mData.length); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(0, 0), 16, new IntPair(1, 0), 8, new IntPair(0, 1), 4, new IntPair(0, 0)), mStats.mBucketStats); } @Test public void testBasic_3() throws Exception { NativePooledByteBufferOutputStream os3 = new NativePooledByteBufferOutputStream(mPool, 16); NativePooledByteBuffer sb3 = doWrite(os3, mData); Assert.assertEquals(16, sb3.mBufRef.get().getSize()); assertArrayEquals(mData, getBytes(sb3), mData.length); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(0, 0), 16, new IntPair(1, 0), 8, new IntPair(0, 0), 4, new IntPair(0, 0)), mStats.mBucketStats); } @Test public void testBasic_4() throws Exception { NativePooledByteBufferOutputStream os4 = new NativePooledByteBufferOutputStream(mPool, 32); NativePooledByteBuffer sb4 = doWrite(os4, mData); Assert.assertEquals(32, sb4.mBufRef.get().getSize()); assertArrayEquals(mData, getBytes(sb4), mData.length); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(1, 0), 16, new IntPair(0, 0), 8, new IntPair(0, 0), 4, new IntPair(0, 0)), mStats.mBucketStats); } @Test public void testClose() throws Exception { NativePooledByteBufferOutputStream os = new NativePooledByteBufferOutputStream(mPool); os.close(); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(0, 0), 16, new IntPair(0, 0), 8, new IntPair(0, 0), 4, new IntPair(0, 1)), mStats.mBucketStats); } @Test public void testToByteBufException() throws Exception { NativePooledByteBufferOutputStream os1 = new NativePooledByteBufferOutputStream(mPool); os1.close(); try { os1.toByteBuffer(); Assert.fail(); } catch (Exception e) { // do nothing } } @Test public void testWriteAfterToByteBuf() throws Exception { NativePooledByteBufferOutputStream os1 = new NativePooledByteBufferOutputStream(mPool); NativePooledByteBuffer buf1 = doWrite(os1, Arrays.copyOf(mData, 9)); NativePooledByteBuffer buf2 = doWrite(os1, Arrays.copyOf(mData, 3)); Assert.assertEquals(12, buf2.size()); final CloseableReference<NativeMemoryChunk> chunk = buf1.mBufRef; Assert.assertEquals(3, chunk.getUnderlyingReferenceTestOnly().getRefCountTestOnly()); os1.close(); buf1.close(); buf2.close(); Assert.assertEquals(0, chunk.getUnderlyingReferenceTestOnly().getRefCountTestOnly()); } }