001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.ipc; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.io.File; 025import java.io.FileOutputStream; 026import java.io.IOException; 027import java.nio.ByteBuffer; 028import java.nio.channels.FileChannel; 029import org.apache.hadoop.hbase.HBaseClassTestRule; 030import org.apache.hadoop.hbase.testclassification.RPCTests; 031import org.apache.hadoop.hbase.testclassification.SmallTests; 032import org.apache.hadoop.hbase.util.Bytes; 033import org.junit.After; 034import org.junit.Before; 035import org.junit.ClassRule; 036import org.junit.Test; 037import org.junit.experimental.categories.Category; 038 039import org.apache.hbase.thirdparty.com.google.common.base.Charsets; 040import org.apache.hbase.thirdparty.com.google.common.io.Files; 041 042@Category({ RPCTests.class, SmallTests.class }) 043public class TestBufferChain { 044 045 @ClassRule 046 public static final HBaseClassTestRule CLASS_RULE = 047 HBaseClassTestRule.forClass(TestBufferChain.class); 048 049 private File tmpFile; 050 051 private static final byte[][] HELLO_WORLD_CHUNKS = 052 new byte[][] { "hello".getBytes(Charsets.UTF_8), " ".getBytes(Charsets.UTF_8), 053 "world".getBytes(Charsets.UTF_8) }; 054 055 @Before 056 public void setup() throws IOException { 057 tmpFile = File.createTempFile("TestBufferChain", "txt"); 058 } 059 060 @After 061 public void teardown() { 062 tmpFile.delete(); 063 } 064 065 @Test 066 public void testGetBackBytesWePutIn() { 067 ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); 068 BufferChain chain = new BufferChain(bufs); 069 assertTrue(Bytes.equals(Bytes.toBytes("hello world"), chain.getBytes())); 070 } 071 072 @Test 073 public void testLimitOffset() throws IOException { 074 ByteBuffer[] bufs = new ByteBuffer[] { stringBuf("XXXhelloYYY", 3, 5), stringBuf(" ", 0, 1), 075 stringBuf("XXXXworldY", 4, 5) }; 076 BufferChain chain = new BufferChain(bufs); 077 writeAndVerify(chain, "hello world"); 078 assertNoRemaining(bufs); 079 } 080 081 private ByteBuffer stringBuf(String string, int position, int length) { 082 ByteBuffer buf = ByteBuffer.wrap(string.getBytes(Charsets.UTF_8)); 083 buf.position(position); 084 buf.limit(position + length); 085 assertTrue(buf.hasRemaining()); 086 return buf; 087 } 088 089 private void assertNoRemaining(ByteBuffer[] bufs) { 090 for (ByteBuffer buf : bufs) { 091 assertFalse(buf.hasRemaining()); 092 } 093 } 094 095 private ByteBuffer[] wrapArrays(byte[][] arrays) { 096 ByteBuffer[] ret = new ByteBuffer[arrays.length]; 097 for (int i = 0; i < arrays.length; i++) { 098 ret[i] = ByteBuffer.wrap(arrays[i]); 099 } 100 return ret; 101 } 102 103 private void writeAndVerify(BufferChain chain, String string) throws IOException { 104 FileOutputStream fos = new FileOutputStream(tmpFile); 105 FileChannel ch = fos.getChannel(); 106 try { 107 long remaining = string.length(); 108 while (chain.hasRemaining()) { 109 long n = chain.write(ch); 110 remaining -= n; 111 } 112 assertEquals(0, remaining); 113 } finally { 114 fos.close(); 115 } 116 assertFalse(chain.hasRemaining()); 117 assertEquals(string, Files.toString(tmpFile, Charsets.UTF_8)); 118 } 119}