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.Assert.assertEquals;
021import static org.junit.Assert.assertTrue;
022import static org.junit.Assert.fail;
023
024import java.io.IOException;
025import java.util.Arrays;
026import java.util.Set;
027
028import org.apache.commons.lang3.builder.EqualsBuilder;
029import org.apache.hadoop.hbase.HBaseClassTestRule;
030import org.apache.hadoop.hbase.HConstants;
031import org.apache.hadoop.hbase.client.Scan.ReadType;
032import org.apache.hadoop.hbase.filter.FilterList;
033import org.apache.hadoop.hbase.security.access.Permission;
034import org.apache.hadoop.hbase.security.visibility.Authorizations;
035import org.apache.hadoop.hbase.testclassification.ClientTests;
036import org.apache.hadoop.hbase.testclassification.SmallTests;
037import org.apache.hadoop.hbase.util.Bytes;
038import org.junit.Assert;
039import org.junit.ClassRule;
040import org.junit.Test;
041import org.junit.experimental.categories.Category;
042import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
043import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos;
044
045// TODO: cover more test cases
046@Category({ClientTests.class, SmallTests.class})
047public class TestScan {
048
049  @ClassRule
050  public static final HBaseClassTestRule CLASS_RULE =
051      HBaseClassTestRule.forClass(TestScan.class);
052
053  @Test
054  public void testAttributesSerialization() throws IOException {
055    Scan scan = new Scan();
056    scan.setAttribute("attribute1", Bytes.toBytes("value1"));
057    scan.setAttribute("attribute2", Bytes.toBytes("value2"));
058    scan.setAttribute("attribute3", Bytes.toBytes("value3"));
059
060    ClientProtos.Scan scanProto = ProtobufUtil.toScan(scan);
061
062    Scan scan2 = ProtobufUtil.toScan(scanProto);
063
064    Assert.assertNull(scan2.getAttribute("absent"));
065    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value1"), scan2.getAttribute("attribute1")));
066    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value2"), scan2.getAttribute("attribute2")));
067    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value3"), scan2.getAttribute("attribute3")));
068    Assert.assertEquals(3, scan2.getAttributesMap().size());
069  }
070
071  @Test
072  public void testGetToScan() throws Exception {
073    Get get = new Get(Bytes.toBytes(1));
074    get.setCacheBlocks(true)
075            .setConsistency(Consistency.TIMELINE)
076            .setFilter(new FilterList())
077            .setId("get")
078            .setIsolationLevel(IsolationLevel.READ_COMMITTED)
079            .setLoadColumnFamiliesOnDemand(false)
080            .setMaxResultsPerColumnFamily(1000)
081            .setMaxVersions(9999)
082            .setRowOffsetPerColumnFamily(5)
083            .setTimeRange(0, 13)
084            .setAttribute("att_v0", Bytes.toBytes("att_v0"))
085            .setColumnFamilyTimeRange(Bytes.toBytes("cf"), 0, 123)
086            .setReplicaId(3)
087            .setACL("test_user", new Permission(Permission.Action.READ))
088            .setAuthorizations(new Authorizations("test_label"))
089            .setPriority(3);
090
091    Scan scan = new Scan(get);
092    assertEquals(get.getCacheBlocks(), scan.getCacheBlocks());
093    assertEquals(get.getConsistency(), scan.getConsistency());
094    assertEquals(get.getFilter(), scan.getFilter());
095    assertEquals(get.getId(), scan.getId());
096    assertEquals(get.getIsolationLevel(), scan.getIsolationLevel());
097    assertEquals(get.getLoadColumnFamiliesOnDemandValue(), scan.getLoadColumnFamiliesOnDemandValue());
098    assertEquals(get.getMaxResultsPerColumnFamily(), scan.getMaxResultsPerColumnFamily());
099    assertEquals(get.getMaxVersions(), scan.getMaxVersions());
100    assertEquals(get.getRowOffsetPerColumnFamily(), scan.getRowOffsetPerColumnFamily());
101    assertEquals(get.getTimeRange().getMin(), scan.getTimeRange().getMin());
102    assertEquals(get.getTimeRange().getMax(), scan.getTimeRange().getMax());
103    assertTrue(Bytes.equals(get.getAttribute("att_v0"), scan.getAttribute("att_v0")));
104    assertEquals(get.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMin(),
105            scan.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMin());
106    assertEquals(get.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMax(),
107            scan.getColumnFamilyTimeRange().get(Bytes.toBytes("cf")).getMax());
108    assertEquals(get.getReplicaId(), scan.getReplicaId());
109    assertEquals(get.getACL(), scan.getACL());
110    assertEquals(get.getAuthorizations().getLabels(), scan.getAuthorizations().getLabels());
111    assertEquals(get.getPriority(), scan.getPriority());
112  }
113
114  @Test
115  public void testScanAttributes() {
116    Scan scan = new Scan();
117    Assert.assertTrue(scan.getAttributesMap().isEmpty());
118    Assert.assertNull(scan.getAttribute("absent"));
119
120    scan.setAttribute("absent", null);
121    Assert.assertTrue(scan.getAttributesMap().isEmpty());
122    Assert.assertNull(scan.getAttribute("absent"));
123
124    // adding attribute
125    scan.setAttribute("attribute1", Bytes.toBytes("value1"));
126    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value1"), scan.getAttribute("attribute1")));
127    Assert.assertEquals(1, scan.getAttributesMap().size());
128    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value1"), scan.getAttributesMap().get("attribute1")));
129
130    // overriding attribute value
131    scan.setAttribute("attribute1", Bytes.toBytes("value12"));
132    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value12"), scan.getAttribute("attribute1")));
133    Assert.assertEquals(1, scan.getAttributesMap().size());
134    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value12"), scan.getAttributesMap().get("attribute1")));
135
136    // adding another attribute
137    scan.setAttribute("attribute2", Bytes.toBytes("value2"));
138    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value2"), scan.getAttribute("attribute2")));
139    Assert.assertEquals(2, scan.getAttributesMap().size());
140    Assert.assertTrue(Arrays.equals(Bytes.toBytes("value2"), scan.getAttributesMap().get("attribute2")));
141
142    // removing attribute
143    scan.setAttribute("attribute2", null);
144    Assert.assertNull(scan.getAttribute("attribute2"));
145    Assert.assertEquals(1, scan.getAttributesMap().size());
146    Assert.assertNull(scan.getAttributesMap().get("attribute2"));
147
148    // removing non-existed attribute
149    scan.setAttribute("attribute2", null);
150    Assert.assertNull(scan.getAttribute("attribute2"));
151    Assert.assertEquals(1, scan.getAttributesMap().size());
152    Assert.assertNull(scan.getAttributesMap().get("attribute2"));
153
154    // removing another attribute
155    scan.setAttribute("attribute1", null);
156    Assert.assertNull(scan.getAttribute("attribute1"));
157    Assert.assertTrue(scan.getAttributesMap().isEmpty());
158    Assert.assertNull(scan.getAttributesMap().get("attribute1"));
159  }
160
161  @Test
162  public void testNullQualifier() {
163    Scan scan = new Scan();
164    byte[] family = Bytes.toBytes("family");
165    scan.addColumn(family, null);
166    Set<byte[]> qualifiers = scan.getFamilyMap().get(family);
167    Assert.assertEquals(1, qualifiers.size());
168  }
169
170  @Test
171  public void testSetAuthorizations() {
172    Scan scan = new Scan();
173    try {
174      scan.setAuthorizations(new Authorizations("\u002b|\u0029"));
175      scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a"));
176      scan.setAuthorizations(new Authorizations("A|B"));
177      scan.setAuthorizations(new Authorizations("A&B"));
178      scan.setAuthorizations(new Authorizations("!B"));
179      scan.setAuthorizations(new Authorizations("A", "(A)"));
180      scan.setAuthorizations(new Authorizations("A", "{A"));
181      scan.setAuthorizations(new Authorizations(" "));
182      scan.setAuthorizations(new Authorizations(":B"));
183      scan.setAuthorizations(new Authorizations("-B"));
184      scan.setAuthorizations(new Authorizations(".B"));
185      scan.setAuthorizations(new Authorizations("/B"));
186    } catch (IllegalArgumentException e) {
187      fail("should not throw exception");
188    }
189  }
190
191  @Test
192  public void testSetStartRowAndSetStopRow() {
193    Scan scan = new Scan();
194    scan.setStartRow(null);
195    scan.setStartRow(new byte[1]);
196    scan.setStartRow(new byte[HConstants.MAX_ROW_LENGTH]);
197    try {
198      scan.setStartRow(new byte[HConstants.MAX_ROW_LENGTH+1]);
199      fail("should've thrown exception");
200    } catch (IllegalArgumentException iae) {
201    } catch (Exception e) {
202      fail("expected IllegalArgumentException to be thrown");
203    }
204
205    scan.setStopRow(null);
206    scan.setStopRow(new byte[1]);
207    scan.setStopRow(new byte[HConstants.MAX_ROW_LENGTH]);
208    try {
209      scan.setStopRow(new byte[HConstants.MAX_ROW_LENGTH+1]);
210      fail("should've thrown exception");
211    } catch (IllegalArgumentException iae) {
212    } catch (Exception e) {
213      fail("expected IllegalArgumentException to be thrown");
214    }
215  }
216
217  @Test
218  public void testScanCopyConstructor() throws Exception {
219    Scan scan = new Scan();
220
221    scan.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("q"))
222        .setACL("test_user", new Permission(Permission.Action.READ))
223        .setAllowPartialResults(true)
224        .setAsyncPrefetch(false)
225        .setAttribute("test_key", Bytes.toBytes("test_value"))
226        .setAuthorizations(new Authorizations("test_label"))
227        .setBatch(10)
228        .setCacheBlocks(false)
229        .setCaching(10)
230        .setConsistency(Consistency.TIMELINE)
231        .setFilter(new FilterList())
232        .setId("scan_copy_constructor")
233        .setIsolationLevel(IsolationLevel.READ_COMMITTED)
234        .setLimit(100)
235        .setLoadColumnFamiliesOnDemand(false)
236        .setMaxResultSize(100)
237        .setMaxResultsPerColumnFamily(1000)
238        .readVersions(9999)
239        .setMvccReadPoint(5)
240        .setNeedCursorResult(true)
241        .setPriority(1)
242        .setRaw(true)
243        .setReplicaId(3)
244        .setReversed(true)
245        .setRowOffsetPerColumnFamily(5)
246        .setRowPrefixFilter(Bytes.toBytes("row_"))
247        .setScanMetricsEnabled(true)
248        .setSmall(true)
249        .setReadType(ReadType.STREAM)
250        .withStartRow(Bytes.toBytes("row_1"))
251        .withStopRow(Bytes.toBytes("row_2"))
252        .setTimeRange(0, 13);
253
254    // create a copy of existing scan object
255    Scan scanCopy = new Scan(scan);
256
257    // validate fields of copied scan object match with the original scan object
258    assertEquals(scan.getACL(), scanCopy.getACL());
259    assertEquals(scan.getAllowPartialResults(), scanCopy.getAllowPartialResults());
260    assertEquals(scan.getAttribute("test_key"), scanCopy.getAttribute("test_key"));
261    assertEquals(scan.getAttributeSize(), scanCopy.getAttributeSize());
262    assertEquals(scan.getAttributesMap(), scanCopy.getAttributesMap());
263    assertEquals(scan.getAuthorizations().getLabels(), scanCopy.getAuthorizations().getLabels());
264    assertEquals(scan.getBatch(), scanCopy.getBatch());
265    assertEquals(scan.getCacheBlocks(), scanCopy.getCacheBlocks());
266    assertEquals(scan.getCaching(), scanCopy.getCaching());
267    assertEquals(scan.getConsistency(), scanCopy.getConsistency());
268    assertEquals(scan.getFamilies().length, scanCopy.getFamilies().length);
269    assertEquals(scan.getFamilies()[0], scanCopy.getFamilies()[0]);
270    assertEquals(scan.getFamilyMap(), scanCopy.getFamilyMap());
271    assertEquals(scan.getFilter(), scanCopy.getFilter());
272    assertEquals(scan.getId(), scanCopy.getId());
273    assertEquals(scan.getIsolationLevel(), scanCopy.getIsolationLevel());
274    assertEquals(scan.getLimit(), scanCopy.getLimit());
275    assertEquals(scan.getLoadColumnFamiliesOnDemandValue(),
276      scanCopy.getLoadColumnFamiliesOnDemandValue());
277    assertEquals(scan.getMaxResultSize(), scanCopy.getMaxResultSize());
278    assertEquals(scan.getMaxResultsPerColumnFamily(), scanCopy.getMaxResultsPerColumnFamily());
279    assertEquals(scan.getMaxVersions(), scanCopy.getMaxVersions());
280    assertEquals(scan.getMvccReadPoint(), scanCopy.getMvccReadPoint());
281    assertEquals(scan.getPriority(), scanCopy.getPriority());
282    assertEquals(scan.getReadType(), scanCopy.getReadType());
283    assertEquals(scan.getReplicaId(), scanCopy.getReplicaId());
284    assertEquals(scan.getRowOffsetPerColumnFamily(), scanCopy.getRowOffsetPerColumnFamily());
285    assertEquals(scan.getStartRow(), scanCopy.getStartRow());
286    assertEquals(scan.getStopRow(), scanCopy.getStopRow());
287    assertEquals(scan.getTimeRange(), scanCopy.getTimeRange());
288
289    assertTrue("Make sure copy constructor adds all the fields in the copied object",
290      EqualsBuilder.reflectionEquals(scan, scanCopy));
291  }
292}
293