1   /**
2    * Copyright 2009 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.util;
21  
22  import java.io.IOException;
23  import java.util.Arrays;
24  
25  import junit.framework.TestCase;
26  
27  public class TestBytes extends TestCase {
28    public void testNullHashCode() {
29      byte [] b = null;
30      Exception ee = null;
31      try {
32        Bytes.hashCode(b);
33      } catch (Exception e) {
34        ee = e;
35      }
36      assertNotNull(ee);
37    }
38  
39    public void testSplit() throws Exception {
40      byte [] lowest = Bytes.toBytes("AAA");
41      byte [] middle = Bytes.toBytes("CCC");
42      byte [] highest = Bytes.toBytes("EEE");
43      byte [][] parts = Bytes.split(lowest, highest, 1);
44      for (int i = 0; i < parts.length; i++) {
45        System.out.println(Bytes.toString(parts[i]));
46      }
47      assertEquals(3, parts.length);
48      assertTrue(Bytes.equals(parts[1], middle));
49      // Now divide into three parts.  Change highest so split is even.
50      highest = Bytes.toBytes("DDD");
51      parts = Bytes.split(lowest, highest, 2);
52      for (int i = 0; i < parts.length; i++) {
53        System.out.println(Bytes.toString(parts[i]));
54      }
55      assertEquals(4, parts.length);
56      // Assert that 3rd part is 'CCC'.
57      assertTrue(Bytes.equals(parts[2], middle));
58    }
59  
60    public void testSplit2() throws Exception {
61      // More split tests.
62      byte [] lowest = Bytes.toBytes("http://A");
63      byte [] highest = Bytes.toBytes("http://z");
64      byte [] middle = Bytes.toBytes("http://]");
65      byte [][] parts = Bytes.split(lowest, highest, 1);
66      for (int i = 0; i < parts.length; i++) {
67        System.out.println(Bytes.toString(parts[i]));
68      }
69      assertEquals(3, parts.length);
70      assertTrue(Bytes.equals(parts[1], middle));
71    }
72  
73    public void testSplit3() throws Exception {
74      // Test invalid split cases
75      byte [] low = { 1, 1, 1 };
76      byte [] high = { 1, 1, 3 };
77  
78      // If swapped, should throw IAE
79      try {
80        Bytes.split(high, low, 1);
81        assertTrue("Should not be able to split if low > high", false);
82      } catch(IllegalArgumentException iae) {
83        // Correct
84      }
85  
86      // Single split should work
87      byte [][] parts = Bytes.split(low, high, 1);
88      for (int i = 0; i < parts.length; i++) {
89        System.out.println("" + i + " -> " + Bytes.toStringBinary(parts[i]));
90      }
91      assertTrue("Returned split should have 3 parts but has " + parts.length, parts.length == 3);
92  
93      // If split more than once, this should fail
94      parts = Bytes.split(low, high, 2);
95      assertTrue("Returned split but should have failed", parts == null);
96  
97      // Split 0 times should throw IAE
98      try {
99        parts = Bytes.split(low, high, 0);
100       assertTrue("Should not be able to split 0 times", false);
101     } catch(IllegalArgumentException iae) {
102       // Correct
103     }
104   }
105 
106   public void testToLong() throws Exception {
107     long [] longs = {-1l, 123l, 122232323232l};
108     for (int i = 0; i < longs.length; i++) {
109       byte [] b = Bytes.toBytes(longs[i]);
110       assertEquals(longs[i], Bytes.toLong(b));
111     }
112   }
113 
114   public void testToFloat() throws Exception {
115     float [] floats = {-1f, 123.123f, Float.MAX_VALUE};
116     for (int i = 0; i < floats.length; i++) {
117       byte [] b = Bytes.toBytes(floats[i]);
118       assertEquals(floats[i], Bytes.toFloat(b));
119     }
120   }
121 
122   public void testToDouble() throws Exception {
123     double [] doubles = {Double.MIN_VALUE, Double.MAX_VALUE};
124     for (int i = 0; i < doubles.length; i++) {
125       byte [] b = Bytes.toBytes(doubles[i]);
126       assertEquals(doubles[i], Bytes.toDouble(b));
127     }
128   }
129 
130   public void testBinarySearch() throws Exception {
131     byte [][] arr = {
132         {1},
133         {3},
134         {5},
135         {7},
136         {9},
137         {11},
138         {13},
139         {15},
140     };
141     byte [] key1 = {3,1};
142     byte [] key2 = {4,9};
143     byte [] key2_2 = {4};
144     byte [] key3 = {5,11};
145 
146     assertEquals(1, Bytes.binarySearch(arr, key1, 0, 1,
147       Bytes.BYTES_RAWCOMPARATOR));
148     assertEquals(0, Bytes.binarySearch(arr, key1, 1, 1,
149       Bytes.BYTES_RAWCOMPARATOR));
150     assertEquals(-(2+1), Arrays.binarySearch(arr, key2_2,
151       Bytes.BYTES_COMPARATOR));
152     assertEquals(-(2+1), Bytes.binarySearch(arr, key2, 0, 1,
153       Bytes.BYTES_RAWCOMPARATOR));
154     assertEquals(4, Bytes.binarySearch(arr, key2, 1, 1,
155       Bytes.BYTES_RAWCOMPARATOR));
156     assertEquals(2, Bytes.binarySearch(arr, key3, 0, 1,
157       Bytes.BYTES_RAWCOMPARATOR));
158     assertEquals(5, Bytes.binarySearch(arr, key3, 1, 1,
159       Bytes.BYTES_RAWCOMPARATOR));
160   }
161   
162   public void testStartsWith() {
163     assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("h")));
164     assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("")));
165     assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("hello")));
166     assertFalse(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("helloworld")));
167     assertFalse(Bytes.startsWith(Bytes.toBytes(""), Bytes.toBytes("hello")));
168   }
169 
170   public void testIncrementBytes() throws IOException {
171 
172     assertTrue(checkTestIncrementBytes(10, 1));
173     assertTrue(checkTestIncrementBytes(12, 123435445));
174     assertTrue(checkTestIncrementBytes(124634654, 1));
175     assertTrue(checkTestIncrementBytes(10005460, 5005645));
176     assertTrue(checkTestIncrementBytes(1, -1));
177     assertTrue(checkTestIncrementBytes(10, -1));
178     assertTrue(checkTestIncrementBytes(10, -5));
179     assertTrue(checkTestIncrementBytes(1005435000, -5));
180     assertTrue(checkTestIncrementBytes(10, -43657655));
181     assertTrue(checkTestIncrementBytes(-1, 1));
182     assertTrue(checkTestIncrementBytes(-26, 5034520));
183     assertTrue(checkTestIncrementBytes(-10657200, 5));
184     assertTrue(checkTestIncrementBytes(-12343250, 45376475));
185     assertTrue(checkTestIncrementBytes(-10, -5));
186     assertTrue(checkTestIncrementBytes(-12343250, -5));
187     assertTrue(checkTestIncrementBytes(-12, -34565445));
188     assertTrue(checkTestIncrementBytes(-1546543452, -34565445));
189   }
190 
191   private static boolean checkTestIncrementBytes(long val, long amount)
192   throws IOException {
193     byte[] value = Bytes.toBytes(val);
194     byte [] testValue = {-1, -1, -1, -1, -1, -1, -1, -1};
195     if (value[0] > 0) {
196       testValue = new byte[Bytes.SIZEOF_LONG];
197     }
198     System.arraycopy(value, 0, testValue, testValue.length - value.length,
199         value.length);
200 
201     long incrementResult = Bytes.toLong(Bytes.incrementBytes(value, amount));
202 
203     return (Bytes.toLong(testValue) + amount) == incrementResult;
204   }
205 }