View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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.ArrayList;
28  import java.util.Arrays;
29  import java.util.List;
30  import java.util.Random;
31  
32  import junit.framework.TestCase;
33  
34  import org.apache.hadoop.hbase.testclassification.SmallTests;
35  import org.apache.hadoop.io.WritableUtils;
36  import org.junit.Assert;
37  import org.junit.experimental.categories.Category;
38  
39  
40  @Category(SmallTests.class)
41  public class TestBytes extends TestCase {
42    public void testNullHashCode() {
43      byte [] b = null;
44      Exception ee = null;
45      try {
46        Bytes.hashCode(b);
47      } catch (Exception e) {
48        ee = e;
49      }
50      assertNotNull(ee);
51    }
52  
53    public void testAdd () throws Exception {
54      byte[] a = {0,0,0,0,0,0,0,0,0,0};
55      byte[] b = {1,1,1,1,1,1,1,1,1,1,1};
56      byte[] c = {2,2,2,2,2,2,2,2,2,2,2,2};
57      byte[] d = {3,3,3,3,3,3,3,3,3,3,3,3,3};
58      byte[] result1 = Bytes.add (a, b, c);
59      byte[] result2 = Bytes.add (new byte[][] {a, b, c});
60      assertEquals(0, Bytes.compareTo(result1, result2));
61      byte[] result4 = Bytes.add (result1, d);
62      byte[] result5 = Bytes.add (new byte[][] {result1, d});
63      assertEquals(0, Bytes.compareTo(result1, result2));
64    }
65  
66    public void testSplit() throws Exception {
67      byte [] lowest = Bytes.toBytes("AAA");
68      byte [] middle = Bytes.toBytes("CCC");
69      byte [] highest = Bytes.toBytes("EEE");
70      byte [][] parts = Bytes.split(lowest, highest, 1);
71      for (int i = 0; i < parts.length; i++) {
72        System.out.println(Bytes.toString(parts[i]));
73      }
74      assertEquals(3, parts.length);
75      assertTrue(Bytes.equals(parts[1], middle));
76      // Now divide into three parts.  Change highest so split is even.
77      highest = Bytes.toBytes("DDD");
78      parts = Bytes.split(lowest, highest, 2);
79      for (int i = 0; i < parts.length; i++) {
80        System.out.println(Bytes.toString(parts[i]));
81      }
82      assertEquals(4, parts.length);
83      // Assert that 3rd part is 'CCC'.
84      assertTrue(Bytes.equals(parts[2], middle));
85    }
86  
87    public void testSplit2() throws Exception {
88      // More split tests.
89      byte [] lowest = Bytes.toBytes("http://A");
90      byte [] highest = Bytes.toBytes("http://z");
91      byte [] middle = Bytes.toBytes("http://]");
92      byte [][] parts = Bytes.split(lowest, highest, 1);
93      for (int i = 0; i < parts.length; i++) {
94        System.out.println(Bytes.toString(parts[i]));
95      }
96      assertEquals(3, parts.length);
97      assertTrue(Bytes.equals(parts[1], middle));
98    }
99  
100   public void testSplit3() throws Exception {
101     // Test invalid split cases
102     byte [] low = { 1, 1, 1 };
103     byte [] high = { 1, 1, 3 };
104 
105     // If swapped, should throw IAE
106     try {
107       Bytes.split(high, low, 1);
108       assertTrue("Should not be able to split if low > high", false);
109     } catch(IllegalArgumentException iae) {
110       // Correct
111     }
112 
113     // Single split should work
114     byte [][] parts = Bytes.split(low, high, 1);
115     for (int i = 0; i < parts.length; i++) {
116       System.out.println("" + i + " -> " + Bytes.toStringBinary(parts[i]));
117     }
118     assertTrue("Returned split should have 3 parts but has " + parts.length, parts.length == 3);
119 
120     // If split more than once, use additional byte to split
121     parts = Bytes.split(low, high, 2);
122     assertTrue("Split with an additional byte", parts != null);
123     assertEquals(parts.length, low.length + 1);
124 
125     // Split 0 times should throw IAE
126     try {
127       parts = Bytes.split(low, high, 0);
128       assertTrue("Should not be able to split 0 times", false);
129     } catch(IllegalArgumentException iae) {
130       // Correct
131     }
132   }
133 
134   public void testToInt() throws Exception {
135     int [] ints = {-1, 123, Integer.MIN_VALUE, Integer.MAX_VALUE};
136     for (int i = 0; i < ints.length; i++) {
137       byte [] b = Bytes.toBytes(ints[i]);
138       assertEquals(ints[i], Bytes.toInt(b));
139       byte [] b2 = bytesWithOffset(b);
140       assertEquals(ints[i], Bytes.toInt(b2, 1));
141       assertEquals(ints[i], Bytes.toInt(b2, 1, Bytes.SIZEOF_INT));
142     }
143   }
144 
145   public void testToLong() throws Exception {
146     long [] longs = {-1l, 123l, Long.MIN_VALUE, Long.MAX_VALUE};
147     for (int i = 0; i < longs.length; i++) {
148       byte [] b = Bytes.toBytes(longs[i]);
149       assertEquals(longs[i], Bytes.toLong(b));
150       byte [] b2 = bytesWithOffset(b);
151       assertEquals(longs[i], Bytes.toLong(b2, 1));
152       assertEquals(longs[i], Bytes.toLong(b2, 1, Bytes.SIZEOF_LONG));
153     }
154   }
155 
156   public void testToFloat() throws Exception {
157     float [] floats = {-1f, 123.123f, Float.MAX_VALUE};
158     for (int i = 0; i < floats.length; i++) {
159       byte [] b = Bytes.toBytes(floats[i]);
160       assertEquals(floats[i], Bytes.toFloat(b));
161       byte [] b2 = bytesWithOffset(b);
162       assertEquals(floats[i], Bytes.toFloat(b2, 1));
163     }
164   }
165 
166   public void testToDouble() throws Exception {
167     double [] doubles = {Double.MIN_VALUE, Double.MAX_VALUE};
168     for (int i = 0; i < doubles.length; i++) {
169       byte [] b = Bytes.toBytes(doubles[i]);
170       assertEquals(doubles[i], Bytes.toDouble(b));
171       byte [] b2 = bytesWithOffset(b);
172       assertEquals(doubles[i], Bytes.toDouble(b2, 1));
173     }
174   }
175 
176   public void testToBigDecimal() throws Exception {
177     BigDecimal [] decimals = {new BigDecimal("-1"), new BigDecimal("123.123"),
178       new BigDecimal("123123123123")};
179     for (int i = 0; i < decimals.length; i++) {
180       byte [] b = Bytes.toBytes(decimals[i]);
181       assertEquals(decimals[i], Bytes.toBigDecimal(b));
182       byte [] b2 = bytesWithOffset(b);
183       assertEquals(decimals[i], Bytes.toBigDecimal(b2, 1, b.length));
184     }
185   }
186 
187   private byte [] bytesWithOffset(byte [] src) {
188     // add one byte in front to test offset
189     byte [] result = new byte[src.length + 1];
190     result[0] = (byte) 0xAA;
191     System.arraycopy(src, 0, result, 1, src.length);
192     return result;
193   }
194 
195   public void testToBytesForByteBuffer() {
196     byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
197     ByteBuffer target = ByteBuffer.wrap(array);
198     target.position(2);
199     target.limit(7);
200 
201     byte[] actual = Bytes.toBytes(target);
202     byte[] expected = { 0, 1, 2, 3, 4, 5, 6 };
203     assertTrue(Arrays.equals(expected,  actual));
204     assertEquals(2, target.position());
205     assertEquals(7, target.limit());
206 
207     ByteBuffer target2 = target.slice();
208     assertEquals(0, target2.position());
209     assertEquals(5, target2.limit());
210 
211     byte[] actual2 = Bytes.toBytes(target2);
212     byte[] expected2 = { 2, 3, 4, 5, 6 };
213     assertTrue(Arrays.equals(expected2, actual2));
214     assertEquals(0, target2.position());
215     assertEquals(5, target2.limit());
216   }
217 
218   public void testGetBytesForByteBuffer() {
219     byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
220     ByteBuffer target = ByteBuffer.wrap(array);
221     target.position(2);
222     target.limit(7);
223 
224     byte[] actual = Bytes.getBytes(target);
225     byte[] expected = { 2, 3, 4, 5, 6 };
226     assertTrue(Arrays.equals(expected,  actual));
227     assertEquals(2, target.position());
228     assertEquals(7, target.limit());
229   }
230 
231   public void testReadAsVLong() throws Exception {
232     long [] longs = {-1l, 123l, Long.MIN_VALUE, Long.MAX_VALUE};
233     for (int i = 0; i < longs.length; i++) {
234       ByteArrayOutputStream baos = new ByteArrayOutputStream();
235       DataOutputStream output = new DataOutputStream(baos);
236       WritableUtils.writeVLong(output, longs[i]);
237       byte[] long_bytes_no_offset = baos.toByteArray();
238       assertEquals(longs[i], Bytes.readAsVLong(long_bytes_no_offset, 0));
239       byte[] long_bytes_with_offset = bytesWithOffset(long_bytes_no_offset);
240       assertEquals(longs[i], Bytes.readAsVLong(long_bytes_with_offset, 1));
241     }
242   }
243 
244   public void testToStringBinaryForBytes() {
245     byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 };
246     String actual = Bytes.toStringBinary(array);
247     String expected = "09azAZ@\\x01";
248     assertEquals(expected, actual);
249 
250     String actual2 = Bytes.toStringBinary(array, 2, 3);
251     String expected2 = "azA";
252     assertEquals(expected2, actual2);
253   }
254 
255   public void testToStringBinaryForArrayBasedByteBuffer() {
256     byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 };
257     ByteBuffer target = ByteBuffer.wrap(array);
258     String actual = Bytes.toStringBinary(target);
259     String expected = "09azAZ@\\x01";
260     assertEquals(expected, actual);
261   }
262 
263   public void testToStringBinaryForReadOnlyByteBuffer() {
264     byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 };
265     ByteBuffer target = ByteBuffer.wrap(array).asReadOnlyBuffer();
266     String actual = Bytes.toStringBinary(target);
267     String expected = "09azAZ@\\x01";
268     assertEquals(expected, actual);
269   }
270 
271   public void testBinarySearch() throws Exception {
272     byte [][] arr = {
273         {1},
274         {3},
275         {5},
276         {7},
277         {9},
278         {11},
279         {13},
280         {15},
281     };
282     byte [] key1 = {3,1};
283     byte [] key2 = {4,9};
284     byte [] key2_2 = {4};
285     byte [] key3 = {5,11};
286     byte [] key4 = {0};
287     byte [] key5 = {2};
288 
289     assertEquals(1, Bytes.binarySearch(arr, key1, 0, 1,
290       Bytes.BYTES_RAWCOMPARATOR));
291     assertEquals(0, Bytes.binarySearch(arr, key1, 1, 1,
292       Bytes.BYTES_RAWCOMPARATOR));
293     assertEquals(-(2+1), Arrays.binarySearch(arr, key2_2,
294       Bytes.BYTES_COMPARATOR));
295     assertEquals(-(2+1), Bytes.binarySearch(arr, key2, 0, 1,
296       Bytes.BYTES_RAWCOMPARATOR));
297     assertEquals(4, Bytes.binarySearch(arr, key2, 1, 1,
298       Bytes.BYTES_RAWCOMPARATOR));
299     assertEquals(2, Bytes.binarySearch(arr, key3, 0, 1,
300       Bytes.BYTES_RAWCOMPARATOR));
301     assertEquals(5, Bytes.binarySearch(arr, key3, 1, 1,
302       Bytes.BYTES_RAWCOMPARATOR));
303     assertEquals(-1,
304       Bytes.binarySearch(arr, key4, 0, 1, Bytes.BYTES_RAWCOMPARATOR));
305     assertEquals(-2,
306       Bytes.binarySearch(arr, key5, 0, 1, Bytes.BYTES_RAWCOMPARATOR));
307 
308     // Search for values to the left and to the right of each item in the array.
309     for (int i = 0; i < arr.length; ++i) {
310       assertEquals(-(i + 1), Bytes.binarySearch(arr,
311           new byte[] { (byte) (arr[i][0] - 1) }, 0, 1,
312           Bytes.BYTES_RAWCOMPARATOR));
313       assertEquals(-(i + 2), Bytes.binarySearch(arr,
314           new byte[] { (byte) (arr[i][0] + 1) }, 0, 1,
315           Bytes.BYTES_RAWCOMPARATOR));
316     }
317   }
318 
319   public void testToStringBytesBinaryReversible() {
320     //  let's run test with 1000 randomly generated byte arrays
321     Random rand = new Random(System.currentTimeMillis());
322     byte[] randomBytes = new byte[1000];
323     for (int i = 0; i < 1000; i++) {
324       rand.nextBytes(randomBytes);
325       verifyReversibleForBytes(randomBytes);
326     }
327 
328     //  some specific cases
329     verifyReversibleForBytes(new  byte[] {});
330     verifyReversibleForBytes(new  byte[] {'\\', 'x', 'A', 'D'});
331     verifyReversibleForBytes(new  byte[] {'\\', 'x', 'A', 'D', '\\'});
332   }
333 
334   private void verifyReversibleForBytes(byte[] originalBytes) {
335     String convertedString = Bytes.toStringBinary(originalBytes);
336     byte[] convertedBytes = Bytes.toBytesBinary(convertedString);
337     if (Bytes.compareTo(originalBytes, convertedBytes) != 0) {
338       fail("Not reversible for\nbyte[]: " + Arrays.toString(originalBytes) +
339           ",\nStringBinary: " + convertedString);
340     }
341   }
342 
343   public void testStartsWith() {
344     assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("h")));
345     assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("")));
346     assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("hello")));
347     assertFalse(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("helloworld")));
348     assertFalse(Bytes.startsWith(Bytes.toBytes(""), Bytes.toBytes("hello")));
349   }
350 
351   public void testIncrementBytes() throws IOException {
352 
353     assertTrue(checkTestIncrementBytes(10, 1));
354     assertTrue(checkTestIncrementBytes(12, 123435445));
355     assertTrue(checkTestIncrementBytes(124634654, 1));
356     assertTrue(checkTestIncrementBytes(10005460, 5005645));
357     assertTrue(checkTestIncrementBytes(1, -1));
358     assertTrue(checkTestIncrementBytes(10, -1));
359     assertTrue(checkTestIncrementBytes(10, -5));
360     assertTrue(checkTestIncrementBytes(1005435000, -5));
361     assertTrue(checkTestIncrementBytes(10, -43657655));
362     assertTrue(checkTestIncrementBytes(-1, 1));
363     assertTrue(checkTestIncrementBytes(-26, 5034520));
364     assertTrue(checkTestIncrementBytes(-10657200, 5));
365     assertTrue(checkTestIncrementBytes(-12343250, 45376475));
366     assertTrue(checkTestIncrementBytes(-10, -5));
367     assertTrue(checkTestIncrementBytes(-12343250, -5));
368     assertTrue(checkTestIncrementBytes(-12, -34565445));
369     assertTrue(checkTestIncrementBytes(-1546543452, -34565445));
370   }
371 
372   private static boolean checkTestIncrementBytes(long val, long amount)
373   throws IOException {
374     byte[] value = Bytes.toBytes(val);
375     byte [] testValue = {-1, -1, -1, -1, -1, -1, -1, -1};
376     if (value[0] > 0) {
377       testValue = new byte[Bytes.SIZEOF_LONG];
378     }
379     System.arraycopy(value, 0, testValue, testValue.length - value.length,
380         value.length);
381 
382     long incrementResult = Bytes.toLong(Bytes.incrementBytes(value, amount));
383 
384     return (Bytes.toLong(testValue) + amount) == incrementResult;
385   }
386 
387   public void testFixedSizeString() throws IOException {
388     ByteArrayOutputStream baos = new ByteArrayOutputStream();
389     DataOutputStream dos = new DataOutputStream(baos);
390     Bytes.writeStringFixedSize(dos, "Hello", 5);
391     Bytes.writeStringFixedSize(dos, "World", 18);
392     Bytes.writeStringFixedSize(dos, "", 9);
393 
394     try {
395       // Use a long dash which is three bytes in UTF-8. If encoding happens
396       // using ISO-8859-1, this will fail.
397       Bytes.writeStringFixedSize(dos, "Too\u2013Long", 9);
398       fail("Exception expected");
399     } catch (IOException ex) {
400       assertEquals(
401           "Trying to write 10 bytes (Too\\xE2\\x80\\x93Long) into a field of " +
402           "length 9", ex.getMessage());
403     }
404 
405     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
406     DataInputStream dis = new DataInputStream(bais);
407     assertEquals("Hello", Bytes.readStringFixedSize(dis, 5));
408     assertEquals("World", Bytes.readStringFixedSize(dis, 18));
409     assertEquals("", Bytes.readStringFixedSize(dis, 9));
410   }
411 
412   public void testCopy() throws Exception {
413     byte [] bytes = Bytes.toBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
414     byte [] copy =  Bytes.copy(bytes);
415     assertFalse(bytes == copy);
416     assertTrue(Bytes.equals(bytes, copy));
417   }
418 
419   public void testToBytesBinaryTrailingBackslashes() throws Exception {
420     try {
421       Bytes.toBytesBinary("abc\\x00\\x01\\");
422     } catch (StringIndexOutOfBoundsException ex) {
423       fail("Illegal string access: " + ex.getMessage());
424     }
425   }
426 
427   public void testToStringBinary_toBytesBinary_Reversable() throws Exception {
428     String bytes = Bytes.toStringBinary(Bytes.toBytes(2.17));
429     assertEquals(2.17, Bytes.toDouble(Bytes.toBytesBinary(bytes)), 0);        
430   }
431 
432   public void testUnsignedBinarySearch(){
433     byte[] bytes = new byte[]{0,5,123,127,-128,-100,-1};
434     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)5), 1);
435     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)127), 3);
436     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-128), 4);
437     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-100), 5);
438     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-1), 6);
439     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)2), -1-1);
440     Assert.assertEquals(Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte)-5), -6-1);
441   }
442 
443   public void testUnsignedIncrement(){
444     byte[] a = Bytes.toBytes(0);
445     int a2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(a), 0);
446     Assert.assertTrue(a2==1);
447 
448     byte[] b = Bytes.toBytes(-1);
449     byte[] actual = Bytes.unsignedCopyAndIncrement(b);
450     Assert.assertNotSame(b, actual);
451     byte[] expected = new byte[]{1,0,0,0,0};
452     Assert.assertArrayEquals(expected, actual);
453 
454     byte[] c = Bytes.toBytes(255);//should wrap to the next significant byte
455     int c2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(c), 0);
456     Assert.assertTrue(c2==256);
457   }
458   
459   public void testIndexOf() {
460     byte[] array = Bytes.toBytes("hello");
461     assertEquals(1, Bytes.indexOf(array, (byte) 'e'));
462     assertEquals(4, Bytes.indexOf(array, (byte) 'o'));
463     assertEquals(-1, Bytes.indexOf(array, (byte) 'a'));
464     assertEquals(0, Bytes.indexOf(array, Bytes.toBytes("hel")));
465     assertEquals(2, Bytes.indexOf(array, Bytes.toBytes("ll")));
466     assertEquals(-1, Bytes.indexOf(array, Bytes.toBytes("hll")));
467   }
468   
469   public void testContains() {
470     byte[] array = Bytes.toBytes("hello world");
471     assertTrue(Bytes.contains(array, (byte) 'e'));
472     assertTrue(Bytes.contains(array, (byte) 'd'));
473     assertFalse( Bytes.contains(array, (byte) 'a'));
474     assertTrue(Bytes.contains(array, Bytes.toBytes("world")));
475     assertTrue(Bytes.contains(array, Bytes.toBytes("ello")));
476     assertFalse(Bytes.contains(array, Bytes.toBytes("owo")));
477   }
478   
479   public void testZero() {
480     byte[] array = Bytes.toBytes("hello");
481     Bytes.zero(array);
482     for (int i = 0; i < array.length; i++) {
483       assertEquals(0, array[i]);
484     }
485     array = Bytes.toBytes("hello world");
486     Bytes.zero(array, 2, 7);
487     assertFalse(array[0] == 0);
488     assertFalse(array[1] == 0);
489     for (int i = 2; i < 9; i++) {
490       assertEquals(0, array[i]);
491     }
492     for (int i = 9; i < array.length; i++) {
493       assertFalse(array[i] == 0);
494     }
495   }
496 
497   public void testPutBuffer() {
498     byte[] b = new byte[100];
499     for (byte i = 0; i < 100; i++) {
500       Bytes.putByteBuffer(b, i, ByteBuffer.wrap(new byte[]{i}));
501     }
502     for (byte i = 0; i < 100; i++) {
503       Assert.assertEquals(i, b[i]);
504     }
505   }
506   
507   public void testToFromHex() {
508     List<String> testStrings = new ArrayList<String>();
509     testStrings.addAll(Arrays.asList(new String[] {
510         "",
511         "00",
512         "A0",
513         "ff",
514         "FFffFFFFFFFFFF",
515         "12",
516         "0123456789abcdef",
517         "283462839463924623984692834692346ABCDFEDDCA0",
518       }));
519     for (String testString : testStrings)
520     {
521       byte[] byteData = Bytes.fromHex(testString);
522       Assert.assertEquals(testString.length() / 2, byteData.length);
523       String result = Bytes.toHex(byteData);
524       Assert.assertTrue(testString.equalsIgnoreCase(result));
525     }
526     
527     List<byte[]> testByteData = new ArrayList<byte[]>();
528     testByteData.addAll(Arrays.asList(new byte[][] {
529       new byte[0],
530       new byte[1],
531       new byte[10],
532       new byte[] {1, 2, 3, 4, 5},
533       new byte[] {(byte) 0xFF},
534     }));
535     Random r = new Random();
536     for (int i = 0; i < 20; i++)
537     {
538       
539       byte[] bytes = new byte[r.nextInt(100)];
540       r.nextBytes(bytes);
541       testByteData.add(bytes);
542     }
543     
544     for (byte[] testData : testByteData)
545     {
546       String hexString = Bytes.toHex(testData);
547       Assert.assertEquals(testData.length * 2, hexString.length());
548       byte[] result = Bytes.fromHex(hexString);
549       Assert.assertArrayEquals(testData, result);
550     }
551   }
552 }
553