Merge "Bootstrap IpReachabilityMonitor unit tests" am: a9889c94aa
am: 39a707813b
Change-Id: Ie56377ae158d32a3592fd700e93fc827754ecaa3
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
|
||||
package android.net.ip;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
@@ -31,18 +29,22 @@ import android.net.netlink.NetlinkErrorMessage;
|
||||
import android.net.netlink.NetlinkMessage;
|
||||
import android.net.netlink.NetlinkSocket;
|
||||
import android.net.netlink.RtNetlinkNeighborMessage;
|
||||
import android.net.netlink.StructNdaCacheInfo;
|
||||
import android.net.netlink.StructNdMsg;
|
||||
import android.net.netlink.StructNdaCacheInfo;
|
||||
import android.net.netlink.StructNlMsgHdr;
|
||||
import android.net.util.MultinetworkPolicyTracker;
|
||||
import android.net.util.SharedLog;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.SystemClock;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.NetlinkSocketAddress;
|
||||
import android.system.OsConstants;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
@@ -147,12 +149,32 @@ public class IpReachabilityMonitor {
|
||||
public void notifyLost(InetAddress ip, String logMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulates IpReachabilityMonitor depencencies on systems that hinder unit testing.
|
||||
* TODO: consider also wrapping MultinetworkPolicyTracker in this interface.
|
||||
*/
|
||||
interface Dependencies {
|
||||
void acquireWakeLock(long durationMs);
|
||||
|
||||
static Dependencies makeDefault(Context context, String iface) {
|
||||
final String lockName = TAG + "." + iface;
|
||||
final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
final WakeLock lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
|
||||
|
||||
return new Dependencies() {
|
||||
public void acquireWakeLock(long durationMs) {
|
||||
lock.acquire(durationMs);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private final Object mLock = new Object();
|
||||
private final PowerManager.WakeLock mWakeLock;
|
||||
private final String mInterfaceName;
|
||||
private final int mInterfaceIndex;
|
||||
private final SharedLog mLog;
|
||||
private final Callback mCallback;
|
||||
private final Dependencies mDependencies;
|
||||
private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
|
||||
private final NetlinkSocketObserver mNetlinkSocketObserver;
|
||||
private final Thread mObserverThread;
|
||||
@@ -228,20 +250,20 @@ public class IpReachabilityMonitor {
|
||||
}
|
||||
|
||||
public IpReachabilityMonitor(Context context, String ifName, SharedLog log, Callback callback,
|
||||
MultinetworkPolicyTracker tracker) throws IllegalArgumentException {
|
||||
MultinetworkPolicyTracker tracker) {
|
||||
this(ifName, getInterfaceIndex(ifName), log, callback, tracker,
|
||||
Dependencies.makeDefault(context, ifName));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
IpReachabilityMonitor(String ifName, int ifIndex, SharedLog log, Callback callback,
|
||||
MultinetworkPolicyTracker tracker, Dependencies dependencies) {
|
||||
mInterfaceName = ifName;
|
||||
int ifIndex = -1;
|
||||
try {
|
||||
NetworkInterface netIf = NetworkInterface.getByName(ifName);
|
||||
mInterfaceIndex = netIf.getIndex();
|
||||
} catch (SocketException | NullPointerException e) {
|
||||
throw new IllegalArgumentException("invalid interface '" + ifName + "': ", e);
|
||||
}
|
||||
mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);
|
||||
mLog = log.forSubComponent(TAG);
|
||||
mCallback = callback;
|
||||
mMultinetworkPolicyTracker = tracker;
|
||||
mInterfaceIndex = ifIndex;
|
||||
mDependencies = dependencies;
|
||||
mNetlinkSocketObserver = new NetlinkSocketObserver();
|
||||
mObserverThread = new Thread(mNetlinkSocketObserver);
|
||||
mObserverThread.start();
|
||||
@@ -398,7 +420,7 @@ public class IpReachabilityMonitor {
|
||||
// The wakelock we use is (by default) refcounted, and this version
|
||||
// of acquire(timeout) queues a release message to keep acquisitions
|
||||
// and releases balanced.
|
||||
mWakeLock.acquire(getProbeWakeLockDuration());
|
||||
mDependencies.acquireWakeLock(getProbeWakeLockDuration());
|
||||
}
|
||||
|
||||
for (InetAddress target : ipProbeList) {
|
||||
@@ -429,6 +451,19 @@ public class IpReachabilityMonitor {
|
||||
return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
|
||||
}
|
||||
|
||||
private static int getInterfaceIndex(String ifname) {
|
||||
final NetworkInterface iface;
|
||||
try {
|
||||
iface = NetworkInterface.getByName(ifname);
|
||||
} catch (SocketException e) {
|
||||
throw new IllegalArgumentException("invalid interface '" + ifname + "': ", e);
|
||||
}
|
||||
if (iface == null) {
|
||||
throw new IllegalArgumentException("NetworkInterface was null for " + ifname);
|
||||
}
|
||||
return iface.getIndex();
|
||||
}
|
||||
|
||||
private void logEvent(int probeType, int errorCode) {
|
||||
int eventType = probeType | (errorCode & 0xff);
|
||||
mMetricsLog.log(mInterfaceName, new IpReachabilityEvent(eventType));
|
||||
|
||||
59
tests/net/java/android/net/ip/IpReachabilityMonitorTest.java
Normal file
59
tests/net/java/android/net/ip/IpReachabilityMonitorTest.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.ip;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for IpReachabilityMonitor.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class IpReachabilityMonitorTest {
|
||||
|
||||
@Mock IpReachabilityMonitor.Callback mCallback;
|
||||
@Mock IpReachabilityMonitor.Dependencies mDependencies;
|
||||
@Mock SharedLog mLog;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
IpReachabilityMonitor makeMonitor() {
|
||||
return new IpReachabilityMonitor("fake0", 1, mLog, mCallback, null, mDependencies);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
IpReachabilityMonitor monitor = makeMonitor();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user