Merge changes I2cea553a,Id8d3dcf6,I19e68e88,I35598935,Idd7dc369, ...
am: e01b4ce6c7
Change-Id: I1800eb214d501e76b8705a27ca817000d009736e
This commit is contained in:
@@ -24,6 +24,8 @@ import static android.net.NetworkUtils.intToInet4AddressHTL;
|
||||
import static android.net.NetworkUtils.netmaskToPrefixLength;
|
||||
import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTH;
|
||||
import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTL;
|
||||
import static android.net.NetworkUtils.getBroadcastAddress;
|
||||
import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
@@ -125,7 +127,6 @@ public class NetworkUtilsTest {
|
||||
assertInvalidNetworkMask(IPv4Address("255.255.0.255"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPrefixLengthToV4NetmaskIntHTL() {
|
||||
assertEquals(0, prefixLengthToV4NetmaskIntHTL(0));
|
||||
@@ -266,4 +267,44 @@ public class NetworkUtilsTest {
|
||||
assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
|
||||
NetworkUtils.routedIPv6AddressCount(set));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrefixMaskAsAddress() {
|
||||
assertEquals("255.255.240.0", getPrefixMaskAsInet4Address(20).getHostAddress());
|
||||
assertEquals("255.0.0.0", getPrefixMaskAsInet4Address(8).getHostAddress());
|
||||
assertEquals("0.0.0.0", getPrefixMaskAsInet4Address(0).getHostAddress());
|
||||
assertEquals("255.255.255.255", getPrefixMaskAsInet4Address(32).getHostAddress());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetPrefixMaskAsAddress_PrefixTooLarge() {
|
||||
getPrefixMaskAsInet4Address(33);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetPrefixMaskAsAddress_NegativePrefix() {
|
||||
getPrefixMaskAsInet4Address(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBroadcastAddress() {
|
||||
assertEquals("192.168.15.255",
|
||||
getBroadcastAddress(IPv4Address("192.168.0.123"), 20).getHostAddress());
|
||||
assertEquals("192.255.255.255",
|
||||
getBroadcastAddress(IPv4Address("192.168.0.123"), 8).getHostAddress());
|
||||
assertEquals("192.168.0.123",
|
||||
getBroadcastAddress(IPv4Address("192.168.0.123"), 32).getHostAddress());
|
||||
assertEquals("255.255.255.255",
|
||||
getBroadcastAddress(IPv4Address("192.168.0.123"), 0).getHostAddress());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetBroadcastAddress_PrefixTooLarge() {
|
||||
getBroadcastAddress(IPv4Address("192.168.0.123"), 33);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetBroadcastAddress_NegativePrefix() {
|
||||
getBroadcastAddress(IPv4Address("192.168.0.123"), -1);
|
||||
}
|
||||
}
|
||||
|
||||
519
tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java
Normal file
519
tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java
Normal file
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.dhcp;
|
||||
|
||||
import static android.net.dhcp.DhcpLease.HOSTNAME_NONE;
|
||||
import static android.net.dhcp.DhcpLeaseRepository.CLIENTID_UNSPEC;
|
||||
import static android.net.dhcp.DhcpLeaseRepository.INETADDR_UNSPEC;
|
||||
|
||||
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 static org.mockito.Mockito.when;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.net.InetAddress.parseNumericAddress;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.net.IpPrefix;
|
||||
import android.net.MacAddress;
|
||||
import android.net.dhcp.DhcpLeaseRepository.Clock;
|
||||
import android.net.util.SharedLog;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class DhcpLeaseRepositoryTest {
|
||||
private static final Inet4Address INET4_ANY = (Inet4Address) Inet4Address.ANY;
|
||||
private static final Inet4Address TEST_DEF_ROUTER = parseAddr4("192.168.42.247");
|
||||
private static final Inet4Address TEST_SERVER_ADDR = parseAddr4("192.168.42.241");
|
||||
private static final Inet4Address TEST_RESERVED_ADDR = parseAddr4("192.168.42.243");
|
||||
private static final MacAddress TEST_MAC_1 = MacAddress.fromBytes(
|
||||
new byte[] { 5, 4, 3, 2, 1, 0 });
|
||||
private static final MacAddress TEST_MAC_2 = MacAddress.fromBytes(
|
||||
new byte[] { 0, 1, 2, 3, 4, 5 });
|
||||
private static final MacAddress TEST_MAC_3 = MacAddress.fromBytes(
|
||||
new byte[] { 0, 1, 2, 3, 4, 6 });
|
||||
private static final Inet4Address TEST_INETADDR_1 = parseAddr4("192.168.42.248");
|
||||
private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249");
|
||||
private static final String TEST_HOSTNAME_1 = "hostname1";
|
||||
private static final String TEST_HOSTNAME_2 = "hostname2";
|
||||
private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22);
|
||||
private static final long TEST_TIME = 100L;
|
||||
private static final int TEST_LEASE_TIME_MS = 3_600_000;
|
||||
private static final Set<Inet4Address> TEST_EXCL_SET =
|
||||
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
TEST_SERVER_ADDR, TEST_DEF_ROUTER, TEST_RESERVED_ADDR)));
|
||||
|
||||
@NonNull
|
||||
private SharedLog mLog;
|
||||
@NonNull @Mock
|
||||
private Clock mClock;
|
||||
@NonNull
|
||||
private DhcpLeaseRepository mRepo;
|
||||
|
||||
private static Inet4Address parseAddr4(String inet4Addr) {
|
||||
return (Inet4Address) parseNumericAddress(inet4Addr);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLog = new SharedLog("DhcpLeaseRepositoryTest");
|
||||
when(mClock.elapsedRealtime()).thenReturn(TEST_TIME);
|
||||
mRepo = new DhcpLeaseRepository(
|
||||
TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, mLog, mClock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a number of addresses through offer/request. Useful to test address exhaustion.
|
||||
* @param nAddr Number of addresses to request.
|
||||
*/
|
||||
private void requestAddresses(byte nAddr) throws Exception {
|
||||
final HashSet<Inet4Address> addrs = new HashSet<>();
|
||||
byte[] hwAddrBytes = new byte[] { 8, 4, 3, 2, 1, 0 };
|
||||
for (byte i = 0; i < nAddr; i++) {
|
||||
hwAddrBytes[5] = i;
|
||||
MacAddress newMac = MacAddress.fromBytes(hwAddrBytes);
|
||||
final String hostname = "host_" + i;
|
||||
final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, newMac,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, hostname);
|
||||
|
||||
assertNotNull(lease);
|
||||
assertEquals(newMac, lease.getHwAddr());
|
||||
assertEquals(hostname, lease.getHostname());
|
||||
assertTrue(format("Duplicate address allocated: %s in %s", lease.getNetAddr(), addrs),
|
||||
addrs.add(lease.getNetAddr()));
|
||||
|
||||
mRepo.requestLease(null, newMac, null, lease.getNetAddr(), true, hostname);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressExhaustion() throws Exception {
|
||||
// Use a /28 to quickly run out of addresses
|
||||
mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
|
||||
|
||||
// /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
|
||||
requestAddresses((byte)11);
|
||||
|
||||
try {
|
||||
mRepo.getOffer(null, TEST_MAC_2,
|
||||
null /* relayAddr */, null /* reqAddr */, HOSTNAME_NONE);
|
||||
fail("Should be out of addresses");
|
||||
} catch (DhcpLeaseRepository.OutOfAddressesException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateParams_LeaseCleanup() throws Exception {
|
||||
// Inside /28:
|
||||
final Inet4Address reqAddrIn28 = parseAddr4("192.168.42.242");
|
||||
final Inet4Address declinedAddrIn28 = parseAddr4("192.168.42.245");
|
||||
|
||||
// Inside /28, but not available there (first address of the range)
|
||||
final Inet4Address declinedFirstAddrIn28 = parseAddr4("192.168.42.240");
|
||||
|
||||
final DhcpLease reqAddrIn28Lease = mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, reqAddrIn28, false, HOSTNAME_NONE);
|
||||
mRepo.markLeaseDeclined(declinedAddrIn28);
|
||||
mRepo.markLeaseDeclined(declinedFirstAddrIn28);
|
||||
|
||||
// Inside /22, but outside /28:
|
||||
final Inet4Address reqAddrIn22 = parseAddr4("192.168.42.3");
|
||||
final Inet4Address declinedAddrIn22 = parseAddr4("192.168.42.4");
|
||||
|
||||
final DhcpLease reqAddrIn22Lease = mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, TEST_MAC_3, INET4_ANY, reqAddrIn22, false, HOSTNAME_NONE);
|
||||
mRepo.markLeaseDeclined(declinedAddrIn22);
|
||||
|
||||
// Address that will be reserved in the updateParams call below
|
||||
final Inet4Address reservedAddr = parseAddr4("192.168.42.244");
|
||||
final DhcpLease reservedAddrLease = mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY, reservedAddr, false, HOSTNAME_NONE);
|
||||
|
||||
// Update from /22 to /28 and add another reserved address
|
||||
Set<Inet4Address> newReserved = new HashSet<>(TEST_EXCL_SET);
|
||||
newReserved.add(reservedAddr);
|
||||
mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), newReserved, TEST_LEASE_TIME_MS);
|
||||
|
||||
assertHasLease(reqAddrIn28Lease);
|
||||
assertDeclined(declinedAddrIn28);
|
||||
|
||||
assertNotDeclined(declinedFirstAddrIn28);
|
||||
|
||||
assertNoLease(reqAddrIn22Lease);
|
||||
assertNotDeclined(declinedAddrIn22);
|
||||
|
||||
assertNoLease(reservedAddrLease);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_StableAddress() throws Exception {
|
||||
for (final MacAddress macAddr : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
|
||||
final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
|
||||
// Same lease is offered twice
|
||||
final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
assertEquals(lease, newLease);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateParams_UsesNewPrefix() throws Exception {
|
||||
final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
|
||||
mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS);
|
||||
|
||||
DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
|
||||
assertTrue(newPrefix.contains(lease.getNetAddr()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_ExistingLease() throws Exception {
|
||||
mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false, TEST_HOSTNAME_1);
|
||||
|
||||
DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
|
||||
assertEquals(TEST_INETADDR_1, offer.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_1, offer.getHostname());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_ClientIdHasExistingLease() throws Exception {
|
||||
final byte[] clientId = new byte[] { 1, 2 };
|
||||
mRepo.requestLease(clientId, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false,
|
||||
TEST_HOSTNAME_1);
|
||||
|
||||
// Different MAC, but same clientId
|
||||
DhcpLease offer = mRepo.getOffer(clientId, TEST_MAC_2,
|
||||
INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
|
||||
assertEquals(TEST_INETADDR_1, offer.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_1, offer.getHostname());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_DifferentClientId() throws Exception {
|
||||
final byte[] clientId1 = new byte[] { 1, 2 };
|
||||
final byte[] clientId2 = new byte[] { 3, 4 };
|
||||
mRepo.requestLease(clientId1, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false,
|
||||
TEST_HOSTNAME_1);
|
||||
|
||||
// Same MAC, different client ID
|
||||
DhcpLease offer = mRepo.getOffer(clientId2, TEST_MAC_1,
|
||||
INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
|
||||
// Obtains a different address
|
||||
assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
|
||||
assertEquals(HOSTNAME_NONE, offer.getHostname());
|
||||
assertEquals(TEST_MAC_1, offer.getHwAddr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_RequestedAddress() throws Exception {
|
||||
DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, TEST_HOSTNAME_1);
|
||||
assertEquals(TEST_INETADDR_1, offer.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_1, offer.getHostname());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_RequestedAddressInUse() throws Exception {
|
||||
mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false, HOSTNAME_NONE);
|
||||
DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
|
||||
TEST_INETADDR_1, HOSTNAME_NONE);
|
||||
assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_RequestedAddressReserved() throws Exception {
|
||||
DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_RESERVED_ADDR, HOSTNAME_NONE);
|
||||
assertNotEquals(TEST_RESERVED_ADDR, offer.getNetAddr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_RequestedAddressInvalid() throws Exception {
|
||||
final Inet4Address invalidAddr = parseAddr4("192.168.42.0");
|
||||
DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
invalidAddr, HOSTNAME_NONE);
|
||||
assertNotEquals(invalidAddr, offer.getNetAddr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffer_RequestedAddressOutsideSubnet() throws Exception {
|
||||
final Inet4Address invalidAddr = parseAddr4("192.168.254.2");
|
||||
DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
invalidAddr, HOSTNAME_NONE);
|
||||
assertNotEquals(invalidAddr, offer.getNetAddr());
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testGetOffer_RelayInInvalidSubnet() throws Exception {
|
||||
mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
parseAddr4("192.168.254.2") /* relayAddr */, INETADDR_UNSPEC, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestLease_SelectingTwice() throws Exception {
|
||||
DhcpLease lease1 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, TEST_HOSTNAME_1);
|
||||
|
||||
// Second request from same client for a different address
|
||||
DhcpLease lease2 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_2, true /* sidSet */, TEST_HOSTNAME_2);
|
||||
|
||||
assertEquals(TEST_INETADDR_1, lease1.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_1, lease1.getHostname());
|
||||
|
||||
assertEquals(TEST_INETADDR_2, lease2.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_2, lease2.getHostname());
|
||||
|
||||
// First address freed when client requested a different one: another client can request it
|
||||
DhcpLease lease3 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
assertEquals(TEST_INETADDR_1, lease3.getNetAddr());
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_SelectingInvalid() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
parseAddr4("192.168.254.5"), true /* sidSet */, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_SelectingInUse() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_SelectingReserved() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_RESERVED_ADDR, true /* sidSet */, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestLease_InitReboot() throws Exception {
|
||||
// Request address once
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
|
||||
final long newTime = TEST_TIME + 100;
|
||||
when(mClock.elapsedRealtime()).thenReturn(newTime);
|
||||
|
||||
// init-reboot (sidSet == false): verify configuration
|
||||
DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, false, HOSTNAME_NONE);
|
||||
assertEquals(TEST_INETADDR_1, lease.getNetAddr());
|
||||
assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_InitRebootWrongAddr() throws Exception {
|
||||
// Request address once
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
// init-reboot with different requested address
|
||||
mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, TEST_INETADDR_2, false, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestLease_InitRebootUnknownAddr() throws Exception {
|
||||
// init-reboot with unknown requested address
|
||||
DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_2, false, HOSTNAME_NONE);
|
||||
// RFC2131 says we should not reply to accommodate other servers, but since we are
|
||||
// authoritative we allow creating the lease to avoid issues with lost lease DB (same as
|
||||
// dnsmasq behavior)
|
||||
assertEquals(TEST_INETADDR_2, lease.getNetAddr());
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_InitRebootWrongSubnet() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
parseAddr4("192.168.254.2"), false /* sidSet */, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestLease_Renewing() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
INET4_ANY /* clientAddr */, TEST_INETADDR_1 /* reqAddr */, true, HOSTNAME_NONE);
|
||||
|
||||
final long newTime = TEST_TIME + 100;
|
||||
when(mClock.elapsedRealtime()).thenReturn(newTime);
|
||||
|
||||
// Renewing: clientAddr filled in, no reqAddr
|
||||
DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
TEST_INETADDR_1 /* clientAddr */, INETADDR_UNSPEC /* reqAddr */, false,
|
||||
HOSTNAME_NONE);
|
||||
|
||||
assertEquals(TEST_INETADDR_1, lease.getNetAddr());
|
||||
assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestLease_RenewingUnknownAddr() throws Exception {
|
||||
final long newTime = TEST_TIME + 100;
|
||||
when(mClock.elapsedRealtime()).thenReturn(newTime);
|
||||
DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
TEST_INETADDR_1 /* clientAddr */, INETADDR_UNSPEC /* reqAddr */, false,
|
||||
HOSTNAME_NONE);
|
||||
// Allows renewing an unknown address if available
|
||||
assertEquals(TEST_INETADDR_1, lease.getNetAddr());
|
||||
assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_RenewingAddrInUse() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2,
|
||||
INET4_ANY /* clientAddr */, TEST_INETADDR_1 /* reqAddr */, true, HOSTNAME_NONE);
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
TEST_INETADDR_1 /* clientAddr */, INETADDR_UNSPEC /* reqAddr */, false,
|
||||
HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
|
||||
public void testRequestLease_RenewingInvalidAddr() throws Exception {
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, parseAddr4("192.168.254.2") /* clientAddr */,
|
||||
INETADDR_UNSPEC /* reqAddr */, false, HOSTNAME_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseLease() throws Exception {
|
||||
DhcpLease lease1 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
|
||||
assertHasLease(lease1);
|
||||
assertTrue(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
|
||||
assertNoLease(lease1);
|
||||
|
||||
DhcpLease lease2 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
|
||||
TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
|
||||
|
||||
assertEquals(TEST_INETADDR_1, lease2.getNetAddr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseLease_UnknownLease() {
|
||||
assertFalse(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseLease_StableOffer() throws Exception {
|
||||
for (MacAddress mac : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
|
||||
final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
mRepo.requestLease(
|
||||
CLIENTID_UNSPEC, mac, INET4_ANY, lease.getNetAddr(), true,
|
||||
HOSTNAME_NONE);
|
||||
mRepo.releaseLease(CLIENTID_UNSPEC, mac, lease.getNetAddr());
|
||||
|
||||
// Same lease is offered after it was released
|
||||
final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
assertEquals(lease.getNetAddr(), newLease.getNetAddr());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkLeaseDeclined() throws Exception {
|
||||
final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
|
||||
mRepo.markLeaseDeclined(lease.getNetAddr());
|
||||
|
||||
// Same lease is not offered again
|
||||
final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
assertNotEquals(lease.getNetAddr(), newLease.getNetAddr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
|
||||
// Use a /28 to quickly run out of addresses
|
||||
mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
|
||||
|
||||
mRepo.markLeaseDeclined(TEST_INETADDR_1);
|
||||
mRepo.markLeaseDeclined(TEST_INETADDR_2);
|
||||
|
||||
// /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
|
||||
requestAddresses((byte)9);
|
||||
|
||||
// Last 2 addresses: addresses marked declined should be used
|
||||
final DhcpLease firstLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_1);
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, firstLease.getNetAddr(), true,
|
||||
HOSTNAME_NONE);
|
||||
|
||||
final DhcpLease secondLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2,
|
||||
INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_2);
|
||||
mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY, secondLease.getNetAddr(), true,
|
||||
HOSTNAME_NONE);
|
||||
|
||||
// Now out of addresses
|
||||
try {
|
||||
mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_3, INETADDR_UNSPEC /* relayAddr */,
|
||||
INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
|
||||
fail("Repository should be out of addresses and throw");
|
||||
} catch (DhcpLeaseRepository.OutOfAddressesException e) { /* expected */ }
|
||||
|
||||
assertEquals(TEST_INETADDR_1, firstLease.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_1, firstLease.getHostname());
|
||||
assertEquals(TEST_INETADDR_2, secondLease.getNetAddr());
|
||||
assertEquals(TEST_HOSTNAME_2, secondLease.getHostname());
|
||||
}
|
||||
|
||||
private void assertNoLease(DhcpLease lease) {
|
||||
assertFalse("Leases contain " + lease, mRepo.getCommittedLeases().contains(lease));
|
||||
}
|
||||
|
||||
private void assertHasLease(DhcpLease lease) {
|
||||
assertTrue("Leases do not contain " + lease, mRepo.getCommittedLeases().contains(lease));
|
||||
}
|
||||
|
||||
private void assertNotDeclined(Inet4Address addr) {
|
||||
assertFalse("Address is declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
|
||||
}
|
||||
|
||||
private void assertDeclined(Inet4Address addr) {
|
||||
assertTrue("Address is not declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
|
||||
}
|
||||
}
|
||||
177
tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
Normal file
177
tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.dhcp;
|
||||
|
||||
import static android.net.dhcp.DhcpServingParams.MTU_UNSET;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static java.net.InetAddress.parseNumericAddress;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.dhcp.DhcpServingParams.InvalidParameterException;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class DhcpServingParamsTest {
|
||||
@NonNull
|
||||
private DhcpServingParams.Builder mBuilder;
|
||||
|
||||
private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
|
||||
Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
|
||||
private static final long TEST_LEASE_TIME_SECS = 3600L;
|
||||
private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
|
||||
Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
|
||||
private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
|
||||
private static final LinkAddress TEST_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
|
||||
private static final int TEST_MTU = 1500;
|
||||
private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
|
||||
Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mBuilder = new DhcpServingParams.Builder()
|
||||
.setDefaultRouters(TEST_DEFAULT_ROUTERS)
|
||||
.setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
|
||||
.setDnsServers(TEST_DNS_SERVERS)
|
||||
.setServerAddr(TEST_LINKADDR)
|
||||
.setLinkMtu(TEST_MTU)
|
||||
.setExcludedAddrs(TEST_EXCLUDED_ADDRS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuild_Immutable() throws InvalidParameterException {
|
||||
final Set<Inet4Address> routers = new HashSet<>(TEST_DEFAULT_ROUTERS);
|
||||
final Set<Inet4Address> dnsServers = new HashSet<>(TEST_DNS_SERVERS);
|
||||
final Set<Inet4Address> excludedAddrs = new HashSet<>(TEST_EXCLUDED_ADDRS);
|
||||
|
||||
final DhcpServingParams params = mBuilder
|
||||
.setDefaultRouters(routers)
|
||||
.setDnsServers(dnsServers)
|
||||
.setExcludedAddrs(excludedAddrs)
|
||||
.build();
|
||||
|
||||
// Modifications to source objects should not affect builder or final parameters
|
||||
final Inet4Address addedAddr = parseAddr("192.168.0.223");
|
||||
routers.add(addedAddr);
|
||||
dnsServers.add(addedAddr);
|
||||
excludedAddrs.add(addedAddr);
|
||||
|
||||
assertEquals(TEST_DEFAULT_ROUTERS, params.defaultRouters);
|
||||
assertEquals(TEST_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
|
||||
assertEquals(TEST_DNS_SERVERS, params.dnsServers);
|
||||
assertEquals(TEST_LINKADDR, params.serverAddr);
|
||||
assertEquals(TEST_MTU, params.linkMtu);
|
||||
|
||||
assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS);
|
||||
assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS);
|
||||
assertContains(params.excludedAddrs, TEST_DNS_SERVERS);
|
||||
assertContains(params.excludedAddrs, TEST_SERVER_ADDR);
|
||||
|
||||
assertFalse("excludedAddrs should not contain " + addedAddr,
|
||||
params.excludedAddrs.contains(addedAddr));
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_NegativeLeaseTime() throws InvalidParameterException {
|
||||
mBuilder.setDhcpLeaseTimeSecs(-1).build();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_LeaseTimeTooLarge() throws InvalidParameterException {
|
||||
// Set lease time larger than max value for uint32
|
||||
mBuilder.setDhcpLeaseTimeSecs(1L << 32).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuild_InfiniteLeaseTime() throws InvalidParameterException {
|
||||
final long infiniteLeaseTime = 0xffffffffL;
|
||||
final DhcpServingParams params = mBuilder
|
||||
.setDhcpLeaseTimeSecs(infiniteLeaseTime).build();
|
||||
assertEquals(infiniteLeaseTime, params.dhcpLeaseTimeSecs);
|
||||
assertTrue(params.dhcpLeaseTimeSecs > 0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuild_UnsetMtu() throws InvalidParameterException {
|
||||
final DhcpServingParams params = mBuilder.setLinkMtu(MTU_UNSET).build();
|
||||
assertEquals(MTU_UNSET, params.linkMtu);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_MtuTooSmall() throws InvalidParameterException {
|
||||
mBuilder.setLinkMtu(20).build();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_MtuTooLarge() throws InvalidParameterException {
|
||||
mBuilder.setLinkMtu(65_536).build();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_IPv6Addr() throws InvalidParameterException {
|
||||
mBuilder.setServerAddr(new LinkAddress(parseNumericAddress("fe80::1111"), 120)).build();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_PrefixTooLarge() throws InvalidParameterException {
|
||||
mBuilder.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 15)).build();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_PrefixTooSmall() throws InvalidParameterException {
|
||||
mBuilder.setDefaultRouters(Collections.singleton(parseAddr("192.168.0.254")))
|
||||
.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterException.class)
|
||||
public void testBuild_RouterNotInPrefix() throws InvalidParameterException {
|
||||
mBuilder.setDefaultRouters(Collections.singleton(parseAddr("192.168.254.254"))).build();
|
||||
}
|
||||
|
||||
private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) {
|
||||
for (final T elem : subset) {
|
||||
assertContains(set, elem);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void assertContains(@NonNull Set<T> set, @Nullable T elem) {
|
||||
assertTrue("Set does not contain " + elem, set.contains(elem));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static Inet4Address parseAddr(@NonNull String inet4Addr) {
|
||||
return (Inet4Address) parseNumericAddress(inet4Addr);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user