Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b88e173 authored by Hugo Benichi's avatar Hugo Benichi Committed by android-build-merger
Browse files

Merge "Bootstrap IpReachabilityMonitor unit tests" am: a9889c94 am: 39a70781

am: 5bc28905

Change-Id: I9ca394ccac1683d5d91b426582cfb3cddb5f5e96
parents 3137ed47 5bc28905
Loading
Loading
Loading
Loading
+50 −15
Original line number Diff line number Diff line
@@ -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 {
        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);
            MultinetworkPolicyTracker tracker) {
        this(ifName, getInterfaceIndex(ifName), log, callback, tracker,
                Dependencies.makeDefault(context, ifName));
    }
        mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);

    @VisibleForTesting
    IpReachabilityMonitor(String ifName, int ifIndex, SharedLog log, Callback callback,
            MultinetworkPolicyTracker tracker, Dependencies dependencies) {
        mInterfaceName = ifName;
        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 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}