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.types; 019 020import static org.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertEquals; 022 023import org.apache.hadoop.hbase.HBaseClassTestRule; 024import org.apache.hadoop.hbase.testclassification.MiscTests; 025import org.apache.hadoop.hbase.testclassification.SmallTests; 026import org.apache.hadoop.hbase.util.Bytes; 027import org.apache.hadoop.hbase.util.Order; 028import org.apache.hadoop.hbase.util.PositionedByteRange; 029import org.apache.hadoop.hbase.util.SimplePositionedMutableByteRange; 030import org.junit.ClassRule; 031import org.junit.Test; 032import org.junit.experimental.categories.Category; 033 034@Category({MiscTests.class, SmallTests.class}) 035public class TestTerminatedWrapper { 036 037 @ClassRule 038 public static final HBaseClassTestRule CLASS_RULE = 039 HBaseClassTestRule.forClass(TestTerminatedWrapper.class); 040 041 static final String[] VALUES_STRINGS = new String[] { 042 "", "1", "22", "333", "4444", "55555", "666666", "7777777", "88888888", "999999999", 043 }; 044 045 static final byte[][] VALUES_BYTES = new byte[VALUES_STRINGS.length][]; 046 static { 047 for (int i = 0; i < VALUES_STRINGS.length; i++) { 048 VALUES_BYTES[i] = Bytes.toBytes(VALUES_STRINGS[i]); 049 } 050 } 051 052 static final byte[][] TERMINATORS = new byte[][] { new byte[] { -2 }, Bytes.toBytes("foo") }; 053 054 @Test(expected = IllegalArgumentException.class) 055 public void testEmptyDelimiter() { 056 new TerminatedWrapper<>(new RawBytes(), ""); 057 } 058 059 @Test(expected = IllegalArgumentException.class) 060 public void testNullDelimiter() { 061 new RawBytesTerminated((byte[]) null); 062 // new TerminatedWrapper<byte[]>(new RawBytes(), (byte[]) null); 063 } 064 065 @Test(expected = IllegalArgumentException.class) 066 public void testEncodedValueContainsTerm() { 067 DataType<byte[]> type = new TerminatedWrapper<>(new RawBytes(), "foo"); 068 PositionedByteRange buff = new SimplePositionedMutableByteRange(16); 069 type.encode(buff, Bytes.toBytes("hello foobar!")); 070 } 071 072 @Test 073 public void testReadWriteSkippable() { 074 PositionedByteRange buff = new SimplePositionedMutableByteRange(14); 075 for (OrderedString t : new OrderedString[] { 076 OrderedString.ASCENDING, OrderedString.DESCENDING 077 }) { 078 for (byte[] term : TERMINATORS) { 079 for (String val : VALUES_STRINGS) { 080 buff.setPosition(0); 081 DataType<String> type = new TerminatedWrapper<>(t, term); 082 assertEquals(val.length() + 2 + term.length, type.encode(buff, val)); 083 buff.setPosition(0); 084 assertEquals(val, type.decode(buff)); 085 assertEquals(val.length() + 2 + term.length, buff.getPosition()); 086 } 087 } 088 } 089 } 090 091 @Test 092 public void testReadWriteNonSkippable() { 093 PositionedByteRange buff = new SimplePositionedMutableByteRange(12); 094 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) { 095 for (byte[] term : TERMINATORS) { 096 for (byte[] val : VALUES_BYTES) { 097 buff.setPosition(0); 098 DataType<byte[]> type = new TerminatedWrapper<>(new RawBytes(ord), term); 099 assertEquals(val.length + term.length, type.encode(buff, val)); 100 buff.setPosition(0); 101 assertArrayEquals(val, type.decode(buff)); 102 assertEquals(val.length + term.length, buff.getPosition()); 103 } 104 } 105 } 106 } 107 108 @Test 109 public void testSkipSkippable() { 110 PositionedByteRange buff = new SimplePositionedMutableByteRange(14); 111 for (OrderedString t : new OrderedString[] { 112 OrderedString.ASCENDING, OrderedString.DESCENDING 113 }) { 114 for (byte[] term : TERMINATORS) { 115 for (String val : VALUES_STRINGS) { 116 buff.setPosition(0); 117 DataType<String> type = new TerminatedWrapper<>(t, term); 118 int expected = val.length() + 2 + term.length; 119 assertEquals(expected, type.encode(buff, val)); 120 buff.setPosition(0); 121 assertEquals(expected, type.skip(buff)); 122 assertEquals(expected, buff.getPosition()); 123 } 124 } 125 } 126 } 127 128 @Test 129 public void testSkipNonSkippable() { 130 PositionedByteRange buff = new SimplePositionedMutableByteRange(12); 131 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) { 132 for (byte[] term : TERMINATORS) { 133 for (byte[] val : VALUES_BYTES) { 134 buff.setPosition(0); 135 DataType<byte[]> type = new TerminatedWrapper<>(new RawBytes(ord), term); 136 int expected = type.encode(buff, val); 137 buff.setPosition(0); 138 assertEquals(expected, type.skip(buff)); 139 assertEquals(expected, buff.getPosition()); 140 } 141 } 142 } 143 } 144 145 @Test(expected = IllegalArgumentException.class) 146 public void testInvalidSkip() { 147 PositionedByteRange buff = new SimplePositionedMutableByteRange(Bytes.toBytes("foo")); 148 DataType<byte[]> type = new TerminatedWrapper<>(new RawBytes(), new byte[] { 0x00 }); 149 type.skip(buff); 150 } 151}