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

Commit 472b9262 authored by Varun Anand's avatar Varun Anand
Browse files

Add unit tests related to data accounting for VPNs with one underlying

network.

This is to establish a baseline for the existing behavior, and to ensure
that following changes are not causing a regression in existing
behavior.

This CL is also adding missing cleanup for NetworkStatsCollectionTest
which was forcing all network types in NetworkTemplate that was causing
NetworkStatsService related tests to fail.

Bug: 113122541
Bug: 120145746
Test: atest FrameworksNetTests
Change-Id: I285f186cfb16bc9fa704c797996b1e4f8a73dee4
parent eb3e7b3f
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;
    }