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