001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertNull; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023import static org.junit.jupiter.api.Assertions.fail; 024 025import java.io.IOException; 026import java.util.Arrays; 027import java.util.Set; 028import org.apache.commons.lang3.builder.EqualsBuilder; 029import org.apache.hadoop.hbase.HConstants; 030import org.apache.hadoop.hbase.client.Scan.ReadType; 031import org.apache.hadoop.hbase.filter.FilterList; 032import org.apache.hadoop.hbase.security.access.Permission; 033import org.apache.hadoop.hbase.security.visibility.Authorizations; 034import org.apache.hadoop.hbase.testclassification.ClientTests; 035import org.apache.hadoop.hbase.testclassification.SmallTests; 036import org.apache.hadoop.hbase.util.Bytes; 037import org.junit.jupiter.api.Tag; 038import org.junit.jupiter.api.Test; 039 040import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 041import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 042 043// TODO: cover more test cases 044@Tag(ClientTests.TAG) 045@Tag(SmallTests.TAG) 046public class TestScan { 047 048 @Test 049 public void testAttributesSerialization() throws IOException { 050 Scan scan = new Scan(); 051 scan.setAttribute("attribute1", Bytes.toBytes("value1")); 052 scan.setAttribute("attribute2", Bytes.toBytes("value2")); 053 scan.setAttribute("attribute3", Bytes.toBytes("value3")); 054 055 ClientProtos.Scan scanProto = ProtobufUtil.toScan(scan); 056 057 Scan scan2 = ProtobufUtil.toScan(scanProto); 058 059 assertNull(scan2.getAttribute("absent")); 060 assertTrue(Arrays.equals(Bytes.toBytes("value1"), scan2.getAttribute("attribute1"))); 061 assertTrue(Arrays.equals(Bytes.toBytes("value2"), scan2.getAttribute("attribute2"))); 062 assertTrue(Arrays.equals(Bytes.toBytes("value3"), scan2.getAttribute("attribute3"))); 063 assertEquals(3, scan2.getAttributesMap().size()); 064 } 065 066 @Test 067 public void testGetToScan() throws Exception { 068 Get get = new Get(Bytes.toBytes(1)); 069 get.setCacheBlocks(true).setConsistency(Consistency.TIMELINE).setFilter(new FilterList()) 070 .setId("get").setIsolationLevel(IsolationLevel.READ_COMMITTED) 071 .setLoadColumnFamiliesOnDemand(false).setMaxResultsPerColumnFamily(1000).readVersions(9999) 072 .setRowOffsetPerColumnFamily(5).setTimeRange(0, 13) 073 .setAttribute("att_v0", Bytes.toBytes("att_v0")) 074 .setColumnFamilyTimeRange(Bytes.toBytes("cf"), 0, 123).setReplicaId(3) 075 .setACL("test_user", new Permission(Permission.Action.READ)) 076 .setAuthorizations(new Authorizations("test_label")).setQueryMetricsEnabled(true) 077 .setPriority(3); 078 079 Scan scan = new Scan(get); 080 assertEquals(get.getCacheBlocks(), scan.getCacheBlocks()); 081 assertEquals(get.getConsistency(), scan.getConsistency()); 082 assertEquals(get.getFilter(), scan.getFilter()); 083 assertEquals(get.getId(), scan.getId()); 084 assertEquals(get.getIsolationLevel(), scan.getIsolationLevel()); 085 assertEquals(get.getLoadColumnFamiliesOnDemandValue(), 086 scan.getLoadColumnFamiliesOnDemandValue()); 087 assertEquals(get.getMaxResultsPerColumnFamily(), scan.getMaxResultsPerColumnFamily()); 088 assertEquals(get.getMaxVersions(), scan.getMaxVersions()); 089 assertEquals(get.getRowOffsetPerColumnFamily(), scan.getRowOffsetPerColumnFamily()); 090 assertEquals(get.getTimeRange().getMin(), scan.getTimeRange().getMin()); 091 assertEquals(get.getTimeRange().getMax(), scan.getTimeRange().getMax()); 092 assertTrue(Bytes.equals(get.getAttribute("att_v0"), scan.getAttribute("att_v0"))); 093 assertEquals(get.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMin(), 094 scan.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMin()); 095 assertEquals(get.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMax(), 096 scan.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMax()); 097 assertEquals(get.getReplicaId(), scan.getReplicaId()); 098 assertEquals(get.getACL(), scan.getACL()); 099 assertEquals(get.getAuthorizations().getLabels(), scan.getAuthorizations().getLabels()); 100 assertEquals(get.getPriority(), scan.getPriority()); 101 assertEquals(get.isQueryMetricsEnabled(), scan.isQueryMetricsEnabled()); 102 } 103 104 @Test 105 public void testScanAttributes() { 106 Scan scan = new Scan(); 107 assertTrue(scan.getAttributesMap().isEmpty()); 108 assertNull(scan.getAttribute("absent")); 109 110 scan.setAttribute("absent", null); 111 assertTrue(scan.getAttributesMap().isEmpty()); 112 assertNull(scan.getAttribute("absent")); 113 114 // adding attribute 115 scan.setAttribute("attribute1", Bytes.toBytes("value1")); 116 assertTrue(Arrays.equals(Bytes.toBytes("value1"), scan.getAttribute("attribute1"))); 117 assertEquals(1, scan.getAttributesMap().size()); 118 assertTrue(Arrays.equals(Bytes.toBytes("value1"), scan.getAttributesMap().get("attribute1"))); 119 120 // overriding attribute value 121 scan.setAttribute("attribute1", Bytes.toBytes("value12")); 122 assertTrue(Arrays.equals(Bytes.toBytes("value12"), scan.getAttribute("attribute1"))); 123 assertEquals(1, scan.getAttributesMap().size()); 124 assertTrue(Arrays.equals(Bytes.toBytes("value12"), scan.getAttributesMap().get("attribute1"))); 125 126 // adding another attribute 127 scan.setAttribute("attribute2", Bytes.toBytes("value2")); 128 assertTrue(Arrays.equals(Bytes.toBytes("value2"), scan.getAttribute("attribute2"))); 129 assertEquals(2, scan.getAttributesMap().size()); 130 assertTrue(Arrays.equals(Bytes.toBytes("value2"), scan.getAttributesMap().get("attribute2"))); 131 132 // removing attribute 133 scan.setAttribute("attribute2", null); 134 assertNull(scan.getAttribute("attribute2")); 135 assertEquals(1, scan.getAttributesMap().size()); 136 assertNull(scan.getAttributesMap().get("attribute2")); 137 138 // removing non-existed attribute 139 scan.setAttribute("attribute2", null); 140 assertNull(scan.getAttribute("attribute2")); 141 assertEquals(1, scan.getAttributesMap().size()); 142 assertNull(scan.getAttributesMap().get("attribute2")); 143 144 // removing another attribute 145 scan.setAttribute("attribute1", null); 146 assertNull(scan.getAttribute("attribute1")); 147 assertTrue(scan.getAttributesMap().isEmpty()); 148 assertNull(scan.getAttributesMap().get("attribute1")); 149 } 150 151 @Test 152 public void testNullQualifier() { 153 Scan scan = new Scan(); 154 byte[] family = Bytes.toBytes("family"); 155 scan.addColumn(family, null); 156 Set<byte[]> qualifiers = scan.getFamilyMap().get(family); 157 assertEquals(1, qualifiers.size()); 158 } 159 160 @Test 161 public void testSetAuthorizations() { 162 Scan scan = new Scan(); 163 scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a")); 164 scan.setAuthorizations(new Authorizations("A|B")); 165 scan.setAuthorizations(new Authorizations("A&B")); 166 scan.setAuthorizations(new Authorizations("!B")); 167 scan.setAuthorizations(new Authorizations("A", "(A)")); 168 scan.setAuthorizations(new Authorizations("A", "{A")); 169 scan.setAuthorizations(new Authorizations(" ")); 170 scan.setAuthorizations(new Authorizations(":B")); 171 scan.setAuthorizations(new Authorizations("-B")); 172 scan.setAuthorizations(new Authorizations(".B")); 173 scan.setAuthorizations(new Authorizations("/B")); 174 } 175 176 @Test 177 public void testSetStartRowAndSetStopRow() { 178 Scan scan = new Scan(); 179 scan.withStartRow(null); 180 scan.withStartRow(new byte[1]); 181 scan.withStartRow(new byte[HConstants.MAX_ROW_LENGTH]); 182 try { 183 scan.withStartRow(new byte[HConstants.MAX_ROW_LENGTH + 1]); 184 fail("should've thrown exception"); 185 } catch (IllegalArgumentException iae) { 186 // Expected 187 } 188 189 scan.withStopRow(null); 190 scan.withStopRow(new byte[1]); 191 scan.withStopRow(new byte[HConstants.MAX_ROW_LENGTH]); 192 try { 193 scan.withStopRow(new byte[HConstants.MAX_ROW_LENGTH + 1]); 194 fail("should've thrown exception"); 195 } catch (IllegalArgumentException iae) { 196 // Expected 197 } 198 } 199 200 @Test 201 public void testScanCopyConstructor() throws Exception { 202 Scan scan = new Scan(); 203 204 scan.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("q")) 205 .setACL("test_user", new Permission(Permission.Action.READ)).setAllowPartialResults(true) 206 .setAsyncPrefetch(false).setAttribute("test_key", Bytes.toBytes("test_value")) 207 .setAuthorizations(new Authorizations("test_label")).setBatch(10).setCacheBlocks(false) 208 .setCaching(10).setConsistency(Consistency.TIMELINE).setFilter(new FilterList()) 209 .setId("scan_copy_constructor").setIsolationLevel(IsolationLevel.READ_COMMITTED).setLimit(100) 210 .setLoadColumnFamiliesOnDemand(false).setMaxResultSize(100).setMaxResultsPerColumnFamily(1000) 211 .readVersions(9999).setMvccReadPoint(5).setNeedCursorResult(true).setPriority(1).setRaw(true) 212 .setReplicaId(3).setReversed(true).setRowOffsetPerColumnFamily(5) 213 .setStartStopRowForPrefixScan(Bytes.toBytes("row_")).setScanMetricsEnabled(true) 214 .setReadType(ReadType.STREAM).withStartRow(Bytes.toBytes("row_1")) 215 .withStopRow(Bytes.toBytes("row_2")).setTimeRange(0, 13).setQueryMetricsEnabled(true); 216 217 // create a copy of existing scan object 218 Scan scanCopy = new Scan(scan); 219 220 // validate fields of copied scan object match with the original scan object 221 assertEquals(scan.getACL(), scanCopy.getACL()); 222 assertEquals(scan.getAllowPartialResults(), scanCopy.getAllowPartialResults()); 223 assertEquals(scan.getAttribute("test_key"), scanCopy.getAttribute("test_key")); 224 assertEquals(scan.getAttributeSize(), scanCopy.getAttributeSize()); 225 assertEquals(scan.getAttributesMap(), scanCopy.getAttributesMap()); 226 assertEquals(scan.getAuthorizations().getLabels(), scanCopy.getAuthorizations().getLabels()); 227 assertEquals(scan.getBatch(), scanCopy.getBatch()); 228 assertEquals(scan.getCacheBlocks(), scanCopy.getCacheBlocks()); 229 assertEquals(scan.getCaching(), scanCopy.getCaching()); 230 assertEquals(scan.getConsistency(), scanCopy.getConsistency()); 231 assertEquals(scan.getFamilies().length, scanCopy.getFamilies().length); 232 assertEquals(scan.getFamilies()[0], scanCopy.getFamilies()[0]); 233 assertEquals(scan.getFamilyMap(), scanCopy.getFamilyMap()); 234 assertEquals(scan.getFilter(), scanCopy.getFilter()); 235 assertEquals(scan.getId(), scanCopy.getId()); 236 assertEquals(scan.getIsolationLevel(), scanCopy.getIsolationLevel()); 237 assertEquals(scan.getLimit(), scanCopy.getLimit()); 238 assertEquals(scan.getLoadColumnFamiliesOnDemandValue(), 239 scanCopy.getLoadColumnFamiliesOnDemandValue()); 240 assertEquals(scan.getMaxResultSize(), scanCopy.getMaxResultSize()); 241 assertEquals(scan.getMaxResultsPerColumnFamily(), scanCopy.getMaxResultsPerColumnFamily()); 242 assertEquals(scan.getMaxVersions(), scanCopy.getMaxVersions()); 243 assertEquals(scan.getMvccReadPoint(), scanCopy.getMvccReadPoint()); 244 assertEquals(scan.getPriority(), scanCopy.getPriority()); 245 assertEquals(scan.getReadType(), scanCopy.getReadType()); 246 assertEquals(scan.getReplicaId(), scanCopy.getReplicaId()); 247 assertEquals(scan.getRowOffsetPerColumnFamily(), scanCopy.getRowOffsetPerColumnFamily()); 248 assertEquals(scan.getStartRow(), scanCopy.getStartRow()); 249 assertEquals(scan.getStopRow(), scanCopy.getStopRow()); 250 assertEquals(scan.getTimeRange(), scanCopy.getTimeRange()); 251 assertEquals(scan.isQueryMetricsEnabled(), scanCopy.isQueryMetricsEnabled()); 252 253 assertTrue(EqualsBuilder.reflectionEquals(scan, scanCopy), 254 "Make sure copy constructor adds all the fields in the copied object"); 255 } 256 257 @Test 258 public void testScanReadType() throws Exception { 259 Scan scan = new Scan(); 260 assertEquals(ReadType.DEFAULT, scan.getReadType()); 261 Scan copyScan = new Scan(scan); 262 assertEquals(ReadType.DEFAULT, copyScan.getReadType()); 263 } 264}