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