View Javadoc

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.RegionLocations;
24  import org.apache.hadoop.hbase.TableName;
25  import org.apache.hadoop.hbase.HRegionInfo;
26  import org.apache.hadoop.hbase.HRegionLocation;
27  import org.apache.hadoop.hbase.ServerName;
28  import org.apache.hadoop.hbase.ZooKeeperConnectionException;
29  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
30  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
31  import org.apache.hadoop.hbase.client.ConnectionManager.HConnectionImplementation;
32  import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
33  import org.mockito.Mockito;
34  
35  /**
36   * {@link ClusterConnection} testing utility.
37   */
38  public class HConnectionTestingUtility {
39    /*
40     * Not part of {@link HBaseTestingUtility} because this class is not
41     * in same package as {@link HConnection}.  Would have to reveal ugly
42     * {@link HConnectionManager} innards to HBaseTestingUtility to give it access.
43     */
44    /**
45     * Get a Mocked {@link HConnection} that goes with the passed <code>conf</code>
46     * configuration instance.  Minimally the mock will return
47     * <code>conf</conf> when {@link ClusterConnection#getConfiguration()} is invoked.
48     * Be sure to shutdown the connection when done by calling
49     * {@link HConnectionManager#deleteConnection(Configuration)} else it
50     * will stick around; this is probably not what you want.
51     * @param conf configuration
52     * @return HConnection object for <code>conf</code>
53     * @throws ZooKeeperConnectionException
54     */
55    public static ClusterConnection getMockedConnection(final Configuration conf)
56    throws ZooKeeperConnectionException {
57      HConnectionKey connectionKey = new HConnectionKey(conf);
58      synchronized (ConnectionManager.CONNECTION_INSTANCES) {
59        HConnectionImplementation connection =
60            ConnectionManager.CONNECTION_INSTANCES.get(connectionKey);
61        if (connection == null) {
62          connection = Mockito.mock(HConnectionImplementation.class);
63          Mockito.when(connection.getConfiguration()).thenReturn(conf);
64          ConnectionManager.CONNECTION_INSTANCES.put(connectionKey, connection);
65        }
66        return connection;
67      }
68    }
69  
70    /**
71     * Calls {@link #getMockedConnection(Configuration)} and then mocks a few
72     * more of the popular {@link ClusterConnection} methods so they do 'normal'
73     * operation (see return doc below for list). Be sure to shutdown the
74     * connection when done by calling
75     * {@link HConnectionManager#deleteConnection(Configuration)} else it
76     * will stick around; this is probably not what you want.
77     *
78     * @param conf Configuration to use
79     * @param admin An AdminProtocol; can be null but is usually
80     * itself a mock.
81     * @param client A ClientProtocol; can be null but is usually
82     * itself a mock.
83     * @param sn ServerName to include in the region location returned by this
84     * <code>connection</code>
85     * @param hri HRegionInfo to include in the location returned when
86     * getRegionLocator is called on the mocked connection
87     * @return Mock up a connection that returns a {@link Configuration} when
88     * {@link ClusterConnection#getConfiguration()} is called, a 'location' when
89     * {@link ClusterConnection#getRegionLocation(org.apache.hadoop.hbase.TableName, byte[], boolean)}
90     * is called,
91     * and that returns the passed {@link AdminProtos.AdminService.BlockingInterface} instance when
92     * {@link ClusterConnection#getAdmin(ServerName)} is called, returns the passed
93     * {@link ClientProtos.ClientService.BlockingInterface} instance when
94     * {@link ClusterConnection#getClient(ServerName)} is called (Be sure to call
95     * {@link HConnectionManager#deleteConnection(Configuration)}
96     * when done with this mocked Connection.
97     * @throws IOException
98     */
99    public static ClusterConnection getMockedConnectionAndDecorate(final Configuration conf,
100       final AdminProtos.AdminService.BlockingInterface admin,
101       final ClientProtos.ClientService.BlockingInterface client,
102       final ServerName sn, final HRegionInfo hri)
103   throws IOException {
104     HConnectionImplementation c = Mockito.mock(HConnectionImplementation.class);
105     Mockito.when(c.getConfiguration()).thenReturn(conf);
106     ConnectionManager.CONNECTION_INSTANCES.put(new HConnectionKey(conf), c);
107     Mockito.doNothing().when(c).close();
108     // Make it so we return a particular location when asked.
109     final HRegionLocation loc = new HRegionLocation(hri, sn);
110     Mockito.when(c.getRegionLocation((TableName) Mockito.any(),
111         (byte[]) Mockito.any(), Mockito.anyBoolean())).
112       thenReturn(loc);
113     Mockito.when(c.locateRegion((TableName) Mockito.any(), (byte[]) Mockito.any())).
114       thenReturn(loc);
115     Mockito.when(c.locateRegion((TableName) Mockito.any(), (byte[]) Mockito.any(),
116         Mockito.anyBoolean(), Mockito.anyBoolean(),  Mockito.anyInt()))
117         .thenReturn(new RegionLocations(loc));
118     if (admin != null) {
119       // If a call to getAdmin, return this implementation.
120       Mockito.when(c.getAdmin(Mockito.any(ServerName.class))).
121         thenReturn(admin);
122     }
123     if (client != null) {
124       // If a call to getClient, return this client.
125       Mockito.when(c.getClient(Mockito.any(ServerName.class))).
126         thenReturn(client);
127     }
128     NonceGenerator ng = Mockito.mock(NonceGenerator.class);
129     Mockito.when(c.getNonceGenerator()).thenReturn(ng);
130     Mockito.when(c.getAsyncProcess()).thenReturn(
131       new AsyncProcess(c, conf, null, RpcRetryingCallerFactory.instantiate(conf), false,
132           RpcControllerFactory.instantiate(conf)));
133     Mockito.doNothing().when(c).incCount();
134     Mockito.doNothing().when(c).decCount();
135     Mockito.when(c.getNewRpcRetryingCallerFactory(conf)).thenReturn(
136         RpcRetryingCallerFactory.instantiate(conf,
137             RetryingCallerInterceptorFactory.NO_OP_INTERCEPTOR, null));
138     HTableInterface t = Mockito.mock(HTableInterface.class);
139     Mockito.when(c.getTable((TableName)Mockito.any())).thenReturn(t);
140     ResultScanner rs = Mockito.mock(ResultScanner.class);
141     Mockito.when(t.getScanner((Scan)Mockito.any())).thenReturn(rs);
142     return c;
143   }
144 
145   /**
146    * Get a Mockito spied-upon {@link ClusterConnection} that goes with the passed
147    * <code>conf</code> configuration instance.
148    * Be sure to shutdown the connection when done by calling
149    * {@link HConnectionManager#deleteConnection(Configuration)} else it
150    * will stick around; this is probably not what you want.
151    * @param conf configuration
152    * @return HConnection object for <code>conf</code>
153    * @throws ZooKeeperConnectionException
154    * @see @link
155    * {http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html#spy(T)}
156    */
157   public static ClusterConnection getSpiedConnection(final Configuration conf)
158   throws IOException {
159     HConnectionKey connectionKey = new HConnectionKey(conf);
160     synchronized (ConnectionManager.CONNECTION_INSTANCES) {
161       HConnectionImplementation connection =
162           ConnectionManager.CONNECTION_INSTANCES.get(connectionKey);
163       if (connection == null) {
164         connection = Mockito.spy(new HConnectionImplementation(conf, true));
165         ConnectionManager.CONNECTION_INSTANCES.put(connectionKey, connection);
166       }
167       return connection;
168     }
169   }
170 
171   public static ClusterConnection getSpiedClusterConnection(final Configuration conf)
172   throws IOException {
173     HConnectionKey connectionKey = new HConnectionKey(conf);
174     synchronized (ConnectionManager.CONNECTION_INSTANCES) {
175       HConnectionImplementation connection =
176           ConnectionManager.CONNECTION_INSTANCES.get(connectionKey);
177       if (connection == null) {
178         connection = Mockito.spy(new HConnectionImplementation(conf, true));
179         ConnectionManager.CONNECTION_INSTANCES.put(connectionKey, connection);
180       }
181       return connection;
182     }
183   }
184 
185   /**
186    * @return Count of extant connection instances
187    */
188   public static int getConnectionCount() {
189     synchronized (ConnectionManager.CONNECTION_INSTANCES) {
190       return ConnectionManager.CONNECTION_INSTANCES.size();
191     }
192   }
193 }