1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hbase.client; 19 20 import java.io.IOException; 21 22 import org.apache.hadoop.conf.Configuration; 23 import org.apache.hadoop.hbase.HRegionInfo; 24 import org.apache.hadoop.hbase.HRegionLocation; 25 import org.apache.hadoop.hbase.ServerName; 26 import org.apache.hadoop.hbase.ZooKeeperConnectionException; 27 import org.apache.hadoop.hbase.client.HConnectionManager.HConnectionImplementation; 28 import org.apache.hadoop.hbase.client.HConnectionManager.HConnectionKey; 29 import org.apache.hadoop.hbase.ipc.HRegionInterface; 30 import org.mockito.Mockito; 31 32 /** 33 * {@link HConnection} testing utility. 34 */ 35 public class HConnectionTestingUtility { 36 /* 37 * Not part of {@link HBaseTestingUtility} because this class is not 38 * in same package as {@link HConnection}. Would have to reveal ugly 39 * {@link HConnectionManager} innards to HBaseTestingUtility to give it access. 40 */ 41 /** 42 * Get a Mocked {@link HConnection} that goes with the passed <code>conf</code> 43 * configuration instance. Minimally the mock will return 44 * <code>conf</conf> when {@link HConnection#getConfiguration()} is invoked. 45 * Be sure to shutdown the connection when done by calling 46 * {@link HConnectionManager#deleteConnection(Configuration, boolean)} else it 47 * will stick around; this is probably not what you want. 48 * @param conf configuration 49 * @return HConnection object for <code>conf</code> 50 * @throws ZooKeeperConnectionException 51 */ 52 public static HConnection getMockedConnection(final Configuration conf) 53 throws ZooKeeperConnectionException { 54 HConnectionKey connectionKey = new HConnectionKey(conf); 55 synchronized (HConnectionManager.HBASE_INSTANCES) { 56 HConnectionImplementation connection = 57 HConnectionManager.HBASE_INSTANCES.get(connectionKey); 58 if (connection == null) { 59 connection = Mockito.mock(HConnectionImplementation.class); 60 Mockito.when(connection.getConfiguration()).thenReturn(conf); 61 HConnectionManager.HBASE_INSTANCES.put(connectionKey, connection); 62 } 63 return connection; 64 } 65 } 66 67 /** 68 * Calls {@link #getMockedConnection(Configuration)} and then mocks a few 69 * more of the popular {@link HConnection} methods so they do 'normal' 70 * operation (see return doc below for list). Be sure to shutdown the 71 * connection when done by calling 72 * {@link HConnectionManager#deleteConnection(Configuration, boolean)} else it 73 * will stick around; this is probably not what you want. 74 * @param implementation An {@link HRegionInterface} instance; you'll likely 75 * want to pass a mocked HRS; can be null. 76 * 77 * @param conf Configuration to use 78 * @param implementation An HRegionInterface; can be null but is usually 79 * itself a mock. 80 * @param sn ServerName to include in the region location returned by this 81 * <code>implementation</code> 82 * @param hri HRegionInfo to include in the location returned when 83 * getRegionLocation is called on the mocked connection 84 * @return Mock up a connection that returns a {@link Configuration} when 85 * {@link HConnection#getConfiguration()} is called, a 'location' when 86 * {@link HConnection#getRegionLocation(byte[], byte[], boolean)} is called, 87 * and that returns the passed {@link HRegionInterface} instance when 88 * {@link HConnection#getHRegionConnection(String, int)} 89 * is called (Be sure call 90 * {@link HConnectionManager#deleteConnection(org.apache.hadoop.conf.Configuration, boolean)} 91 * when done with this mocked Connection. 92 * @throws IOException 93 */ 94 public static HConnection getMockedConnectionAndDecorate(final Configuration conf, 95 final HRegionInterface implementation, final ServerName sn, final HRegionInfo hri) 96 throws IOException { 97 HConnection c = HConnectionTestingUtility.getMockedConnection(conf); 98 Mockito.doNothing().when(c).close(); 99 // Make it so we return a particular location when asked. 100 final HRegionLocation loc = new HRegionLocation(hri, sn.getHostname(), sn.getPort()); 101 Mockito.when(c.getRegionLocation((byte[]) Mockito.any(), 102 (byte[]) Mockito.any(), Mockito.anyBoolean())). 103 thenReturn(loc); 104 Mockito.when(c.locateRegion((byte[]) Mockito.any(), (byte[]) Mockito.any())). 105 thenReturn(loc); 106 if (implementation != null) { 107 // If a call to getHRegionConnection, return this implementation. 108 Mockito.when(c.getHRegionConnection(Mockito.anyString(), Mockito.anyInt())). 109 thenReturn(implementation); 110 } 111 return c; 112 } 113 114 /** 115 * Get a Mockito spied-upon {@link HConnection} that goes with the passed 116 * <code>conf</code> configuration instance. 117 * Be sure to shutdown the connection when done by calling 118 * {@link HConnectionManager#deleteConnection(Configuration, boolean)} else it 119 * will stick around; this is probably not what you want. 120 * @param conf configuration 121 * @return HConnection object for <code>conf</code> 122 * @throws ZooKeeperConnectionException 123 * @see http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html#spy(T) 124 */ 125 public static HConnection getSpiedConnection(final Configuration conf) 126 throws ZooKeeperConnectionException { 127 HConnectionKey connectionKey = new HConnectionKey(conf); 128 synchronized (HConnectionManager.HBASE_INSTANCES) { 129 HConnectionImplementation connection = 130 HConnectionManager.HBASE_INSTANCES.get(connectionKey); 131 if (connection == null) { 132 connection = Mockito.spy(new HConnectionImplementation(conf, true)); 133 HConnectionManager.HBASE_INSTANCES.put(connectionKey, connection); 134 } 135 return connection; 136 } 137 } 138 139 /** 140 * @return Count of extant connection instances 141 */ 142 public static int getConnectionCount() { 143 synchronized (HConnectionManager.HBASE_INSTANCES) { 144 return HConnectionManager.HBASE_INSTANCES.size(); 145 } 146 } 147 }