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