Skip to content

Commit b8737d4

Browse files
wchevreuilApache9
authored andcommitted
HBASE-23238 Additional test and checks for null references on ScannerCallableWithReplicas (apache#780)
Signed-off-by: Sean Busbey <busbey@apache.org> (cherry picked from commit 577db5d)
1 parent 471a6e5 commit b8737d4

2 files changed

Lines changed: 87 additions & 4 deletions

File tree

hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ public ScannerCallableWithReplicas(TableName tableName, ClusterConnection cConne
9494
}
9595

9696
public void setClose() {
97-
currentScannerCallable.setClose();
97+
if(currentScannerCallable != null) {
98+
currentScannerCallable.setClose();
99+
} else {
100+
LOG.warn("Calling close on ScannerCallable reference that is already null, "
101+
+ "which shouldn't happen.");
102+
}
98103
}
99104

100105
public void setRenew(boolean val) {
@@ -136,6 +141,10 @@ public MoreResults moreResultsForScan() {
136141
Result[] r = currentScannerCallable.call(timeout);
137142
currentScannerCallable = null;
138143
return r;
144+
} else if(currentScannerCallable == null) {
145+
LOG.warn("Another call received, but our ScannerCallable is already null. "
146+
+ "This shouldn't happen, but there's not much to do, so logging and returning null.");
147+
return null;
139148
}
140149
// We need to do the following:
141150
//1. When a scan goes out to a certain replica (default or not), we need to

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestScannersFromClientSide.java

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
import org.apache.hadoop.hbase.HTestConst;
4747
import org.apache.hadoop.hbase.KeyValue;
4848
import org.apache.hadoop.hbase.MiniHBaseCluster;
49+
import org.apache.hadoop.hbase.exceptions.DeserializationException;
50+
import org.apache.hadoop.hbase.filter.FilterBase;
51+
import org.apache.hadoop.hbase.testclassification.MediumTests;
4952
import org.apache.hadoop.hbase.TableName;
5053
import org.apache.hadoop.hbase.TableNotFoundException;
5154
import org.apache.hadoop.hbase.filter.BinaryComparator;
@@ -54,7 +57,6 @@
5457
import org.apache.hadoop.hbase.filter.QualifierFilter;
5558
import org.apache.hadoop.hbase.regionserver.HRegionServer;
5659
import org.apache.hadoop.hbase.testclassification.ClientTests;
57-
import org.apache.hadoop.hbase.testclassification.MediumTests;
5860
import org.apache.hadoop.hbase.util.Bytes;
5961
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
6062
import org.junit.After;
@@ -946,7 +948,7 @@ public void testReverseScanWithFlush() throws Exception {
946948
final byte[] LARGE_VALUE = generateHugeValue(128 * 1024);
947949

948950
try (Table table = TEST_UTIL.createTable(tableName, FAMILY);
949-
Admin admin = TEST_UTIL.getAdmin()) {
951+
Admin admin = TEST_UTIL.getAdmin()) {
950952
List<Put> putList = new ArrayList<>();
951953
for (long i = 0; i < ROWS_TO_INSERT; i++) {
952954
Put put = new Put(Bytes.toBytes(i));
@@ -976,7 +978,79 @@ public void testReverseScanWithFlush() throws Exception {
976978
}
977979
}
978980
assertEquals("Expected " + ROWS_TO_INSERT + " rows in the table but it is " + count,
979-
ROWS_TO_INSERT, count);
981+
ROWS_TO_INSERT, count);
980982
}
981983
}
984+
985+
@Test
986+
public void testScannerWithPartialResults() throws Exception {
987+
TableName tableName = TableName.valueOf("testScannerWithPartialResults");
988+
try (Table table = TEST_UTIL.createMultiRegionTable(tableName,
989+
Bytes.toBytes("c"), 4)) {
990+
List<Put> puts = new ArrayList<>();
991+
byte[] largeArray = new byte[10000];
992+
Put put = new Put(Bytes.toBytes("aaaa0"));
993+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("1"), Bytes.toBytes("1"));
994+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("2"), Bytes.toBytes("2"));
995+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("3"), Bytes.toBytes("3"));
996+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("4"), Bytes.toBytes("4"));
997+
puts.add(put);
998+
put = new Put(Bytes.toBytes("aaaa1"));
999+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("1"), Bytes.toBytes("1"));
1000+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("2"), largeArray);
1001+
put.addColumn(Bytes.toBytes("c"), Bytes.toBytes("3"), largeArray);
1002+
puts.add(put);
1003+
table.put(puts);
1004+
Scan scan = new Scan();
1005+
scan.addFamily(Bytes.toBytes("c"));
1006+
scan.setAttribute(Scan.SCAN_ATTRIBUTES_TABLE_NAME, tableName.getName());
1007+
scan.setMaxResultSize(10001);
1008+
scan.setStopRow(Bytes.toBytes("bbbb"));
1009+
scan.setFilter(new LimitKVsReturnFilter());
1010+
ResultScanner rs = table.getScanner(scan);
1011+
Result result;
1012+
int expectedKvNumber = 6;
1013+
int returnedKvNumber = 0;
1014+
while((result = rs.next()) != null){
1015+
returnedKvNumber += result.listCells().size();
1016+
}
1017+
rs.close();
1018+
assertEquals(expectedKvNumber, returnedKvNumber);
1019+
}
1020+
}
1021+
1022+
public static class LimitKVsReturnFilter extends FilterBase {
1023+
1024+
private static int total = 0;
1025+
1026+
@Override
1027+
public ReturnCode filterCell(Cell v) throws IOException {
1028+
if(total>=6) {
1029+
total++;
1030+
return ReturnCode.SKIP;
1031+
}
1032+
total++;
1033+
return ReturnCode.INCLUDE;
1034+
}
1035+
1036+
@Override
1037+
public boolean filterAllRemaining() throws IOException {
1038+
if(total<7) {
1039+
return false;
1040+
}
1041+
total++;
1042+
return true;
1043+
}
1044+
1045+
@Override
1046+
public String toString() {
1047+
return this.getClass().getSimpleName();
1048+
}
1049+
1050+
public static LimitKVsReturnFilter parseFrom(final byte [] pbBytes)
1051+
throws DeserializationException {
1052+
return new LimitKVsReturnFilter();
1053+
}
1054+
}
1055+
9821056
}

0 commit comments

Comments
 (0)