|
@@ -0,0 +1,183 @@
|
|
|
+/**
|
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one
|
|
|
+ * or more contributor license agreements. See the NOTICE file
|
|
|
+ * distributed with this work for additional information
|
|
|
+ * regarding copyright ownership. The ASF licenses this file
|
|
|
+ * to you under the Apache License, Version 2.0 (the
|
|
|
+ * "License"); you may not use this file except in compliance
|
|
|
+ * with the License. You may obtain a copy of the License at
|
|
|
+ *
|
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+ *
|
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+ * See the License for the specific language governing permissions and
|
|
|
+ * limitations under the License.
|
|
|
+ */
|
|
|
+package org.apache.hadoop.fs;
|
|
|
+
|
|
|
+import org.junit.Test;
|
|
|
+import static org.junit.Assert.*;
|
|
|
+
|
|
|
+public class TestVolumeId {
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testEquality() {
|
|
|
+ final VolumeId id1 = new HdfsVolumeId(new byte[] { (byte)0, (byte)0 });
|
|
|
+ testEq(true, id1, id1);
|
|
|
+
|
|
|
+ final VolumeId id2 = new HdfsVolumeId(new byte[] { (byte)0, (byte)1 });
|
|
|
+ testEq(true, id2, id2);
|
|
|
+ testEq(false, id1, id2);
|
|
|
+
|
|
|
+ final VolumeId id3 = new HdfsVolumeId(new byte[] { (byte)1, (byte)0 });
|
|
|
+ testEq(true, id3, id3);
|
|
|
+ testEq(false, id1, id3);
|
|
|
+
|
|
|
+ // same as 2, but "invalid":
|
|
|
+ final VolumeId id2copy1 = new HdfsVolumeId(new byte[] { (byte)0, (byte)1 });
|
|
|
+
|
|
|
+ testEq(true, id2, id2copy1);
|
|
|
+
|
|
|
+ // same as 2copy1:
|
|
|
+ final VolumeId id2copy2 = new HdfsVolumeId(new byte[] { (byte)0, (byte)1 });
|
|
|
+
|
|
|
+ testEq(true, id2, id2copy2);
|
|
|
+
|
|
|
+ testEqMany(true, new VolumeId[] { id2, id2copy1, id2copy2 });
|
|
|
+
|
|
|
+ testEqMany(false, new VolumeId[] { id1, id2, id3 });
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private <T> void testEq(final boolean eq, Comparable<? super T> id1, Comparable<? super T> id2) {
|
|
|
+ final int h1 = id1.hashCode();
|
|
|
+ final int h2 = id2.hashCode();
|
|
|
+
|
|
|
+ // eq reflectivity:
|
|
|
+ assertTrue(id1.equals(id1));
|
|
|
+ assertTrue(id2.equals(id2));
|
|
|
+ assertEquals(0, id1.compareTo((T)id1));
|
|
|
+ assertEquals(0, id2.compareTo((T)id2));
|
|
|
+
|
|
|
+ // eq symmetry:
|
|
|
+ assertEquals(eq, id1.equals(id2));
|
|
|
+ assertEquals(eq, id2.equals(id1));
|
|
|
+
|
|
|
+ // null comparison:
|
|
|
+ assertFalse(id1.equals(null));
|
|
|
+ assertFalse(id2.equals(null));
|
|
|
+
|
|
|
+ // compareTo:
|
|
|
+ assertEquals(eq, 0 == id1.compareTo((T)id2));
|
|
|
+ assertEquals(eq, 0 == id2.compareTo((T)id1));
|
|
|
+ // compareTo must be antisymmetric:
|
|
|
+ assertEquals(sign(id1.compareTo((T)id2)), -sign(id2.compareTo((T)id1)));
|
|
|
+
|
|
|
+ // compare with null should never return 0 to be consistent with #equals():
|
|
|
+ assertTrue(id1.compareTo(null) != 0);
|
|
|
+ assertTrue(id2.compareTo(null) != 0);
|
|
|
+
|
|
|
+ // check that hash codes did not change:
|
|
|
+ assertEquals(h1, id1.hashCode());
|
|
|
+ assertEquals(h2, id2.hashCode());
|
|
|
+ if (eq) {
|
|
|
+ // in this case the hash codes must be the same:
|
|
|
+ assertEquals(h1, h2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int sign(int x) {
|
|
|
+ if (x == 0) {
|
|
|
+ return 0;
|
|
|
+ } else if (x > 0) {
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private <T> void testEqMany(final boolean eq, Comparable<? super T>... volumeIds) {
|
|
|
+ Comparable<? super T> vidNext;
|
|
|
+ int sum = 0;
|
|
|
+ for (int i=0; i<volumeIds.length; i++) {
|
|
|
+ if (i == volumeIds.length - 1) {
|
|
|
+ vidNext = volumeIds[0];
|
|
|
+ } else {
|
|
|
+ vidNext = volumeIds[i + 1];
|
|
|
+ }
|
|
|
+ testEq(eq, volumeIds[i], vidNext);
|
|
|
+ sum += sign(volumeIds[i].compareTo((T)vidNext));
|
|
|
+ }
|
|
|
+ // the comparison relationship must always be acyclic:
|
|
|
+ assertTrue(sum < volumeIds.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Test HdfsVolumeId(new byte[0]) instances: show that we permit such
|
|
|
+ * objects, they are still valid, and obey the same equality
|
|
|
+ * rules other objects do.
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void testIdEmptyBytes() {
|
|
|
+ final VolumeId idEmpty1 = new HdfsVolumeId(new byte[0]);
|
|
|
+ assertTrue(idEmpty1.isValid());
|
|
|
+ final VolumeId idEmpty2 = new HdfsVolumeId(new byte[0]);
|
|
|
+ assertTrue(idEmpty2.isValid());
|
|
|
+ final VolumeId idNotEmpty = new HdfsVolumeId(new byte[] { (byte)1 });
|
|
|
+ assertTrue(idNotEmpty.isValid());
|
|
|
+
|
|
|
+ testEq(true, idEmpty1, idEmpty2);
|
|
|
+ testEq(false, idEmpty1, idNotEmpty);
|
|
|
+ testEq(false, idEmpty2, idNotEmpty);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Test the VolumeId.INVALID_VOLUME_ID singleton.
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void testInvalidId() {
|
|
|
+ try {
|
|
|
+ new HdfsVolumeId(null);
|
|
|
+ assertTrue("NPE expected.", false);
|
|
|
+ } catch (NullPointerException npe) {
|
|
|
+ // okay
|
|
|
+ }
|
|
|
+ final VolumeId idEmpty = new HdfsVolumeId(new byte[] {});
|
|
|
+ final VolumeId idNotEmpty = new HdfsVolumeId(new byte[] { (byte)1 });
|
|
|
+
|
|
|
+ testEq(false, VolumeId.INVALID_VOLUME_ID, idNotEmpty);
|
|
|
+ testEq(false, VolumeId.INVALID_VOLUME_ID, idEmpty);
|
|
|
+
|
|
|
+ testEqMany(true,
|
|
|
+ new VolumeId[] {
|
|
|
+ VolumeId.INVALID_VOLUME_ID,
|
|
|
+ VolumeId.INVALID_VOLUME_ID,
|
|
|
+ VolumeId.INVALID_VOLUME_ID } );
|
|
|
+ testEqMany(false,
|
|
|
+ new VolumeId[] {
|
|
|
+ VolumeId.INVALID_VOLUME_ID,
|
|
|
+ idEmpty,
|
|
|
+ idNotEmpty });
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * test #toString() for typical VolumeId equality classes
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void testToString() {
|
|
|
+ // The #toString() return value is only checked for != null.
|
|
|
+ // We cannot assert more.
|
|
|
+ String strInvalid = VolumeId.INVALID_VOLUME_ID.toString();
|
|
|
+ assertNotNull(strInvalid);
|
|
|
+
|
|
|
+ String strEmpty = new HdfsVolumeId(new byte[] {}).toString();
|
|
|
+ assertNotNull(strEmpty);
|
|
|
+
|
|
|
+ String strNotEmpty = new HdfsVolumeId(new byte[] { (byte)1 }).toString();
|
|
|
+ assertNotNull(strNotEmpty);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|