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 static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertTrue;
22  
23  import com.google.protobuf.ServiceException;
24  
25  import java.io.IOException;
26  
27  import org.apache.hadoop.hbase.HBaseTestingUtility;
28  import org.apache.hadoop.hbase.HRegionInfo;
29  import org.apache.hadoop.hbase.TableName;
30  import org.apache.hadoop.hbase.client.ConnectionManager.HConnectionImplementation;
31  import org.apache.hadoop.hbase.ipc.HBaseRpcController;
32  import org.apache.hadoop.hbase.ipc.HBaseRpcControllerImpl;
33  import org.apache.hadoop.hbase.protobuf.RequestConverter;
34  import org.apache.hadoop.hbase.protobuf.ResponseConverter;
35  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
36  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
37  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse;
38  import org.apache.hadoop.hbase.testclassification.MediumTests;
39  import org.apache.hadoop.hbase.testclassification.RegionServerTests;
40  import org.apache.hadoop.hbase.util.Bytes;
41  import org.junit.AfterClass;
42  import org.junit.BeforeClass;
43  import org.junit.Test;
44  import org.junit.experimental.categories.Category;
45  
46  /**
47   * Testcase to make sure that we do not close scanners if ScanRequest.numberOfRows is zero. See
48   * HBASE-18042 for more details.
49   */
50  @Category({ RegionServerTests.class, MediumTests.class })
51  public class TestScanWithoutFetchingData {
52  
53    private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
54  
55    private static final TableName TABLE_NAME = TableName.valueOf("test");
56  
57    private static final byte[] CF = Bytes.toBytes("cf");
58  
59    private static final byte[] CQ = Bytes.toBytes("cq");
60  
61    private static final int COUNT = 10;
62  
63    private static HRegionInfo HRI;
64  
65    private static ClientProtos.ClientService.BlockingInterface STUB;
66  
67    @BeforeClass
68    public static void setUp() throws Exception {
69      UTIL.startMiniCluster(1);
70      try (Table table = UTIL.createTable(TABLE_NAME, CF)) {
71        for (int i = 0; i < COUNT; i++) {
72          table.put(new Put(Bytes.toBytes(i)).addColumn(CF, CQ, Bytes.toBytes(i)));
73        }
74      }
75      HRI = UTIL.getHBaseAdmin().getTableRegions(TABLE_NAME).get(0);
76      STUB = ((HConnectionImplementation) UTIL.getConnection())
77          .getClient(UTIL.getHBaseCluster().getRegionServer(0).getServerName());
78    }
79  
80    @AfterClass
81    public static void tearDown() throws Exception {
82      UTIL.shutdownMiniCluster();
83    }
84  
85    private void assertResult(int row, Result result) {
86      assertEquals(row, Bytes.toInt(result.getRow()));
87      assertEquals(row, Bytes.toInt(result.getValue(CF, CQ)));
88    }
89  
90    @Test
91    public void test() throws ServiceException, IOException {
92      Scan scan = new Scan();
93      ScanRequest req = RequestConverter.buildScanRequest(HRI.getRegionName(), scan, 0, false);
94      HBaseRpcController hrc = new HBaseRpcControllerImpl();
95      ScanResponse resp = STUB.scan(hrc, req);
96      assertTrue(resp.getMoreResults());
97      assertTrue(resp.getMoreResultsInRegion());
98      assertEquals(0, ResponseConverter.getResults(hrc.cellScanner(), resp).length);
99      long scannerId = resp.getScannerId();
100     int nextCallSeq = 0;
101     // test normal next
102     for (int i = 0; i < COUNT / 2; i++) {
103       req = RequestConverter.buildScanRequest(scannerId, 1, false, nextCallSeq++, false, false, -1);
104       hrc.reset();
105       resp = STUB.scan(hrc, req);
106       assertTrue(resp.getMoreResults());
107       assertTrue(resp.getMoreResultsInRegion());
108       Result[] results = ResponseConverter.getResults(hrc.cellScanner(), resp);
109       assertEquals(1, results.length);
110       assertResult(i, results[0]);
111     }
112     // test zero next
113     req = RequestConverter.buildScanRequest(scannerId, 0, false, nextCallSeq++, false, false, -1);
114     hrc.reset();
115     resp = STUB.scan(hrc, req);
116     assertTrue(resp.getMoreResults());
117     assertTrue(resp.getMoreResultsInRegion());
118     assertEquals(0, ResponseConverter.getResults(hrc.cellScanner(), resp).length);
119     for (int i = COUNT / 2; i < COUNT; i++) {
120       req = RequestConverter.buildScanRequest(scannerId, 1, false, nextCallSeq++, false, false, -1);
121       hrc.reset();
122       resp = STUB.scan(hrc, req);
123       assertTrue(resp.getMoreResults());
124       assertEquals(i != COUNT - 1, resp.getMoreResultsInRegion());
125       Result[] results = ResponseConverter.getResults(hrc.cellScanner(), resp);
126       assertEquals(1, results.length);
127       assertResult(i, results[0]);
128     }
129     // close
130     req = RequestConverter.buildScanRequest(scannerId, 0, true, false);
131     resp = STUB.scan(null, req);
132   }
133 }