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

Commit 6baf734a authored by Junyu Lai's avatar Junyu Lai Committed by Gerrit Code Review
Browse files

Merge changes from topic "sp26-networkstats-cts"

* changes:
  [SP26] add CTS for NetworkStats
  [SP26.2] add a method in NetworkStats that removes empty entries
parents e0aedb2e 863f3908
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -1195,18 +1195,24 @@ public final class NetworkStats implements Parcelable {

    /**
     * Remove all rows that match one of specified UIDs.
     * This mutates the original structure in place.
     * @hide
     */
    public void removeUids(int[] uids) {
        int nextOutputEntry = 0;
        for (int i = 0; i < size; i++) {
            if (!ArrayUtils.contains(uids, uid[i])) {
                maybeCopyEntry(nextOutputEntry, i);
                nextOutputEntry++;
            }
        filter(e -> !ArrayUtils.contains(uids, e.uid));
    }

        size = nextOutputEntry;
    /**
     * Remove all rows that match one of specified UIDs.
     * @return the result object.
     * @hide
     */
    @NonNull
    public NetworkStats removeEmptyEntries() {
        final NetworkStats ret = this.clone();
        ret.filter(e -> e.rxBytes != 0 || e.rxPackets != 0 || e.txBytes != 0 || e.txPackets != 0
                || e.operations != 0);
        return ret;
    }

    /**
+209 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.netstats

import android.net.NetworkStats
import android.net.NetworkStats.DEFAULT_NETWORK_NO
import android.net.NetworkStats.DEFAULT_NETWORK_YES
import android.net.NetworkStats.Entry
import android.net.NetworkStats.IFACE_VT
import android.net.NetworkStats.METERED_NO
import android.net.NetworkStats.METERED_YES
import android.net.NetworkStats.ROAMING_NO
import android.net.NetworkStats.ROAMING_YES
import android.net.NetworkStats.SET_DEFAULT
import android.net.NetworkStats.SET_FOREGROUND
import android.net.NetworkStats.TAG_NONE
import android.os.Build
import androidx.test.filters.SmallTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.assertFieldCountEquals
import com.android.testutils.assertNetworkStatsEquals
import com.android.testutils.assertParcelingIsLossless
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import kotlin.test.assertEquals

@RunWith(JUnit4::class)
@SmallTest
class NetworkStatsApiTest {
    @Rule
    @JvmField
    val ignoreRule = DevSdkIgnoreRule()

    private val testStatsEmpty = NetworkStats(0L, 0)

    // stats1 and stats2 will have some entries with common keys, which are expected to
    // be merged if performing add on these 2 stats.
    private val testStats1 = NetworkStats(0L, 0)
            // Entries which only appear in set1.
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 37, 52, 1, 10, 4))
            // Entries which are common for set1 and set2.
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 17, 2, 11, 1, 0))
            .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 40, 1, 0, 0, 8))
            .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 1, 6, 2, 0))

    private val testStats2 = NetworkStats(0L, 0)
            // Entries which are common for set1 and set2.
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45))
            .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7))
            .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0))
            // Entry which only appears in set2.
            .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0))

    // This is a result of adding stats1 and stats2, while the merging of common key items is
    // subject to test later, this should not be initialized with for a loop to add stats1
    // and stats2 above.
    private val testStats3 = NetworkStats(0L, 9)
            // Entries which are unique either in stats1 or stats2.
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2))
            .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0))
            // Entries which are common for stats1 and stats2 are being merged.
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 20, 17, 13, 32, 1))
            .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 50, 113, 11, 11, 49))
            .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 51, 3, 3, 4, 15))
            .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7, 4, 8, 3, 0))

    companion object {
        private const val TEST_IFACE = "test0"
        private const val TEST_UID1 = 1001
        private const val TEST_UID2 = 1002
    }

    @Before
    fun setUp() {
        assertEquals(8, testStats1.size())
        assertEquals(5, testStats2.size())
        assertEquals(9, testStats3.size())
    }

    @Test
    @IgnoreUpTo(Build.VERSION_CODES.Q)
    fun testAddEntry() {
        val expectedEntriesInStats2 = arrayOf(
                Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80,
                        METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1),
                Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE,
                        METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45),
                Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE,
                        METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7),
                Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE,
                        METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0),
                Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE,
                        METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0))

        // While testStats* are already initialized with addEntry, verify content added
        // matches expectation.
        for (i in expectedEntriesInStats2.indices) {
            val entry = testStats2.getValues(i, null)
            assertEquals(expectedEntriesInStats2[i], entry)
        }

        // Verify entry updated with addEntry.
        val stats = testStats2.addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE,
                METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12, -5, 7, 0, 9))
        assertEquals(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE,
                METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16, -2, 9, 1, 9),
                stats.getValues(3, null))
    }

    @Test
    @IgnoreUpTo(Build.VERSION_CODES.Q)
    fun testAdd() {
        var stats = NetworkStats(0L, 0)
        assertNetworkStatsEquals(testStatsEmpty, stats)
        stats = stats.add(testStats2)
        assertNetworkStatsEquals(testStats2, stats)
        stats = stats.add(testStats1)
        // EMPTY + STATS2 + STATS1 = STATS3
        assertNetworkStatsEquals(testStats3, stats)
    }

    @Test
    @IgnoreUpTo(Build.VERSION_CODES.Q)
    fun testParcelUnparcel() {
        assertParcelingIsLossless(testStatsEmpty)
        assertParcelingIsLossless(testStats1)
        assertParcelingIsLossless(testStats2)
        assertFieldCountEquals(15, NetworkStats::class.java)
    }

    @Test
    @IgnoreUpTo(Build.VERSION_CODES.Q)
    fun testDescribeContents() {
        assertEquals(0, testStatsEmpty.describeContents())
        assertEquals(0, testStats1.describeContents())
        assertEquals(0, testStats2.describeContents())
        assertEquals(0, testStats3.describeContents())
    }

    @Test
    @IgnoreUpTo(Build.VERSION_CODES.Q)
    fun testSubtract() {
        // STATS3 - STATS2 = STATS1
        assertNetworkStatsEquals(testStats1, testStats3.subtract(testStats2))
        // STATS3 - STATS1 = STATS2
        assertNetworkStatsEquals(testStats2, testStats3.subtract(testStats1))
    }

    @Test
    @IgnoreUpTo(Build.VERSION_CODES.Q)
    fun testMethodsDontModifyReceiver() {
        listOf(testStatsEmpty, testStats1, testStats2, testStats3).forEach {
            val origStats = it.clone()
            it.addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE,
                    METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45))
            it.add(testStats3)
            it.subtract(testStats1)
            assertNetworkStatsEquals(origStats, it)
        }
    }
}
 No newline at end of file
+47 −0
Original line number Diff line number Diff line
@@ -502,6 +502,53 @@ public class NetworkStatsTest {
                DEFAULT_NETWORK_NO, 64L, 2L, 0L, 0L, 0L);
    }

    @Test
    public void testRemoveEmptyEntries() throws Exception {
        // Test empty stats.
        final NetworkStats statsEmpty = new NetworkStats(TEST_START, 3);
        assertEquals(0, statsEmpty.removeEmptyEntries().size());

        // Test stats with non-zero entry.
        final NetworkStats statsNonZero = new NetworkStats(TEST_START, 1)
                .insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO,
                        ROAMING_NO, DEFAULT_NETWORK_NO, 1L, 128L, 0L, 2L, 20L);
        assertEquals(1, statsNonZero.size());
        final NetworkStats expectedNonZero = statsNonZero.removeEmptyEntries();
        assertEquals(1, expectedNonZero.size());
        assertValues(expectedNonZero, 0, TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO,
                ROAMING_NO, DEFAULT_NETWORK_NO, 1L, 128L, 0L, 2L, 20L);

        // Test stats with empty entry.
        final NetworkStats statsZero = new NetworkStats(TEST_START, 1)
                .insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO,
                        ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
        assertEquals(1, statsZero.size());
        final NetworkStats expectedZero = statsZero.removeEmptyEntries();
        assertEquals(1, statsZero.size()); // Assert immutable.
        assertEquals(0, expectedZero.size());

        // Test stats with multiple entries.
        final NetworkStats statsMultiple = new NetworkStats(TEST_START, 0)
                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 0L, 0L)
                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 0L, 0L)
                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 0L, 8L, 0L, 0L, 0L)
                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 4L, 0L, 0L)
                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 2L, 0L)
                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 0L, 1L);
        assertEquals(9, statsMultiple.size());
        final NetworkStats expectedMultiple = statsMultiple.removeEmptyEntries();
        assertEquals(9, statsMultiple.size()); // Assert immutable.
        assertEquals(7, expectedMultiple.size());
        assertValues(expectedMultiple.getTotalIncludingTags(null), 14L, 104L, 4L, 4L, 21L);

        // Test stats with multiple empty entries.
        assertEquals(statsMultiple.size(), statsMultiple.subtract(statsMultiple).size());
        assertEquals(0, statsMultiple.subtract(statsMultiple).removeEmptyEntries().size());
    }

    @Test
    public void testClone() throws Exception {
        final NetworkStats original = new NetworkStats(TEST_START, 5)