Merge "Bootstrap IpReachabilityMonitor unit tests"

am: a9889c94aa

Change-Id: Ic3b145159a4c0430cc248a19b8527af40fa67696
This commit is contained in:
Hugo Benichi
2017-07-25 14:33:45 +00:00
committed by android-build-merger
2 changed files with 109 additions and 15 deletions

View File

@@ -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));

View 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();
}
}