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

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

Merge "Add unit tests related to data accounting for VPNs with one underlying network."

parents 0bb3c6bb 472b9262
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.Parcelable;
import android.util.BackupUtils;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;

import java.io.ByteArrayOutputStream;
@@ -89,10 +90,22 @@ public class NetworkTemplate implements Parcelable {

    private static boolean sForceAllNetworkTypes = false;

    /**
     * Results in matching against all mobile network types.
     *
     * <p>See {@link #matchesMobile} and {@link matchesMobileWildcard}.
     */
    @VisibleForTesting
    public static void forceAllNetworkTypes() {
        sForceAllNetworkTypes = true;
    }

    /** Resets the affect of {@link #forceAllNetworkTypes}. */
    @VisibleForTesting
    public static void resetForceAllNetworkTypes() {
        sForceAllNetworkTypes = false;
    }

    /**
     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
     * the given IMSI.
+1 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ public class NetworkStatsCollectionTest {
    @After
    public void tearDown() throws Exception {
        RecurrenceRule.sClock = sOriginalClock;
        NetworkTemplate.resetForceAllNetworkTypes();
    }

    private void setClock(Instant instant) {
+129 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.net;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
@@ -41,6 +42,7 @@ import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UID_REMOVED;
@@ -132,6 +134,8 @@ public class NetworkStatsServiceTest {

    private static final String TEST_IFACE = "test0";
    private static final String TEST_IFACE2 = "test1";
    private static final String TUN_IFACE = "test_nss_tun0";

    private static final long TEST_START = 1194220800000L;

    private static final String IMSI_1 = "310004";
@@ -145,10 +149,12 @@ public class NetworkStatsServiceTest {
    private static final int UID_RED = 1001;
    private static final int UID_BLUE = 1002;
    private static final int UID_GREEN = 1003;

    private static final int UID_VPN = 1004;

    private static final Network WIFI_NETWORK =  new Network(100);
    private static final Network MOBILE_NETWORK =  new Network(101);
    private static final Network VPN_NETWORK = new Network(102);

    private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK };
    private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK };

@@ -914,7 +920,113 @@ public class NetworkStatsServiceTest {
        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
        assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
    }

    @Test
    public void vpnWithOneUnderlyingIface() throws Exception {
        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
        expectDefaultSettings();
        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces(
                new Network[] {WIFI_NETWORK, VPN_NETWORK},
                vpnInfos,
                networkStates,
                getActiveIface(networkStates));
        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
        // overhead per packet):
        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
        // 500 bytes (50 packets) were sent/received by UID_BLUE over VPN.
        // VPN sent/received 1650 bytes (150 packets) over WiFi.
        // Of 1650 bytes over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes attributed to
        // UID_BLUE, and 150 bytes attributed to UID_VPN for both rx/tx traffic.
        incrementCurrentTime(HOUR_IN_MILLIS);
        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 500L, 50L, 500L, 50L, 1L)
                .addValues(
                    TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1650L, 150L, 1650L, 150L, 2L));

        forcePollAndWaitForIdle();

        assertUidTotal(sTemplateWifi, UID_RED, 1000L, 100L, 1000L, 100L, 1);
        assertUidTotal(sTemplateWifi, UID_BLUE, 500L, 50L, 500L, 50L, 1);
        assertUidTotal(sTemplateWifi, UID_VPN, 150L, 0L, 150L, 0L, 2);
    }

    @Test
    public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
        expectDefaultSettings();
        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces(
                new Network[] {WIFI_NETWORK, VPN_NETWORK},
                vpnInfos,
                networkStates,
                getActiveIface(networkStates));
        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
        // overhead per packet):
        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
        // 3000 bytes (300 packets) were sent/received by UID_BLUE over VPN.
        // VPN sent/received 1000 bytes (100 packets) over WiFi.
        // Of 1000 bytes over WiFi, expect 250 bytes attributed UID_RED and 750 bytes to UID_BLUE,
        // with nothing attributed to UID_VPN for both rx/tx traffic.
        incrementCurrentTime(HOUR_IN_MILLIS);
        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 3000L, 300L, 3000L, 300L, 1L)
                .addValues(
                    TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 0L));

        forcePollAndWaitForIdle();

        assertUidTotal(sTemplateWifi, UID_RED, 250L, 25L, 250L, 25L, 0);
        assertUidTotal(sTemplateWifi, UID_BLUE, 750L, 75L, 750L, 75L, 0);
        assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
    }

    @Test
    public void vpnWithIncorrectUnderlyingIface() throws Exception {
        // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
        // but has declared only WiFi (TEST_IFACE) in its underlying network set.
        expectDefaultSettings();
        NetworkState[] networkStates =
                new NetworkState[] {
                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
                };
        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces(
                new Network[] {WIFI_NETWORK, VPN_NETWORK},
                vpnInfos,
                networkStates,
                getActiveIface(networkStates));
        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
        // overhead per packet):
        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
        // VPN sent/received 1100 bytes (100 packets) over Cell.
        // Of 1100 bytes over Cell, expect all of it attributed to UID_VPN for both rx/tx traffic.
        incrementCurrentTime(HOUR_IN_MILLIS);
        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
                .addValues(
                    TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 1100L, 100L, 1L));

        forcePollAndWaitForIdle();

        assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
        assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 0L, 0L, 0L, 0L, 0);
        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 1100L, 100L, 1100L, 100L, 1);
    }

    @Test
@@ -1262,6 +1374,22 @@ public class NetworkStatsServiceTest {
        return new NetworkStats(getElapsedRealtime(), 0);
    }

    private static NetworkState buildVpnState() {
        final NetworkInfo info = new NetworkInfo(TYPE_VPN, 0, null, null);
        info.setDetailedState(DetailedState.CONNECTED, null, null);
        final LinkProperties prop = new LinkProperties();
        prop.setInterfaceName(TUN_IFACE);
        return new NetworkState(info, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
    }

    private static VpnInfo createVpnInfo(String underlyingIface) {
        VpnInfo info = new VpnInfo();
        info.ownerUid = UID_VPN;
        info.vpnIface = TUN_IFACE;
        info.primaryUnderlyingIface = underlyingIface;
        return info;
    }

    private long getElapsedRealtime() {
        return mElapsedRealtime;
    }