/*
* Copyright (C) 2014 The Async HBase Authors. All rights reserved.
* This file is part of Async HBase.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the StumbleUpon nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.hbase.async;
import static org.junit.Assert.assertNotNull;
import java.util.concurrent.ConcurrentHashMap;
import org.hbase.async.HBaseRpc;
import org.hbase.async.generated.RPCPB;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.mockito.Mockito;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
import static org.mockito.Matchers.any;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.DefaultExceptionEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
import org.jboss.netty.handler.codec.replay.VoidEnum;
@RunWith(PowerMockRunner.class)
//"Classloader hell"... It's real. Tell PowerMock to ignore these classes
//because they fiddle with the class loader. We don't test them anyway.
@PowerMockIgnore({"javax.management.*", "javax.xml.*",
"ch.qos.*", "org.slf4j.*",
"com.sum.*", "org.xml.*"})
@PrepareForTest({ HBaseClient.class, RegionClient.class, Channels.class,
RPCPB.ResponseHeader.class, NotServingRegionException.class,
RegionInfo.class, RPCPB.ExceptionResponse.class, HBaseRpc.class })
public class TestRegionClient extends BaseTestRegionClient {
@Test
public void ctor() throws Exception {
assertNotNull(new RegionClient(hbase_client));
}
@Test (expected = NullPointerException.class)
public void ctorNullClient() throws Exception {
new RegionClient(null);
}
@Test
public void getClosestRowBefore() throws Exception {
final RegionClient rclient = new RegionClient(hbase_client);
rclient.getClosestRowBefore(region, TABLE, KEY, FAMILY);
verifyPrivate(rclient).invoke("sendRpc", rpc);
}
@Test
public void getRemoteAddressChanNotSet() throws Exception {
RegionClient rclient = new RegionClient(hbase_client);
assertNull(Whitebox.getInternalState(rclient, "chan"));
assertNull(rclient.getRemoteAddress());
}
@Test
public void getRemoteAddressChanSet() throws Exception {
RegionClient rclient = mock(RegionClient.class);
PowerMockito.field(RegionClient.class, "chan").set(rclient, chan);
PowerMockito.when(chan.getRemoteAddress().toString()).thenReturn("127.0.0.1");
PowerMockito.when(rclient.getRemoteAddress()).thenCallRealMethod();
assertNotNull(Whitebox.getInternalState(rclient, "chan"));
String addy = rclient.getRemoteAddress();
assertNotNull(addy);
assertEquals(addy, "127.0.0.1");
}
@Test
public void exceptionCaught() throws Exception {
PowerMockito.mockStatic(Channels.class);
when(chan.isOpen()).thenReturn(true);
final RegionClient rclient = PowerMockito.spy(new RegionClient(hbase_client));
PowerMockito.field(RegionClient.class, "chan").set(rclient, chan);
final ExceptionEvent event = new DefaultExceptionEvent(chan,
new RuntimeException("Boo!"));
rclient.exceptionCaught(null, event);
verifyPrivate(rclient, never()).invoke("cleanup", chan);
PowerMockito.verifyStatic();
Channels.close(chan);
}
@Test
public void exceptionCaughtChNotOpen() throws Exception {
PowerMockito.mockStatic(Channels.class);
final RegionClient rclient = PowerMockito.spy(new RegionClient(hbase_client));
PowerMockito.field(RegionClient.class, "chan").set(rclient, chan);
final ExceptionEvent event = new DefaultExceptionEvent(chan,
new RuntimeException("Boo!"));
rclient.exceptionCaught(null, event);
verifyPrivate(rclient, times(1)).invoke("cleanup", chan);
PowerMockito.verifyStatic(never());
Channels.close(chan);
}
@Test (expected = NullPointerException.class)
public void exceptionCaughtNullEvent() throws Exception {
final RegionClient rclient = new RegionClient(hbase_client);
rclient.exceptionCaught(null, null);
}
@Test (expected = NullPointerException.class)
public void exceptionCaughtNullChannel() throws Exception {
final RegionClient rclient = new RegionClient(hbase_client);
final ExceptionEvent event = new DefaultExceptionEvent(null,
new RuntimeException("Boo!"));
rclient.exceptionCaught(null, event);
}
@Test (expected = NullPointerException.class)
public void exceptionCaughtNullException() throws Exception {
final RegionClient rclient = new RegionClient(hbase_client);
final ExceptionEvent event = new DefaultExceptionEvent(chan, null);
rclient.exceptionCaught(null, event);
}
@Test
public void exceptionCaughtDifferentChannel() throws Exception {
PowerMockito.mockStatic(Channels.class);
when(chan.isOpen()).thenReturn(true);
// honey badger don't care; apparently we can call this with any old channel.
final Channel ch = mock(Channel.class, Mockito.RETURNS_DEEP_STUBS);
when(ch.isOpen()).thenReturn(true);
final RegionClient rclient = PowerMockito.spy(new RegionClient(hbase_client));
PowerMockito.field(RegionClient.class, "chan").set(rclient, chan);
final ExceptionEvent event = new DefaultExceptionEvent(ch,
new RuntimeException("Boo!"));
rclient.exceptionCaught(null, event);
verifyPrivate(rclient, never()).invoke("cleanup", ch);
PowerMockito.verifyStatic();
Channels.close(ch);
}
@Test
public void exceptionCaughtDifferentChannelNotOpen() throws Exception {
PowerMockito.mockStatic(Channels.class);
// honey badger don't care; apparently we can call this with any old channel.
final Channel ch = mock(Channel.class, Mockito.RETURNS_DEEP_STUBS);
final RegionClient rclient = PowerMockito.spy(new RegionClient(hbase_client));
PowerMockito.field(RegionClient.class, "chan").set(rclient, chan);
final ExceptionEvent event = new DefaultExceptionEvent(ch,
new RuntimeException("Boo!"));
rclient.exceptionCaught(null, event);
verifyPrivate(rclient, times(1)).invoke("cleanup", ch);
PowerMockito.verifyStatic(never());
Channels.close(ch);
}
@SuppressWarnings("rawtypes")
@Test
public void channelDisconnected() throws Exception {
RegionClient rclient = PowerMockito.spy(new RegionClient(hbase_client));
PowerMockito.field(RegionClient.class, "chan").set(rclient, chan);
when(cse.getChannel()).thenReturn(chan);
// Prevent/stub logic in super.method()
PowerMockito.doNothing().when((ReplayingDecoder)rclient)
.channelDisconnected(ctx, cse);
PowerMockito.doNothing().when(rclient, "cleanup", chan);
PowerMockito.when(rclient, "channelDisconnected", ctx, cse)
.thenCallRealMethod();
assertNotNull(Whitebox.getInternalState(rclient, "chan"));
rclient.channelDisconnected(ctx, cse);
assertNull(Whitebox.getInternalState(rclient, "chan"));
}
@Test
public void channelClosed() throws Exception {
RegionClient rclient = new RegionClient(hbase_client);
assertNotNull(rclient);
rclient.becomeReady(chan, SERVER_VERSION_UNKNOWN);
assertNotNull(Whitebox.getInternalState(rclient, "chan"));
rclient.channelClosed(ctx, cse);
assertNull(Whitebox.getInternalState(rclient, "chan"));
verifyPrivate(rclient).invoke("cleanup", mock(Channel.class));
}
@Test
public void channelConnectedCDH3b3() throws Exception {
RegionClient rclient = mock(RegionClient.class, Mockito.RETURNS_DEEP_STUBS);
ChannelBuffer header = mock(ChannelBuffer.class);
hbase_client.has_root = true;
when(cse.getChannel()).thenReturn(chan);
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("org.hbase.async.cdh3b3"))
.thenReturn("some value");
PowerMockito.doNothing().when(rclient, "helloRpc", chan, header);
PowerMockito.when(rclient, "headerCDH3b3").thenReturn(header);
PowerMockito.field(RegionClient.class, "hbase_client")
.set(rclient, hbase_client);
PowerMockito.when(rclient, "channelConnected", ctx, cse).thenCallRealMethod();
rclient.channelConnected(ctx, cse);
verifyPrivate(rclient).invoke("headerCDH3b3");
verifyPrivate(rclient).invoke("helloRpc", chan, header);
}
@Test
public void channelConnected090() throws Exception {
RegionClient rclient = mock(RegionClient.class, Mockito.RETURNS_DEEP_STUBS);
ChannelBuffer header = mock(ChannelBuffer.class);
hbase_client.has_root = true;
when(cse.getChannel()).thenReturn(chan);
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("org.hbase.async.cdh3b3"))
.thenReturn(null);
PowerMockito.doNothing().when(rclient, "helloRpc", chan, header);
PowerMockito.when(rclient, "header090").thenReturn(header);
PowerMockito.field(RegionClient.class, "hbase_client")
.set(rclient, hbase_client);
PowerMockito.when(rclient, "channelConnected", ctx, cse)
.thenCallRealMethod();
rclient.channelConnected(ctx, cse);
verifyPrivate(rclient).invoke("header090");
verifyPrivate(rclient).invoke("helloRpc", chan, header);
}
@Test (expected=NonRecoverableException.class)
public void decodeHbase95orAboveNoCallId() throws Exception {
RegionClient rclient = mock(RegionClient.class);
ChannelBuffer buf = mock(ChannelBuffer.class);
RPCPB.ResponseHeader header = mock(RPCPB.ResponseHeader.class);
PowerMockito.mockStatic(HBaseRpc.class);
@SuppressWarnings("unchecked")
ConcurrentHashMap<Integer, HBaseRpc> mcmap = mock(ConcurrentHashMap.class);
PowerMockito.field(RegionClient.class, "rpcs_inflight").set(rclient, mcmap);
PowerMockito.field(RegionClient.class, "server_version")
.set(rclient, RegionClient.SERVER_VERSION_095_OR_ABOVE);
PowerMockito.when(HBaseRpc.readProtobuf(buf, RPCPB.ResponseHeader.PARSER))
.thenReturn(header);
PowerMockito.when(buf, "readInt").thenReturn(0);
PowerMockito.when(header, "hasCallId").thenReturn(false);
PowerMockito.when(rclient, "decode", (ChannelHandlerContext)any(),
(Channel)any(), (ChannelBuffer)any(), (VoidEnum)any())
.thenCallRealMethod();
assertNull(rclient.decode(null, chan, buf, (VoidEnum)null));
}
@Test
public void decodeHbase92orAboveRpcNotNull() throws Exception {
RegionClient rclient = mock(RegionClient.class);
ChannelBuffer buf = mock(ChannelBuffer.class);
NotServingRegionException blowzup = mock(NotServingRegionException.class);
HBaseRpc rpc = mock(HBaseRpc.class);
RegionInfo region = mock(RegionInfo.class);
ConcurrentHashMap<Integer, HBaseRpc> mcmap =
new ConcurrentHashMap<Integer, HBaseRpc>(1);
mcmap.put(0, rpc);
PowerMockito.field(RegionClient.class, "rpcs_inflight").set(rclient, mcmap);
PowerMockito.field(RegionClient.class, "hbase_client")
.set(rclient, hbase_client);
PowerMockito.field(RegionClient.class, "server_version")
.set(rclient, RegionClient.SERVER_VERSION_092_OR_ABOVE);
PowerMockito.when(buf, "readInt").thenReturn(0);
PowerMockito.when(rpc, "getRegion").thenReturn(region);
PowerMockito.when(region, "name").thenReturn(Bytes.fromInt(1337));
PowerMockito.doNothing().when(hbase_client, "handleNSRE", Mockito.any(),
Mockito.any(), Mockito.any());
PowerMockito.when(rclient, "deserialize", buf, rpc).thenReturn(blowzup);
PowerMockito.when(rclient, "decode", (ChannelHandlerContext)any(),
(Channel)any(), (ChannelBuffer)any(), (VoidEnum)any())
.thenCallRealMethod();
assertNull(rclient.decode(null, chan, buf, (VoidEnum)null));
}
@Test
public void encode() throws Exception {
// TODO
}
@Test
public void deserialize() throws Exception {
// TOD
}
@Test
public void numberOfKeyValuesAhead() throws Exception {
// TODO
}
@Test
public void parseResult() throws Exception {
// TODO
}
@Test
public void parseResults() throws Exception {
// TODO
}
@Test (expected=InvalidResponseException.class)
public void badResponse() throws Exception {
RegionClient rclient = new RegionClient(hbase_client);
Whitebox.invokeMethod(rclient, "badResponse", "ZOMG ERRMSG");
}
@Test
public void commonHeader() throws Exception {
RegionClient rclient = new RegionClient(hbase_client);
final byte[] buf = new byte[42];
ChannelBuffer commonHeader =
Whitebox.invokeMethod(rclient, "commonHeader", buf, HRPC3 );
assertNotNull(commonHeader);
}
@Test
public void header090() throws Exception {
RegionClient rclient = mock(RegionClient.class);
final byte[] buf = new byte[4 + 1 + 4 + 2 + 29 + 2 + 48 + 2 + 47];
final String klass = "org.apache.hadoop.io.Writable";
ChannelBuffer header = mock(ChannelBuffer.class);
PowerMockito.when(rclient, "commonHeader", buf, HRPC3).thenReturn(header);
PowerMockito.when(header, "writerIndex").thenReturn(0);
PowerMockito.when(rclient, "header090").thenCallRealMethod();
ChannelBuffer header090 = Whitebox.invokeMethod(rclient, "header090");
verifyPrivate(rclient, Mockito.atMost(1)).invoke("commonHeader", buf, HRPC3);
verifyPrivate(header, Mockito.atMost(2)).invoke("writerIndex");
verifyPrivate(header, Mockito.atLeast(1))
.invoke("writerIndex", Mockito.anyInt());
verifyPrivate(header, Mockito.atMost(3)).invoke("writeShort", klass.length());
verifyPrivate(header, Mockito.atMost(3))
.invoke("writeBytes", Bytes.ISO88591(klass));
verifyPrivate(header, Mockito.atMost(1))
.invoke("setInt", Mockito.eq(5), Mockito.anyInt());
assertNotNull(header090);
}
@Test
public void header092() throws Exception {
RegionClient rclient = mock(RegionClient.class);
final byte[] buf = new byte[4 + 1 + 4 + 1 + 44];
final String klass = "org.apache.hadoop.hbase.ipc.HRegionInterface";
ChannelBuffer header = mock(ChannelBuffer.class);
PowerMockito.when(rclient, "commonHeader", buf, HRPC3).thenReturn(header);
PowerMockito.when(header, "writerIndex").thenReturn(0);
PowerMockito.when(rclient, "header092").thenCallRealMethod();
ChannelBuffer header092 = Whitebox.invokeMethod(rclient, "header092");
verifyPrivate(rclient, Mockito.atMost(1)).invoke("commonHeader", buf, HRPC3);
verifyPrivate(header, Mockito.atMost(2)).invoke("writerIndex");
verifyPrivate(header, Mockito.atLeast(1))
.invoke("writerIndex", Mockito.anyInt());
verifyPrivate(header, Mockito.atMost(1)).invoke("writeByte", klass.length());
verifyPrivate(header, Mockito.atMost(1))
.invoke("writeBytes", Bytes.ISO88591(klass));
verifyPrivate(header, Mockito.atMost(1))
.invoke("setInt", Mockito.eq(5), Mockito.anyInt());
assertNotNull(header092);
}
@Test
public void headerCDH3b3() throws Exception {
RegionClient rclient = mock(RegionClient.class);
byte[] user = Bytes.UTF8("some value");
byte[] buf = new byte[4 + 1 + 4 + 4 + user.length];
ChannelBuffer header = mock(ChannelBuffer.class);
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("user.name", "asynchbase"))
.thenReturn("some value");
PowerMockito.when(rclient, "commonHeader", buf, HRPC3).thenReturn(header);
PowerMockito.when(rclient, "headerCDH3b3").thenCallRealMethod();
ChannelBuffer headerCDH3b3 = Whitebox.invokeMethod(rclient, "headerCDH3b3");
verifyPrivate(rclient, Mockito.atMost(1)).invoke("commonHeader", buf, HRPC3);
verifyPrivate(header, Mockito.atMost(2)).invoke("writeInt", Mockito.anyInt());
verifyPrivate(header, Mockito.atMost(1)).invoke("writeBytes", user);
assertNotNull(headerCDH3b3);
}
}