/* * 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.beam.sdk.io.range; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests of {@link ByteKey}. */ @RunWith(JUnit4.class) public class ByteKeyTest { /* A big list of byte[] keys, in ascending sorted order. */ static final ByteKey[] TEST_KEYS = new ByteKey[] { ByteKey.EMPTY, ByteKey.of(0), ByteKey.of(0, 1), ByteKey.of(0, 1, 1), ByteKey.of(0, 1, 2), ByteKey.of(0, 1, 2, 0xfe), ByteKey.of(0, 1, 3, 0xfe), ByteKey.of(0, 0xfe, 0xfe, 0xfe), ByteKey.of(0, 0xfe, 0xfe, 0xff), ByteKey.of(0, 0xfe, 0xff, 0), ByteKey.of(0, 0xff, 0xff, 0), ByteKey.of(0, 0xff, 0xff, 1), ByteKey.of(0, 0xff, 0xff, 0xfe), ByteKey.of(0, 0xff, 0xff, 0xff), ByteKey.of(1), ByteKey.of(1, 2), ByteKey.of(1, 2, 3), ByteKey.of(3), ByteKey.of(0xdd), ByteKey.of(0xfe), ByteKey.of(0xfe, 0xfe), ByteKey.of(0xfe, 0xff), ByteKey.of(0xff), ByteKey.of(0xff, 0), ByteKey.of(0xff, 0xfe), ByteKey.of(0xff, 0xff), ByteKey.of(0xff, 0xff, 0xff), ByteKey.of(0xff, 0xff, 0xff, 0xff), }; /** * Tests {@link ByteKey#compareTo(ByteKey)} using exhaustive testing within a large sorted list * of keys. */ @Test public void testCompareToExhaustive() { // Verify that the comparison gives the correct result for all values in both directions. for (int i = 0; i < TEST_KEYS.length; ++i) { for (int j = 0; j < TEST_KEYS.length; ++j) { ByteKey left = TEST_KEYS[i]; ByteKey right = TEST_KEYS[j]; int cmp = left.compareTo(right); if (i < j && !(cmp < 0)) { fail( String.format( "Expected that cmp(%s, %s) < 0, got %d [i=%d, j=%d]", left, right, cmp, i, j)); } else if (i == j && !(cmp == 0)) { fail( String.format( "Expected that cmp(%s, %s) == 0, got %d [i=%d, j=%d]", left, right, cmp, i, j)); } else if (i > j && !(cmp > 0)) { fail( String.format( "Expected that cmp(%s, %s) > 0, got %d [i=%d, j=%d]", left, right, cmp, i, j)); } } } } /** * Tests {@link ByteKey#equals}. */ @Test public void testEquals() { // Verify that the comparison gives the correct result for all values in both directions. for (int i = 0; i < TEST_KEYS.length; ++i) { for (int j = 0; j < TEST_KEYS.length; ++j) { ByteKey left = TEST_KEYS[i]; ByteKey right = TEST_KEYS[j]; boolean eq = left.equals(right); if (i == j) { assertTrue(String.format("Expected that %s is equal to itself.", left), eq); assertTrue( String.format("Expected that %s is equal to a copy of itself.", left), left.equals(ByteKey.copyFrom(right.getValue()))); } else { assertFalse(String.format("Expected that %s is not equal to %s", left, right), eq); } } } } /** * Tests {@link ByteKey#hashCode}. */ @Test public void testHashCode() { // Verify that the hashCode is equal when i==j, and usually not equal otherwise. int collisions = 0; for (int i = 0; i < TEST_KEYS.length; ++i) { int left = TEST_KEYS[i].hashCode(); int leftClone = ByteKey.copyFrom(TEST_KEYS[i].getValue()).hashCode(); assertEquals( String.format("Expected same hash code for %s and a copy of itself", TEST_KEYS[i]), left, leftClone); for (int j = i + 1; j < TEST_KEYS.length; ++j) { int right = TEST_KEYS[j].hashCode(); if (left == right) { ++collisions; } } } int totalUnequalTests = TEST_KEYS.length * (TEST_KEYS.length - 1) / 2; assertThat("Too many hash collisions", collisions, lessThan(totalUnequalTests / 2)); } /** * Tests {@link ByteKey#toString}. */ @Test public void testToString() { assertEquals("[]", ByteKey.EMPTY.toString()); assertEquals("[00]", ByteKey.of(0).toString()); assertEquals("[0000]", ByteKey.of(0x00, 0x00).toString()); assertEquals( "[0123456789abcdef]", ByteKey.of(0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef).toString()); } /** * Tests {@link ByteKey#isEmpty}. */ @Test public void testIsEmpty() { assertTrue("[] is empty", ByteKey.EMPTY.isEmpty()); assertFalse("[00]", ByteKey.of(0).isEmpty()); } /** * Tests {@link ByteKey#getBytes}. */ @Test public void testGetBytes() { assertTrue("[] equal after getBytes", Arrays.equals(new byte[] {}, ByteKey.EMPTY.getBytes())); assertTrue( "[00] equal after getBytes", Arrays.equals(new byte[] {0x00}, ByteKey.of(0x00).getBytes())); } }