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

Commit a9889c94 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Bootstrap IpReachabilityMonitor unit tests"

parents ec5fc487 06b1f2b1
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;
@@ -229,20 +251,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();
@@ -405,7 +427,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) {
@@ -436,6 +458,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(new IpReachabilityEvent(mInterfaceName, 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();
    }
}