/* * Copyright 2013 Jan Van Besien * * Licensed 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 com.googlecode.ipv6; import org.junit.Test; import java.math.BigInteger; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Random; import static com.googlecode.ipv6.IPv6Address.fromInetAddress; import static com.googlecode.ipv6.IPv6Address.fromString; import static org.junit.Assert.*; /** * @author Jan Van Besien */ public class IPv6AddressTest { @Test public void parseFromAllZeroes() { assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); } @Test public void parseFromAllZeroesShortNotation() { assertEquals("::", fromString("::").toString()); } @Test public void parseSomeRealAddresses() { assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); } @Test public void parseSomeRealAddressesShortNotation() { assertEquals("::1", fromString("::1").toString()); assertEquals("::1:0", fromString("::1:0").toString()); assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); assertEquals("::ffff", fromString("::ffff").toString()); assertEquals("ffff::", fromString("ffff::").toString()); assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); } @Test public void parseSomeRealAddressesFromRFC5952() { assertEquals("::", fromString("::").toString()); assertEquals("::", fromString("::0").toString()); assertEquals("1:2:3:4::", fromString("1:2:3:4::").toString()); assertEquals("::1:2:3:4", fromString("::1:2:3:4").toString()); assertEquals("1::2", fromString("1::2").toString()); assertEquals("::2", fromString("::2").toString()); assertEquals("1::", fromString("1::").toString()); assertEquals("a31:200:3abc::de4", fromString("0a31:0200:3AbC::0dE4").toString()); assertEquals("1::4:0:0:0", fromString("1:0:0:0:4:0:0:0").toString()); assertEquals("2001:db8::1", fromString("2001:db8::1").toString()); assertEquals("2001:db8::2:1", fromString("2001:db8:0:0:0:0:2:1").toString()); assertEquals("2001:db8:0:1:1:1:1:1", fromString("2001:db8:0:1:1:1:1:1").toString()); assertEquals("2001:db8::1:0:0:1", fromString("2001:db8::1:0:0:1").toString()); assertEquals("2001:0:0:1::1", fromString("2001:0:0:1:0:0:0:1").toString()); assertEquals("1:0:0:4::", fromString("1:0:0:4::").toString()); } @Test public void parseSomeRealIPv4MappedAddresses() { assertEquals("::ffff:0.0.0.1", fromString("::ffff:0.0.0.1").toString()); assertEquals("::ffff:192.168.139.50", fromString("::ffff:192.168.139.50").toString()); assertEquals("::ffff:192.168.139.50", fromString("::ffff:c0a8:8b32").toString()); } @Test public void toLongStringOnSomeRealAddresses() { assertEquals("0000:0000:0000:0000:0000:0000:0000:0000", fromString("::").toLongString()); assertEquals("0000:0000:0000:0000:0000:0000:0000:0000", fromString("::0").toLongString()); assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); } @Test(expected = IllegalArgumentException.class) public void parseInvalid_1() { fromString(":"); } @Test(expected = IllegalArgumentException.class) public void parseInvalid_2() { fromString(":a"); } @Test(expected = IllegalArgumentException.class) public void parseInvalidTooShort_1() { fromString("a:"); } @Test(expected = IllegalArgumentException.class) public void parseInvalidTooShort_2() { fromString("a:a:"); } @Test(expected = IllegalArgumentException.class) public void parseInvalidTooLong() { fromString("a:a:a:a:a:a:a:a:a:a:a:a"); } @Test public void constructFromInet6Address() throws UnknownHostException { final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); } @Test public void constructFromInet6AddressWithScopeId() throws UnknownHostException { byte[] bytes = fromString("2001:db8:85a3::8a2e:370:7334").toByteArray(); final InetAddress inetAddress = Inet6Address.getByAddress("host", bytes, 12); assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); } @Test public void convertToInet6Address() throws UnknownHostException { final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); } @Test public void constructFromByteArray() throws UnknownHostException { assertEquals("1:1:1:1:1:1:1:1", IPv6Address.fromByteArray( new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) .toString()); } @Test public void convertToByteArray() throws UnknownHostException { assertArrayEquals( new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, fromString("1:1:1:1:1:1:1:1").toByteArray()); } @Test public void convertToAndFromByteArray() { final int nTests = 10000; final Random rg = new Random(); for (int i = 0; i < nTests; i++) { byte[] randomBytes = new byte[16]; rg.nextBytes(randomBytes); final IPv6Address address = IPv6Address.fromByteArray(randomBytes); assertArrayEquals(randomBytes, address.toByteArray()); } } @Test public void convertToBigInteger() throws UnknownHostException { assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE), IPv6Address.MAX.toBigInteger()); assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.valueOf(16)), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0").toBigInteger()); } @Test public void convertToAndFromBigInteger() { final int nTests = 10000; final Random rg = new Random(); for (int i = 0; i < nTests; i++) { byte[] randomBytes = new byte[16]; rg.nextBytes(randomBytes); BigInteger randomBigInteger = new BigInteger(1, randomBytes); final IPv6Address address = IPv6Address.fromBigInteger(randomBigInteger); assertEquals(randomBigInteger, address.toBigInteger()); } } @Test public void positionOfLongestRunOfZeroes() { assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); } @Test public void toStringCompactsLongestRunOfZeroes() { assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 } @Test public void toStringCanBeUsedInFromStringAndViceVersa() { final int nTests = 10000; final Random rg = new Random(); for (int i = 0; i < nTests; i++) { final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); assertEquals(address, fromString(address.toString())); } } @Test public void addition() { assertEquals(fromString("::2"), fromString("::1").add(1)); assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( Integer.MAX_VALUE)); } @Test public void additionOverflow() { assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); } @Test public void subtraction() { assertEquals(fromString("::1"), fromString("::2").subtract(1)); assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); } @Test public void subtractionVersusAdditionWithRandomAddresses() { final Random random = new Random(); final int randomInt = random.nextInt(); final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); } @Test public void subtractionVersusAdditionCornerCases() { final Random random = new Random(); final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); } @Test public void subtractionUnderflow() { assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); } @Test public void setBit() { assertEquals(fromString("::1"), fromString("::").setBit(0)); assertEquals(fromString("::2"), fromString("::").setBit(1)); assertEquals(fromString("::3"), fromString("::").setBit(0).setBit(1)); assertEquals(fromString("0:0:0:1::"), fromString("::").setBit(64)); assertEquals(fromString("0:0:0:2::"), fromString("::").setBit(65)); assertEquals(fromString("8000::"), fromString("::").setBit(127)); } @Test public void compare() { assertTrue(0 == fromString("::").compareTo(fromString("::"))); assertTrue(0 > fromString("::").compareTo(fromString("::1"))); assertTrue(0 < fromString("::1").compareTo(fromString("::"))); assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); } @Test public void maskWithPrefixLength() { assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); assertEquals(fromString("2001:0db8:85a3::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); assertEquals(fromString("2000::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); assertEquals(fromString("8000::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); } @Test public void maximumAddressWithPrefixLength() { assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); } @Test public void numberOfTrailingOnes() { assertEquals(0, fromString("::").numberOfTrailingOnes()); assertEquals(1, fromString("::1").numberOfTrailingOnes()); assertEquals(4, fromString("::f").numberOfTrailingOnes()); final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); } @Test public void numberOfLeadingOnes() { assertEquals(0, fromString("::").numberOfLeadingOnes()); assertEquals(1, fromString("8000::").numberOfLeadingOnes()); assertEquals(4, fromString("f000::").numberOfLeadingOnes()); assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); } @Test public void numberOfTrailingZeroes() { assertEquals(128, fromString("::").numberOfTrailingZeroes()); assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); } @Test public void numberOfLeadingZeroes() { assertEquals(128, fromString("::").numberOfLeadingZeroes()); assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); assertEquals(124, fromString("::f").numberOfLeadingZeroes()); assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); } @Test public void isIPv4Mapped() { assertFalse(fromString("::").isIPv4Mapped()); assertFalse(fromString("::0001:ffff:1234:5678").isIPv4Mapped()); assertFalse(fromString("1::ffff:1234:5678").isIPv4Mapped()); assertFalse(fromString("::afff:1234:5678").isIPv4Mapped()); assertTrue(fromString("::ffff:1234:5678").isIPv4Mapped()); assertTrue(fromString("::ffff:192.168.123.123").isIPv4Mapped()); } @Test public void isMulticast() { assertFalse(fromString("::").isMulticast()); assertTrue(fromString("ff12::ffff:1234:5678").isMulticast()); } @Test public void isLinkLocal() { assertFalse(fromString("::").isLinkLocal()); assertTrue(fromString("fe80::ffff:1234:5678").isLinkLocal()); } @Test public void isSiteLocal() { assertFalse(fromString("::").isSiteLocal()); assertTrue(fromString("fec0::ffff:1234:5678").isSiteLocal()); } }