1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.netstats 18 19 import android.net.NetworkStats 20 import android.net.NetworkStats.DEFAULT_NETWORK_NO 21 import android.net.NetworkStats.DEFAULT_NETWORK_YES 22 import android.net.NetworkStats.Entry 23 import android.net.NetworkStats.IFACE_VT 24 import android.net.NetworkStats.METERED_NO 25 import android.net.NetworkStats.METERED_YES 26 import android.net.NetworkStats.ROAMING_NO 27 import android.net.NetworkStats.ROAMING_YES 28 import android.net.NetworkStats.SET_DEFAULT 29 import android.net.NetworkStats.SET_FOREGROUND 30 import android.net.NetworkStats.TAG_NONE 31 import android.os.Build 32 import androidx.test.filters.SmallTest 33 import com.android.testutils.ConnectivityModuleTest 34 import com.android.testutils.DevSdkIgnoreRule 35 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 36 import com.android.testutils.DevSdkIgnoreRunner 37 import com.android.testutils.assertNetworkStatsEquals 38 import com.android.testutils.assertParcelingIsLossless 39 import kotlin.test.assertEquals 40 import org.junit.Before 41 import org.junit.Rule 42 import org.junit.Test 43 import org.junit.runner.RunWith 44 45 @DevSdkIgnoreRunner.MonitorThreadLeak 46 @RunWith(DevSdkIgnoreRunner::class) 47 @SmallTest 48 class NetworkStatsApiTest { 49 @get:Rule 50 val ignoreRule = DevSdkIgnoreRule() 51 private val testStatsEmpty = NetworkStats(0L, 0) 52 53 // Note that these variables need to be initialized outside of constructor, initialize 54 // here with methods that don't exist in Q devices will result in crash. 55 56 // stats1 and stats2 will have some entries with common keys, which are expected to 57 // be merged if performing add on these 2 stats. 58 private lateinit var testStats1: NetworkStats 59 private lateinit var testStats2: NetworkStats 60 private lateinit var expectedEntriesInStats2: List<Entry> 61 62 // This is a result of adding stats1 and stats2, while the merging of common key items is 63 // subject to test later, this should not be initialized with for a loop to add stats1 64 // and stats2 above. 65 private lateinit var testStats3: NetworkStats 66 67 companion object { 68 private const val TEST_IFACE = "test0" 69 private const val TEST_UID1 = 1001 70 private const val TEST_UID2 = 1002 71 } 72 73 @Before setUpnull74 fun setUp() { 75 testStats1 = NetworkStats(0L, 0) 76 // Entries which only appear in set1. 77 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 78 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3)) 79 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 80 METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8)) 81 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 82 METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2)) 83 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 84 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 37, 52, 1, 10, 4)) 85 // Entries which are common for set1 and set2. 86 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 87 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5)) 88 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 89 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 17, 2, 11, 1, 0)) 90 .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 91 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 40, 1, 0, 0, 8)) 92 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 93 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 1, 6, 2, 0)) 94 assertEquals(8, testStats1.size()) 95 96 expectedEntriesInStats2 = listOf( 97 // Entries which are common for set1 and set2. 98 Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 99 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1), 100 Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 101 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45), 102 Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 103 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7), 104 Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 105 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0), 106 // Entry which only appears in set2. 107 Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, 108 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) 109 testStats2 = NetworkStats(0L, 5) 110 for (entry in expectedEntriesInStats2) { 111 testStats2 = testStats2.addEntry(entry) 112 } 113 assertEquals(5, testStats2.size()) 114 115 testStats3 = NetworkStats(0L, 9) 116 // Entries which are unique either in stats1 or stats2. 117 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 118 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5)) 119 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 120 METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8)) 121 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 122 METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2)) 123 .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, 124 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) 125 // Entries which are common for stats1 and stats2 are being merged. 126 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 127 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3)) 128 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 129 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 20, 17, 13, 32, 1)) 130 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 131 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 50, 113, 11, 11, 49)) 132 .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 133 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 51, 3, 3, 4, 15)) 134 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 135 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7, 4, 8, 3, 0)) 136 assertEquals(9, testStats3.size()) 137 } 138 139 @Test testAddEntrynull140 fun testAddEntry() { 141 // While testStats* are already initialized with addEntry, verify content added 142 // matches expectation. 143 for (i in expectedEntriesInStats2.indices) { 144 val entry = testStats2.getValues(i, null) 145 assertEquals(expectedEntriesInStats2[i], entry) 146 } 147 148 // Verify entry updated with addEntry. 149 val stats = testStats2.addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 150 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12, -5, 7, 0, 9)) 151 assertEquals(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 152 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16, -2, 9, 1, 9), 153 stats.getValues(3, null)) 154 155 // Verify the original ststs object is not altered. 156 for (i in expectedEntriesInStats2.indices) { 157 val entry = testStats2.getValues(i, null) 158 assertEquals(expectedEntriesInStats2[i], entry) 159 } 160 } 161 162 @ConnectivityModuleTest 163 @IgnoreUpTo(Build.VERSION_CODES.S_V2) // Mainlined NetworkStats only runs on T+ 164 @Test testAddEntriesnull165 fun testAddEntries() { 166 val baseStats = NetworkStats(0L, 1) 167 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 168 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12, -5, 7, 0, 9)) 169 val statsUnderTest = baseStats.addEntries(expectedEntriesInStats2) 170 // Assume the correctness of addEntry is verified in other tests. 171 val expectedStats = testStats2 172 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 173 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12, -5, 7, 0, 9)) 174 assertNetworkStatsEquals(expectedStats, statsUnderTest) 175 } 176 177 @Test testAddnull178 fun testAdd() { 179 var stats = NetworkStats(0L, 0) 180 assertNetworkStatsEquals(testStatsEmpty, stats) 181 stats = stats.add(testStats2) 182 assertNetworkStatsEquals(testStats2, stats) 183 stats = stats.add(testStats1) 184 // EMPTY + STATS2 + STATS1 = STATS3 185 assertNetworkStatsEquals(testStats3, stats) 186 } 187 188 @Test testParcelUnparcelnull189 fun testParcelUnparcel() { 190 assertParcelingIsLossless(testStatsEmpty) 191 assertParcelingIsLossless(testStats1) 192 assertParcelingIsLossless(testStats2) 193 } 194 195 @Test testDescribeContentsnull196 fun testDescribeContents() { 197 assertEquals(0, testStatsEmpty.describeContents()) 198 assertEquals(0, testStats1.describeContents()) 199 assertEquals(0, testStats2.describeContents()) 200 assertEquals(0, testStats3.describeContents()) 201 } 202 203 @Test testSubtractnull204 fun testSubtract() { 205 // STATS3 - STATS2 = STATS1 206 assertNetworkStatsEquals(testStats1, testStats3.subtract(testStats2)) 207 // STATS3 - STATS1 = STATS2 208 assertNetworkStatsEquals(testStats2, testStats3.subtract(testStats1)) 209 } 210 211 @Test testMethodsDontModifyReceivernull212 fun testMethodsDontModifyReceiver() { 213 listOf(testStatsEmpty, testStats1, testStats2, testStats3).forEach { 214 val origStats = it.clone() 215 it.addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 216 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45)) 217 it.add(testStats3) 218 it.subtract(testStats1) 219 assertNetworkStatsEquals(origStats, it) 220 } 221 } 222 }