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