Add @ConnectivityModuleTest to tests for classes that are mainly used to back the connectivity (tethering) module, in particular data classes. This causes the test not to be run in NetworkStack/CaptivePortalLogin MTS tests when the connectivity (tethering) module is not installed. Skipping such tests is necessary in that configuration as they may test behavior that is new in the latest update, and data classes backing the connectivity module would not be affected by NetworkStack/CaptivePortalLogin updates anyway. Bug: 211075897 Test: atest CtsNetTestCasesLatestSdk Change-Id: I6163cd998fc78765b903fdb7acd21e652bc711c9
378 lines
14 KiB
Java
378 lines
14 KiB
Java
/*
|
|
* Copyright (C) 2014 The Android Open Source Project
|
|
*
|
|
* 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 android.net;
|
|
|
|
import static com.android.testutils.MiscAsserts.assertEqualBothWays;
|
|
import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
|
|
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
|
|
|
|
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.assertTrue;
|
|
import static org.junit.Assert.fail;
|
|
|
|
import androidx.test.filters.SmallTest;
|
|
import androidx.test.runner.AndroidJUnit4;
|
|
|
|
import com.android.testutils.ConnectivityModuleTest;
|
|
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
|
|
import java.net.InetAddress;
|
|
import java.util.Random;
|
|
|
|
@RunWith(AndroidJUnit4.class)
|
|
@SmallTest
|
|
@ConnectivityModuleTest
|
|
public class IpPrefixTest {
|
|
|
|
private static InetAddress address(String addr) {
|
|
return InetAddress.parseNumericAddress(addr);
|
|
}
|
|
|
|
// Explicitly cast everything to byte because "error: possible loss of precision".
|
|
private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4};
|
|
private static final byte[] IPV6_BYTES = {
|
|
(byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
|
|
(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
|
|
(byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00,
|
|
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xa0
|
|
};
|
|
|
|
@Test
|
|
public void testConstructor() {
|
|
IpPrefix p;
|
|
try {
|
|
p = new IpPrefix((byte[]) null, 9);
|
|
fail("Expected NullPointerException: null byte array");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix((InetAddress) null, 10);
|
|
fail("Expected NullPointerException: null InetAddress");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix((String) null);
|
|
fail("Expected NullPointerException: null String");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
|
|
try {
|
|
byte[] b2 = {1, 2, 3, 4, 5};
|
|
p = new IpPrefix(b2, 29);
|
|
fail("Expected IllegalArgumentException: invalid array length");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("1.2.3.4");
|
|
fail("Expected IllegalArgumentException: no prefix length");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("1.2.3.4/");
|
|
fail("Expected IllegalArgumentException: empty prefix length");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("foo/32");
|
|
fail("Expected IllegalArgumentException: invalid address");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("1/32");
|
|
fail("Expected IllegalArgumentException: deprecated IPv4 format");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("1.2.3.256/32");
|
|
fail("Expected IllegalArgumentException: invalid IPv4 address");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("foo/32");
|
|
fail("Expected IllegalArgumentException: non-address");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix("f00:::/32");
|
|
fail("Expected IllegalArgumentException: invalid IPv6 address");
|
|
} catch (IllegalArgumentException expected) { }
|
|
|
|
p = new IpPrefix("/64");
|
|
assertEquals("::/64", p.toString());
|
|
|
|
p = new IpPrefix("/128");
|
|
assertEquals("::1/128", p.toString());
|
|
|
|
p = new IpPrefix("[2001:db8::123]/64");
|
|
assertEquals("2001:db8::/64", p.toString());
|
|
|
|
p = new IpPrefix(InetAddresses.parseNumericAddress("::128"), 64);
|
|
assertEquals("::/64", p.toString());
|
|
}
|
|
|
|
@Test
|
|
public void testTruncation() {
|
|
IpPrefix p;
|
|
|
|
p = new IpPrefix(IPV4_BYTES, 32);
|
|
assertEquals("192.0.2.4/32", p.toString());
|
|
|
|
p = new IpPrefix(IPV4_BYTES, 29);
|
|
assertEquals("192.0.2.0/29", p.toString());
|
|
|
|
p = new IpPrefix(IPV4_BYTES, 8);
|
|
assertEquals("192.0.0.0/8", p.toString());
|
|
|
|
p = new IpPrefix(IPV4_BYTES, 0);
|
|
assertEquals("0.0.0.0/0", p.toString());
|
|
|
|
try {
|
|
p = new IpPrefix(IPV4_BYTES, 33);
|
|
fail("Expected IllegalArgumentException: invalid prefix length");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix(IPV4_BYTES, 128);
|
|
fail("Expected IllegalArgumentException: invalid prefix length");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix(IPV4_BYTES, -1);
|
|
fail("Expected IllegalArgumentException: negative prefix length");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
p = new IpPrefix(IPV6_BYTES, 128);
|
|
assertEquals("2001:db8:dead:beef:f00::a0/128", p.toString());
|
|
|
|
p = new IpPrefix(IPV6_BYTES, 122);
|
|
assertEquals("2001:db8:dead:beef:f00::80/122", p.toString());
|
|
|
|
p = new IpPrefix(IPV6_BYTES, 64);
|
|
assertEquals("2001:db8:dead:beef::/64", p.toString());
|
|
|
|
p = new IpPrefix(IPV6_BYTES, 3);
|
|
assertEquals("2000::/3", p.toString());
|
|
|
|
p = new IpPrefix(IPV6_BYTES, 0);
|
|
assertEquals("::/0", p.toString());
|
|
|
|
try {
|
|
p = new IpPrefix(IPV6_BYTES, -1);
|
|
fail("Expected IllegalArgumentException: negative prefix length");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
try {
|
|
p = new IpPrefix(IPV6_BYTES, 129);
|
|
fail("Expected IllegalArgumentException: negative prefix length");
|
|
} catch (RuntimeException expected) { }
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testEquals() {
|
|
IpPrefix p1, p2;
|
|
|
|
p1 = new IpPrefix("192.0.2.251/23");
|
|
p2 = new IpPrefix(new byte[]{(byte) 192, (byte) 0, (byte) 2, (byte) 251}, 23);
|
|
assertEqualBothWays(p1, p2);
|
|
|
|
p1 = new IpPrefix("192.0.2.5/23");
|
|
assertEqualBothWays(p1, p2);
|
|
|
|
p1 = new IpPrefix("192.0.2.5/24");
|
|
assertNotEqualEitherWay(p1, p2);
|
|
|
|
p1 = new IpPrefix("192.0.4.5/23");
|
|
assertNotEqualEitherWay(p1, p2);
|
|
|
|
|
|
p1 = new IpPrefix("2001:db8:dead:beef:f00::80/122");
|
|
p2 = new IpPrefix(IPV6_BYTES, 122);
|
|
assertEquals("2001:db8:dead:beef:f00::80/122", p2.toString());
|
|
assertEqualBothWays(p1, p2);
|
|
|
|
p1 = new IpPrefix("2001:db8:dead:beef:f00::bf/122");
|
|
assertEqualBothWays(p1, p2);
|
|
|
|
p1 = new IpPrefix("2001:db8:dead:beef:f00::8:0/123");
|
|
assertNotEqualEitherWay(p1, p2);
|
|
|
|
p1 = new IpPrefix("2001:db8:dead:beef::/122");
|
|
assertNotEqualEitherWay(p1, p2);
|
|
|
|
// 192.0.2.4/32 != c000:0204::/32.
|
|
byte[] ipv6bytes = new byte[16];
|
|
System.arraycopy(IPV4_BYTES, 0, ipv6bytes, 0, IPV4_BYTES.length);
|
|
p1 = new IpPrefix(ipv6bytes, 32);
|
|
assertEqualBothWays(p1, new IpPrefix("c000:0204::/32"));
|
|
|
|
p2 = new IpPrefix(IPV4_BYTES, 32);
|
|
assertNotEqualEitherWay(p1, p2);
|
|
}
|
|
|
|
@Test
|
|
public void testContainsInetAddress() {
|
|
IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127");
|
|
assertTrue(p.contains(address("2001:db8:f00::ace:d00c")));
|
|
assertTrue(p.contains(address("2001:db8:f00::ace:d00d")));
|
|
assertFalse(p.contains(address("2001:db8:f00::ace:d00e")));
|
|
assertFalse(p.contains(address("2001:db8:f00::bad:d00d")));
|
|
assertFalse(p.contains(address("2001:4868:4860::8888")));
|
|
assertFalse(p.contains(address("8.8.8.8")));
|
|
|
|
p = new IpPrefix("192.0.2.0/23");
|
|
assertTrue(p.contains(address("192.0.2.43")));
|
|
assertTrue(p.contains(address("192.0.3.21")));
|
|
assertFalse(p.contains(address("192.0.0.21")));
|
|
assertFalse(p.contains(address("8.8.8.8")));
|
|
assertFalse(p.contains(address("2001:4868:4860::8888")));
|
|
|
|
IpPrefix ipv6Default = new IpPrefix("::/0");
|
|
assertTrue(ipv6Default.contains(address("2001:db8::f00")));
|
|
assertFalse(ipv6Default.contains(address("192.0.2.1")));
|
|
|
|
IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0");
|
|
assertTrue(ipv4Default.contains(address("255.255.255.255")));
|
|
assertTrue(ipv4Default.contains(address("192.0.2.1")));
|
|
assertFalse(ipv4Default.contains(address("2001:db8::f00")));
|
|
}
|
|
|
|
@Test
|
|
public void testContainsIpPrefix() {
|
|
assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("0.0.0.0/0")));
|
|
assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/0")));
|
|
assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/8")));
|
|
assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/24")));
|
|
assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/23")));
|
|
|
|
assertTrue(new IpPrefix("1.2.3.4/8").containsPrefix(new IpPrefix("1.2.3.4/8")));
|
|
assertTrue(new IpPrefix("1.2.3.4/8").containsPrefix(new IpPrefix("1.254.12.9/8")));
|
|
assertTrue(new IpPrefix("1.2.3.4/21").containsPrefix(new IpPrefix("1.2.3.4/21")));
|
|
assertTrue(new IpPrefix("1.2.3.4/32").containsPrefix(new IpPrefix("1.2.3.4/32")));
|
|
|
|
assertTrue(new IpPrefix("1.2.3.4/20").containsPrefix(new IpPrefix("1.2.3.0/24")));
|
|
|
|
assertFalse(new IpPrefix("1.2.3.4/32").containsPrefix(new IpPrefix("1.2.3.5/32")));
|
|
assertFalse(new IpPrefix("1.2.3.4/8").containsPrefix(new IpPrefix("2.2.3.4/8")));
|
|
assertFalse(new IpPrefix("0.0.0.0/16").containsPrefix(new IpPrefix("0.0.0.0/15")));
|
|
assertFalse(new IpPrefix("100.0.0.0/8").containsPrefix(new IpPrefix("99.0.0.0/8")));
|
|
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("::/0")));
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/1")));
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("3d8a:661:a0::770/8")));
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/8")));
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/64")));
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/113")));
|
|
assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/128")));
|
|
|
|
assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix(
|
|
new IpPrefix("2001:db8:f00::ace:d00d/64")));
|
|
assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix(
|
|
new IpPrefix("2001:db8:f00::ace:d00d/120")));
|
|
assertFalse(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix(
|
|
new IpPrefix("2001:db8:f00::ace:d00d/32")));
|
|
assertFalse(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix(
|
|
new IpPrefix("2006:db8:f00::ace:d00d/96")));
|
|
|
|
assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/128").containsPrefix(
|
|
new IpPrefix("2001:db8:f00::ace:d00d/128")));
|
|
assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/100").containsPrefix(
|
|
new IpPrefix("2001:db8:f00::ace:ccaf/110")));
|
|
|
|
assertFalse(new IpPrefix("2001:db8:f00::ace:d00d/128").containsPrefix(
|
|
new IpPrefix("2001:db8:f00::ace:d00e/128")));
|
|
assertFalse(new IpPrefix("::/30").containsPrefix(new IpPrefix("::/29")));
|
|
}
|
|
|
|
@Test
|
|
public void testHashCode() {
|
|
IpPrefix p = new IpPrefix(new byte[4], 0);
|
|
Random random = new Random();
|
|
for (int i = 0; i < 100; i++) {
|
|
final IpPrefix oldP = p;
|
|
if (random.nextBoolean()) {
|
|
// IPv4.
|
|
byte[] b = new byte[4];
|
|
random.nextBytes(b);
|
|
p = new IpPrefix(b, random.nextInt(33));
|
|
} else {
|
|
// IPv6.
|
|
byte[] b = new byte[16];
|
|
random.nextBytes(b);
|
|
p = new IpPrefix(b, random.nextInt(129));
|
|
}
|
|
if (p.equals(oldP)) {
|
|
assertEquals(p.hashCode(), oldP.hashCode());
|
|
}
|
|
if (p.hashCode() != oldP.hashCode()) {
|
|
assertNotEquals(p, oldP);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testHashCodeIsNotConstant() {
|
|
IpPrefix[] prefixes = {
|
|
new IpPrefix("2001:db8:f00::ace:d00d/127"),
|
|
new IpPrefix("192.0.2.0/23"),
|
|
new IpPrefix("::/0"),
|
|
new IpPrefix("0.0.0.0/0"),
|
|
};
|
|
for (int i = 0; i < prefixes.length; i++) {
|
|
for (int j = i + 1; j < prefixes.length; j++) {
|
|
assertNotEquals(prefixes[i].hashCode(), prefixes[j].hashCode());
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testMappedAddressesAreBroken() {
|
|
// 192.0.2.0/24 != ::ffff:c000:0204/120, but because we use InetAddress,
|
|
// we are unable to comprehend that.
|
|
byte[] ipv6bytes = {
|
|
(byte) 0, (byte) 0, (byte) 0, (byte) 0,
|
|
(byte) 0, (byte) 0, (byte) 0, (byte) 0,
|
|
(byte) 0, (byte) 0, (byte) 0xff, (byte) 0xff,
|
|
(byte) 192, (byte) 0, (byte) 2, (byte) 0};
|
|
IpPrefix p = new IpPrefix(ipv6bytes, 120);
|
|
assertEquals(16, p.getRawAddress().length); // Fine.
|
|
assertArrayEquals(ipv6bytes, p.getRawAddress()); // Fine.
|
|
|
|
// Broken.
|
|
assertEquals("192.0.2.0/120", p.toString());
|
|
assertEquals(InetAddress.parseNumericAddress("192.0.2.0"), p.getAddress());
|
|
}
|
|
|
|
@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());
|
|
}
|
|
}
|