Add convenience methods to IpPrefix and LinkAddress
Also moving relevant test files into tests/net as part of runtest
framworks-net.
Also removes testHashCode in LinkAddress() because this test relies on
the assumption that hashCode() is stable across releases or jdk
versions, which is absolutely not true.
This creates maintenance work for little benefit since hashCode is
already tested as part of the equality test.
For instance this test is now broken because hashing for InetAddress
changed.
Bug: 62988545
Bug: 62918393
Test: runtest frameworks-net, added coverage in tests
Change-Id: I695bc3f0e801bf13bc4fc0706565758f12b775b4
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
index 6b4f2d5..6e2654e 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/core/java/android/net/IpPrefix.java
@@ -20,6 +20,8 @@
import android.os.Parcelable;
import android.util.Pair;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
@@ -185,6 +187,20 @@
}
/**
+ * @hide
+ */
+ public boolean isIPv6() {
+ return getAddress() instanceof Inet6Address;
+ }
+
+ /**
+ * @hide
+ */
+ public boolean isIPv4() {
+ return getAddress() instanceof Inet4Address;
+ }
+
+ /**
* Returns a string representation of this {@code IpPrefix}.
*
* @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}.
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index 62de991..bcfe938 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -76,7 +76,7 @@
* RFC 6724 section 3.2.
* @hide
*/
- static int scopeForUnicastAddress(InetAddress addr) {
+ private static int scopeForUnicastAddress(InetAddress addr) {
if (addr.isAnyLocalAddress()) {
return RT_SCOPE_HOST;
}
@@ -101,7 +101,7 @@
* Per RFC 4193 section 8, fc00::/7 identifies these addresses.
*/
private boolean isIPv6ULA() {
- if (address instanceof Inet6Address) {
+ if (isIPv6()) {
byte[] bytes = address.getAddress();
return ((bytes[0] & (byte)0xfe) == (byte)0xfc);
}
@@ -109,13 +109,29 @@
}
/**
+ * @return true if the address is IPv6.
+ * @hide
+ */
+ public boolean isIPv6() {
+ return address instanceof Inet6Address;
+ }
+
+ /**
+ * @return true if the address is IPv4 or is a mapped IPv4 address.
+ * @hide
+ */
+ public boolean isIPv4() {
+ return address instanceof Inet4Address;
+ }
+
+ /**
* Utility function for the constructors.
*/
private void init(InetAddress address, int prefixLength, int flags, int scope) {
if (address == null ||
address.isMulticastAddress() ||
prefixLength < 0 ||
- ((address instanceof Inet4Address) && prefixLength > 32) ||
+ (address instanceof Inet4Address && prefixLength > 32) ||
(prefixLength > 128)) {
throw new IllegalArgumentException("Bad LinkAddress params " + address +
"/" + prefixLength);
@@ -184,6 +200,7 @@
*/
public LinkAddress(String address, int flags, int scope) {
// This may throw an IllegalArgumentException; catching it is the caller's responsibility.
+ // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24".
Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address);
init(ipAndMask.first, ipAndMask.second, flags, scope);
}
diff --git a/core/tests/coretests/src/android/net/IpPrefixTest.java b/tests/net/java/android/net/IpPrefixTest.java
similarity index 93%
rename from core/tests/coretests/src/android/net/IpPrefixTest.java
rename to tests/net/java/android/net/IpPrefixTest.java
index 4f2387d..b5b2c07 100644
--- a/core/tests/coretests/src/android/net/IpPrefixTest.java
+++ b/tests/net/java/android/net/IpPrefixTest.java
@@ -16,18 +16,27 @@
package android.net;
-import android.net.IpPrefix;
-import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-import java.net.InetAddress;
-import java.util.Random;
-import junit.framework.TestCase;
-
-import static android.test.MoreAsserts.assertNotEqual;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-public class IpPrefixTest extends TestCase {
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.net.InetAddress;
+import java.util.Random;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpPrefixTest {
private static InetAddress Address(String addr) {
return InetAddress.parseNumericAddress(addr);
@@ -42,7 +51,7 @@
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xa0
};
- @SmallTest
+ @Test
public void testConstructor() {
IpPrefix p;
try {
@@ -103,6 +112,7 @@
} catch(IllegalArgumentException expected) {}
}
+ @Test
public void testTruncation() {
IpPrefix p;
@@ -170,7 +180,7 @@
assertFalse(o2.equals(o1));
}
- @SmallTest
+ @Test
public void testEquals() {
IpPrefix p1, p2;
@@ -212,7 +222,7 @@
assertAreNotEqual(p1, p2);
}
- @SmallTest
+ @Test
public void testContains() {
IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127");
assertTrue(p.contains(Address("2001:db8:f00::ace:d00c")));
@@ -240,7 +250,7 @@
assertFalse(ipv4Default.contains(Address("2001:db8::f00")));
}
- @SmallTest
+ @Test
public void testHashCode() {
IpPrefix p = new IpPrefix(new byte[4], 0);
Random random = new Random();
@@ -261,12 +271,12 @@
assertEquals(p.hashCode(), oldP.hashCode());
}
if (p.hashCode() != oldP.hashCode()) {
- assertNotEqual(p, oldP);
+ assertNotEquals(p, oldP);
}
}
}
- @SmallTest
+ @Test
public void testHashCodeIsNotConstant() {
IpPrefix[] prefixes = {
new IpPrefix("2001:db8:f00::ace:d00d/127"),
@@ -276,12 +286,12 @@
};
for (int i = 0; i < prefixes.length; i++) {
for (int j = i + 1; j < prefixes.length; j++) {
- assertNotEqual(prefixes[i].hashCode(), prefixes[j].hashCode());
+ assertNotEquals(prefixes[i].hashCode(), prefixes[j].hashCode());
}
}
}
- @SmallTest
+ @Test
public void testMappedAddressesAreBroken() {
// 192.0.2.0/24 != ::ffff:c000:0204/120, but because we use InetAddress,
// we are unable to comprehend that.
@@ -318,13 +328,16 @@
assertEquals(p, p2);
}
+ @Test
public void testParceling() {
IpPrefix p;
p = new IpPrefix("2001:4860:db8::/64");
assertParcelingIsLossless(p);
+ assertTrue(p.isIPv6());
p = new IpPrefix("192.0.2.0/25");
assertParcelingIsLossless(p);
+ assertTrue(p.isIPv4());
}
}
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/tests/net/java/android/net/LinkAddressTest.java
similarity index 91%
rename from core/tests/coretests/src/android/net/LinkAddressTest.java
rename to tests/net/java/android/net/LinkAddressTest.java
index adf8d95..c1ad946 100644
--- a/core/tests/coretests/src/android/net/LinkAddressTest.java
+++ b/tests/net/java/android/net/LinkAddressTest.java
@@ -16,6 +16,23 @@
package android.net;
+import static android.system.OsConstants.IFA_F_DADFAILED;
+import static android.system.OsConstants.IFA_F_DEPRECATED;
+import static android.system.OsConstants.IFA_F_OPTIMISTIC;
+import static android.system.OsConstants.IFA_F_PERMANENT;
+import static android.system.OsConstants.IFA_F_TEMPORARY;
+import static android.system.OsConstants.IFA_F_TENTATIVE;
+import static android.system.OsConstants.RT_SCOPE_HOST;
+import static android.system.OsConstants.RT_SCOPE_LINK;
+import static android.system.OsConstants.RT_SCOPE_SITE;
+import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -27,44 +44,35 @@
import java.util.Comparator;
import java.util.List;
-import android.net.LinkAddress;
import android.os.Parcel;
-import android.test.AndroidTestCase;
-import static android.test.MoreAsserts.assertNotEqual;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
-import static android.system.OsConstants.IFA_F_DADFAILED;
-import static android.system.OsConstants.IFA_F_DEPRECATED;
-import static android.system.OsConstants.IFA_F_OPTIMISTIC;
-import static android.system.OsConstants.IFA_F_PERMANENT;
-import static android.system.OsConstants.IFA_F_TEMPORARY;
-import static android.system.OsConstants.IFA_F_TENTATIVE;
-import static android.system.OsConstants.RT_SCOPE_HOST;
-import static android.system.OsConstants.RT_SCOPE_LINK;
-import static android.system.OsConstants.RT_SCOPE_SITE;
-import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
+import org.junit.runner.RunWith;
+import org.junit.Test;
-/**
- * Tests for {@link LinkAddress}.
- */
-public class LinkAddressTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LinkAddressTest {
private static final String V4 = "192.0.2.1";
private static final String V6 = "2001:db8::1";
private static final InetAddress V4_ADDRESS = NetworkUtils.numericToInetAddress(V4);
private static final InetAddress V6_ADDRESS = NetworkUtils.numericToInetAddress(V6);
+ @Test
public void testConstants() {
// RT_SCOPE_UNIVERSE = 0, but all the other constants should be nonzero.
- assertNotEqual(0, RT_SCOPE_HOST);
- assertNotEqual(0, RT_SCOPE_LINK);
- assertNotEqual(0, RT_SCOPE_SITE);
+ assertNotEquals(0, RT_SCOPE_HOST);
+ assertNotEquals(0, RT_SCOPE_LINK);
+ assertNotEquals(0, RT_SCOPE_SITE);
- assertNotEqual(0, IFA_F_DEPRECATED);
- assertNotEqual(0, IFA_F_PERMANENT);
- assertNotEqual(0, IFA_F_TENTATIVE);
+ assertNotEquals(0, IFA_F_DEPRECATED);
+ assertNotEquals(0, IFA_F_PERMANENT);
+ assertNotEquals(0, IFA_F_TENTATIVE);
}
+ @Test
public void testConstructors() throws SocketException {
LinkAddress address;
@@ -74,12 +82,14 @@
assertEquals(25, address.getPrefixLength());
assertEquals(0, address.getFlags());
assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
+ assertTrue(address.isIPv4());
address = new LinkAddress(V6_ADDRESS, 127);
assertEquals(V6_ADDRESS, address.getAddress());
assertEquals(127, address.getPrefixLength());
assertEquals(0, address.getFlags());
assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
+ assertTrue(address.isIPv6());
// Nonsensical flags/scopes or combinations thereof are acceptable.
address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK);
@@ -87,12 +97,14 @@
assertEquals(64, address.getPrefixLength());
assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags());
assertEquals(RT_SCOPE_LINK, address.getScope());
+ assertTrue(address.isIPv6());
address = new LinkAddress(V4 + "/23", 123, 456);
assertEquals(V4_ADDRESS, address.getAddress());
assertEquals(23, address.getPrefixLength());
assertEquals(123, address.getFlags());
assertEquals(456, address.getScope());
+ assertTrue(address.isIPv4());
// InterfaceAddress doesn't have a constructor. Fetch some from an interface.
List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses();
@@ -174,6 +186,7 @@
} catch(IllegalArgumentException expected) {}
}
+ @Test
public void testAddressScopes() {
assertEquals(RT_SCOPE_HOST, new LinkAddress("::/128").getScope());
assertEquals(RT_SCOPE_HOST, new LinkAddress("0.0.0.0/32").getScope());
@@ -216,6 +229,7 @@
assertFalse(l2 + " unexpectedly equal to " + l1, l2.equals(l1));
}
+ @Test
public void testEqualsAndSameAddressAs() {
LinkAddress l1, l2, l3;
@@ -293,26 +307,17 @@
assertIsSameAddressAs(l1, l2);
}
+ @Test
public void testHashCode() {
- LinkAddress l;
+ LinkAddress l1, l2;
- l = new LinkAddress(V4_ADDRESS, 23);
- assertEquals(-982787, l.hashCode());
+ l1 = new LinkAddress(V4_ADDRESS, 23);
+ l2 = new LinkAddress(V4_ADDRESS, 23, 0, RT_SCOPE_HOST);
+ assertNotEquals(l1.hashCode(), l2.hashCode());
- l = new LinkAddress(V4_ADDRESS, 23, 0, RT_SCOPE_HOST);
- assertEquals(-971865, l.hashCode());
-
- l = new LinkAddress(V4_ADDRESS, 27);
- assertEquals(-982743, l.hashCode());
-
- l = new LinkAddress(V6_ADDRESS, 64);
- assertEquals(1076522926, l.hashCode());
-
- l = new LinkAddress(V6_ADDRESS, 128);
- assertEquals(1076523630, l.hashCode());
-
- l = new LinkAddress(V6_ADDRESS, 128, IFA_F_TENTATIVE, RT_SCOPE_UNIVERSE);
- assertEquals(1076524846, l.hashCode());
+ l1 = new LinkAddress(V6_ADDRESS, 128);
+ l2 = new LinkAddress(V6_ADDRESS, 128, IFA_F_TENTATIVE, RT_SCOPE_UNIVERSE);
+ assertNotEquals(l1.hashCode(), l2.hashCode());
}
private LinkAddress passThroughParcel(LinkAddress l) {
@@ -334,6 +339,7 @@
assertEquals(l, l2);
}
+ @Test
public void testParceling() {
LinkAddress l;
@@ -352,6 +358,7 @@
assertFalse(msg, l.isGlobalPreferred());
}
+ @Test
public void testIsGlobalPreferred() {
LinkAddress l;