1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.util;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.DataInputStream;
23 import java.io.DataOutputStream;
24 import java.io.IOException;
25 import java.math.BigDecimal;
26 import java.nio.ByteBuffer;
27 import java.util.Arrays;
28 import java.util.Random;
29
30 import junit.framework.TestCase;
31
32 import org.apache.hadoop.hbase.testclassification.SmallTests;
33 import org.apache.hadoop.io.WritableUtils;
34 import org.junit.Assert;
35 import org.junit.experimental.categories.Category;
36
37
38 @Category(SmallTests.class)
39 public class TestBytes extends TestCase {
40 public void testNullHashCode() {
41 byte [] b = null;
42 Exception ee = null;
43 try {
44 Bytes.hashCode(b);
45 } catch (Exception e) {
46 ee = e;
47 }
48 assertNotNull(ee);
49 }
50
51 public void testSplit() throws Exception {
52 byte [] lowest = Bytes.toBytes("AAA");
53 byte [] middle = Bytes.toBytes("CCC");
54 byte [] highest = Bytes.toBytes("EEE");
55 byte [][] parts = Bytes.split(lowest, highest, 1);
56 for (int i = 0; i < parts.length; i++) {
57 System.out.println(Bytes.toString(parts[i]));
58 }
59 assertEquals(3, parts.length);
60 assertTrue(Bytes.equals(parts[1], middle));
61
62 highest = Bytes.toBytes("DDD");
63 parts = Bytes.split(lowest, highest, 2);
64 for (int i = 0; i < parts.length; i++) {
65 System.out.println(Bytes.toString(parts[i]));
66 }
67 assertEquals(4, parts.length);
68
69 assertTrue(Bytes.equals(parts[2], middle));
70 }
71
72 public void testSplit2() throws Exception {
73
74 byte [] lowest = Bytes.toBytes("http://A");
75 byte [] highest = Bytes.toBytes("http://z");
76 byte [] middle = Bytes.toBytes("http://]");
77 byte [][] parts = Bytes.split(lowest, highest, 1);
78 for (int i = 0; i < parts.length; i++) {
79 System.out.println(Bytes.toString(parts[i]));
80 }
81 assertEquals(3, parts.length);
82 assertTrue(Bytes.equals(parts[1], middle));
83 }
84
85 public void testSplit3() throws Exception {
86
87 byte [] low = { 1, 1, 1 };
88 byte [] high = { 1, 1, 3 };
89
90
91 try {
92 Bytes.split(high, low, 1);
93 assertTrue("Should not be able to split if low > high", false);
94 } catch(IllegalArgumentException iae) {
95
96 }
97
98
99 byte [][] parts = Bytes.split(low, high, 1);
100 for (int i = 0; i < parts.length; i++) {
101 System.out.println("" + i + " -> " + Bytes.toStringBinary(parts[i]));
102 }
103 assertTrue("Returned split should have 3 parts but has " + parts.length, parts.length == 3);
104
105
106 parts = Bytes.split(low, high, 2);
107 assertTrue("Split with an additional byte", parts != null);
108 assertEquals(parts.length, low.length + 1);
109
110
111 try {
112 parts = Bytes.split(low, high, 0);
113 assertTrue("Should not be able to split 0 times", false);
114 } catch(IllegalArgumentException iae) {
115
116 }
117 }
118
119 public void testToInt() throws Exception {
120 int [] ints = {-1, 123, Integer.MIN_VALUE, Integer.MAX_VALUE};
121 for (int i = 0; i < ints.length; i++) {
122 byte [] b = Bytes.toBytes(ints[i]);
123 assertEquals(ints[i], Bytes.toInt(b));
124 byte [] b2 = bytesWithOffset(b);
125 assertEquals(ints[i], Bytes.toInt(b2, 1));
126 assertEquals(ints[i], Bytes.toInt(b2, 1, Bytes.SIZEOF_INT));
127 }
128 }
129
130 public void testToLong() throws Exception {
131 long [] longs = {-1l, 123l, Long.MIN_VALUE, Long.MAX_VALUE};
132 for (int i = 0; i < longs.length; i++) {
133 byte [] b = Bytes.toBytes(longs[i]);
134 assertEquals(longs[i], Bytes.toLong(b));
135 byte [] b2 = bytesWithOffset(b);
136 assertEquals(longs[i], Bytes.toLong(b2, 1));
137 assertEquals(longs[i], Bytes.toLong(b2, 1, Bytes.SIZEOF_LONG));
138 }
139 }
140
141 public void testToFloat() throws Exception {
142 float [] floats = {-1f, 123.123f, Float.MAX_VALUE};
143 for (int i = 0; i < floats.length; i++) {
144 byte [] b = Bytes.toBytes(floats[i]);
145 assertEquals(floats[i], Bytes.toFloat(b));
146 byte [] b2 = bytesWithOffset(b);
147 assertEquals(floats[i], Bytes.toFloat(b2, 1));
148 }
149 }
150
151 public void testToDouble() throws Exception {
152 double [] doubles = {Double.MIN_VALUE, Double.MAX_VALUE};
153 for (int i = 0; i < doubles.length; i++) {
154 byte [] b = Bytes.toBytes(doubles[i]);
155 assertEquals(doubles[i], Bytes.toDouble(b));
156 byte [] b2 = bytesWithOffset(b);
157 assertEquals(doubles[i], Bytes.toDouble(b2, 1));
158 }
159 }
160
161 public void testToBigDecimal() throws Exception {
162 BigDecimal [] decimals = {new BigDecimal("-1"), new BigDecimal("123.123"),
163 new BigDecimal("123123123123")};
164 for (int i = 0; i < decimals.length; i++) {
165 byte [] b = Bytes.toBytes(decimals[i]);
166 assertEquals(decimals[i], Bytes.toBigDecimal(b));
167 byte [] b2 = bytesWithOffset(b);
168 assertEquals(decimals[i], Bytes.toBigDecimal(b2, 1, b.length));
169 }
170 }
171
172 private byte [] bytesWithOffset(byte [] src) {
173
174 byte [] result = new byte[src.length + 1];
175 result[0] = (byte) 0xAA;
176 System.arraycopy(src, 0, result, 1, src.length);
177 return result;
178 }
179
180 public void testToBytesForByteBuffer() {
181 byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
182 ByteBuffer target = ByteBuffer.wrap(array);
183 target.position(2);
184 target.limit(7);
185
186 byte[] actual = Bytes.toBytes(target);
187 byte[] expected = { 0, 1, 2, 3, 4, 5, 6 };
188 assertTrue(Arrays.equals(expected, actual));
189 assertEquals(2, target.position());
190 assertEquals(7, target.limit());
191
192 ByteBuffer target2 = target.slice();
193 assertEquals(0, target2.position());
194 assertEquals(5, target2.limit());
195
196 byte[] actual2 = Bytes.toBytes(target2);
197 byte[] expected2 = { 2, 3, 4, 5, 6 };
198 assertTrue(Arrays.equals(expected2, actual2));
199 assertEquals(0, target2.position());
200 assertEquals(5, target2.limit());
201 }
202
203 public void testGetBytesForByteBuffer() {
204 byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
205 ByteBuffer target = ByteBuffer.wrap(array);
206 target.position(2);
207 target.limit(7);
208
209 byte[] actual = Bytes.getBytes(target);
210 byte[] expected = { 2, 3, 4, 5, 6 };
211 assertTrue(Arrays.equals(expected, actual));
212 assertEquals(2, target.position());
213 assertEquals(7, target.limit());
214 }
215
216 public void testReadAsVLong() throws Exception {
217 long [] longs = {-1l, 123l, Long.MIN_VALUE, Long.MAX_VALUE};
218 for (int i = 0; i < longs.length; i++) {
219 ByteArrayOutputStream baos = new ByteArrayOutputStream();
220 DataOutputStream output = new DataOutputStream(baos);
221 WritableUtils.writeVLong(output, longs[i]);
222 byte[] long_bytes_no_offset = baos.toByteArray();
223 assertEquals(longs[i], Bytes.readAsVLong(long_bytes_no_offset, 0));
224 byte[] long_bytes_with_offset = bytesWithOffset(long_bytes_no_offset);
225 assertEquals(longs[i], Bytes.readAsVLong(long_bytes_with_offset, 1));
226 }
227 }
228
229 public void testToStringBinaryForBytes() {
230 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 };
231 String actual = Bytes.toStringBinary(array);
232 String expected = "09azAZ@\\x01";
233 assertEquals(expected, actual);
234
235 String actual2 = Bytes.toStringBinary(array, 2, 3);
236 String expected2 = "azA";
237 assertEquals(expected2, actual2);
238 }
239
240 public void testToStringBinaryForArrayBasedByteBuffer() {
241 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 };
242 ByteBuffer target = ByteBuffer.wrap(array);
243 String actual = Bytes.toStringBinary(target);
244 String expected = "09azAZ@\\x01";
245 assertEquals(expected, actual);
246 }
247
248 public void testToStringBinaryForReadOnlyByteBuffer() {
249 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 };
250 ByteBuffer target = ByteBuffer.wrap(array).asReadOnlyBuffer();
251 String actual = Bytes.toStringBinary(target);
252 String expected = "09azAZ@\\x01";
253 assertEquals(expected, actual);
254 }
255
256 public void testBinarySearch() throws Exception {
257 byte [][] arr = {
258 {1},
259 {3},
260 {5},
261 {7},
262 {9},
263 {11},
264 {13},
265 {15},
266 };
267 byte [] key1 = {3,1};
268 byte [] key2 = {4,9};
269 byte [] key2_2 = {4};
270 byte [] key3 = {5,11};
271 byte [] key4 = {0};
272 byte [] key5 = {2};
273
274 assertEquals(1, Bytes.binarySearch(arr, key1, 0, 1,
275 Bytes.BYTES_RAWCOMPARATOR));
276 assertEquals(0, Bytes.binarySearch(arr, key1, 1, 1,
277 Bytes.BYTES_RAWCOMPARATOR));
278 assertEquals(-(2+1), Arrays.binarySearch(arr, key2_2,
279 Bytes.BYTES_COMPARATOR));
280 assertEquals(-(2+1), Bytes.binarySearch(arr, key2, 0, 1,
281 Bytes.BYTES_RAWCOMPARATOR));
282 assertEquals(4, Bytes.binarySearch(arr, key2, 1, 1,
283 Bytes.BYTES_RAWCOMPARATOR));
284 assertEquals(2, Bytes.binarySearch(arr, key3, 0, 1,
285 Bytes.BYTES_RAWCOMPARATOR));
286 assertEquals(5, Bytes.binarySearch(arr, key3, 1, 1,
287 Bytes.BYTES_RAWCOMPARATOR));
288 assertEquals(-1,
289 Bytes.binarySearch(arr, key4, 0, 1, Bytes.BYTES_RAWCOMPARATOR));
290 assertEquals(-2,
291 Bytes.binarySearch(arr, key5, 0, 1, Bytes.BYTES_RAWCOMPARATOR));
292
293
294 for (int i = 0; i < arr.length; ++i) {
295 assertEquals(-(i + 1), Bytes.binarySearch(arr,
296 new byte[] { (byte) (arr[i][0] - 1) }, 0, 1,
297 Bytes.BYTES_RAWCOMPARATOR));
298 assertEquals(-(i + 2), Bytes.binarySearch(arr,
299 new byte[] { (byte) (arr[i][0] + 1) }, 0, 1,
300 Bytes.BYTES_RAWCOMPARATOR));
301 }
302 }
303
304 public void testToStringBytesBinaryReversible() {
305
306 Random rand = new Random(System.currentTimeMillis());
307 byte[] randomBytes = new byte[1000];
308 for (int i = 0; i < 1000; i++) {
309 rand.nextBytes(randomBytes);
310 verifyReversibleForBytes(randomBytes);
311 }
312
313
314 verifyReversibleForBytes(new byte[] {});
315 verifyReversibleForBytes(new byte[] {'\\', 'x', 'A', 'D'});
316 verifyReversibleForBytes(new byte[] {'\\', 'x', 'A', 'D', '\\'});
317 }
318
319 private void verifyReversibleForBytes(byte[] originalBytes) {
320 String convertedString = Bytes.toStringBinary(originalBytes);
321 byte[] convertedBytes = Bytes.toBytesBinary(convertedString);
322 if (Bytes.compareTo(originalBytes, convertedBytes) != 0) {
323 fail("Not reversible for\nbyte[]: " + Arrays.toString(originalBytes) +
324 ",\nStringBinary: " + convertedString);
325 }
326 }
327
328 public void testStartsWith() {
329 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("h")));
330 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("")));
331 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("hello")));
332 assertFalse(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("helloworld")));
333 assertFalse(Bytes.startsWith(Bytes.toBytes(""), Bytes.toBytes("hello")));
334 }
335
336 public void testIncrementBytes() throws IOException {
337
338 assertTrue(checkTestIncrementBytes(10, 1));
339 assertTrue(checkTestIncrementBytes(12, 123435445));
340 assertTrue(checkTestIncrementBytes(124634654, 1));
341 assertTrue(checkTestIncrementBytes(10005460, 5005645));
342 assertTrue(checkTestIncrementBytes(1, -1));
343 assertTrue(checkTestIncrementBytes(10, -1));
344 assertTrue(checkTestIncrementBytes(10, -5));
345 assertTrue(checkTestIncrementBytes(1005435000, -5));
346 assertTrue(checkTestIncrementBytes(10, -43657655));
347 assertTrue(checkTestIncrementBytes(-1, 1));
348 assertTrue(checkTestIncrementBytes(-26, 5034520));
349 assertTrue(checkTestIncrementBytes(-10657200, 5));
350 assertTrue(checkTestIncrementBytes(-12343250, 45376475));
351 assertTrue(checkTestIncrementBytes(-10, -5));
352 assertTrue(checkTestIncrementBytes(-12343250, -5));
353 assertTrue(checkTestIncrementBytes(-12, -34565445));
354 assertTrue(checkTestIncrementBytes(-1546543452, -34565445));
355 }
356
357 private static boolean checkTestIncrementBytes(long val, long amount)
358 throws IOException {
359 byte[] value = Bytes.toBytes(val);
360 byte [] testValue = {-1, -1, -1, -1, -1, -1, -1, -1};
361 if (value[0] > 0) {
362 testValue = new byte[Bytes.SIZEOF_LONG];
363 }
364 System.arraycopy(value, 0, testValue, testValue.length - value.length,
365 value.length);
366
367 long incrementResult = Bytes.toLong(Bytes.incrementBytes(value, amount));
368
369 return (Bytes.toLong(testValue) + amount) == incrementResult;
370 }
371
372 public void testFixedSizeString() throws IOException {
373 ByteArrayOutputStream baos = new ByteArrayOutputStream();
374 DataOutputStream dos = new DataOutputStream(baos);
375 Bytes.writeStringFixedSize(dos, "Hello", 5);
376 Bytes.writeStringFixedSize(dos, "World", 18);
377 Bytes.writeStringFixedSize(dos, "", 9);
378
379 try {
380
381
382 Bytes.writeStringFixedSize(dos, "Too\u2013Long", 9);
383 fail("Exception expected");
384 } catch (IOException ex) {
385 assertEquals(
386 "Trying to write 10 bytes (Too\\xE2\\x80\\x93Long) into a field of " +
387 "length 9", ex.getMessage());
388 }
389
390 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
391 DataInputStream dis = new DataInputStream(bais);
392 assertEquals("Hello", Bytes.readStringFixedSize(dis, 5));
393 assertEquals("World", Bytes.readStringFixedSize(dis, 18));
394 assertEquals("", Bytes.readStringFixedSize(dis, 9));
395 }
396
397 public void testCopy() throws Exception {
398 byte [] bytes = Bytes.toBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
399 byte [] copy = Bytes.copy(bytes);
400 assertFalse(bytes == copy);
401 assertTrue(Bytes.equals(bytes, copy));
402 }
403
404 public void testToBytesBinaryTrailingBackslashes() throws Exception {
405 try {
406 Bytes.toBytesBinary("abc\\x00\\x01\\");
407 } catch (StringIndexOutOfBoundsException ex) {
408 fail("Illegal string access: " + ex.getMessage());
409 }
410 }
411
412 public void testToStringBinary_toBytesBinary_Reversable() throws Exception {
413 String bytes = Bytes.toStringBinary(Bytes.toBytes(2.17));
414 assertEquals(2.17, Bytes.toDouble(Bytes.toBytesBinary(bytes)), 0);
415 }
416
417 public void testUnsignedBinarySearch(){
418 byte[] bytes = new byte[]{0,5,123,127,-128,-100,-1};
419 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)5), 1);
420 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)127), 3);
421 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-128), 4);
422 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-100), 5);
423 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-1), 6);
424 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)2), -1-1);
425 Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-5), -6-1);
426 }
427
428 public void testUnsignedIncrement(){
429 byte[] a = Bytes.toBytes(0);
430 int a2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(a), 0);
431 Assert.assertTrue(a2==1);
432
433 byte[] b = Bytes.toBytes(-1);
434 byte[] actual = Bytes.unsignedCopyAndIncrement(b);
435 Assert.assertNotSame(b, actual);
436 byte[] expected = new byte[]{1,0,0,0,0};
437 Assert.assertArrayEquals(expected, actual);
438
439 byte[] c = Bytes.toBytes(255);
440 int c2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(c), 0);
441 Assert.assertTrue(c2==256);
442 }
443
444 public void testIndexOf() {
445 byte[] array = Bytes.toBytes("hello");
446 assertEquals(1, Bytes.indexOf(array, (byte) 'e'));
447 assertEquals(4, Bytes.indexOf(array, (byte) 'o'));
448 assertEquals(-1, Bytes.indexOf(array, (byte) 'a'));
449 assertEquals(0, Bytes.indexOf(array, Bytes.toBytes("hel")));
450 assertEquals(2, Bytes.indexOf(array, Bytes.toBytes("ll")));
451 assertEquals(-1, Bytes.indexOf(array, Bytes.toBytes("hll")));
452 }
453
454 public void testContains() {
455 byte[] array = Bytes.toBytes("hello world");
456 assertTrue(Bytes.contains(array, (byte) 'e'));
457 assertTrue(Bytes.contains(array, (byte) 'd'));
458 assertFalse( Bytes.contains(array, (byte) 'a'));
459 assertTrue(Bytes.contains(array, Bytes.toBytes("world")));
460 assertTrue(Bytes.contains(array, Bytes.toBytes("ello")));
461 assertFalse(Bytes.contains(array, Bytes.toBytes("owo")));
462 }
463
464 public void testZero() {
465 byte[] array = Bytes.toBytes("hello");
466 Bytes.zero(array);
467 for (int i = 0; i < array.length; i++) {
468 assertEquals(0, array[i]);
469 }
470 array = Bytes.toBytes("hello world");
471 Bytes.zero(array, 2, 7);
472 assertFalse(array[0] == 0);
473 assertFalse(array[1] == 0);
474 for (int i = 2; i < 9; i++) {
475 assertEquals(0, array[i]);
476 }
477 for (int i = 9; i < array.length; i++) {
478 assertFalse(array[i] == 0);
479 }
480 }
481
482 public void testPutBuffer() {
483 byte[] b = new byte[100];
484 for (byte i = 0; i < 100; i++) {
485 Bytes.putByteBuffer(b, i, ByteBuffer.wrap(new byte[]{i}));
486 }
487 for (byte i = 0; i < 100; i++) {
488 Assert.assertEquals(i, b[i]);
489 }
490 }
491 }
492