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.DevSdkIgnoreRule 34 import com.android.testutils.assertNetworkStatsEquals 35 import com.android.testutils.assertParcelingIsLossless 36 import org.junit.Before 37 import org.junit.Rule 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 import org.junit.runners.JUnit4 41 import kotlin.test.assertEquals 42 43 @RunWith(JUnit4::class) 44 @SmallTest 45 class NetworkStatsApiTest { 46 @Rule 47 @JvmField 48 val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) 49 50 private val testStatsEmpty = NetworkStats(0L, 0) 51 52 // Note that these variables need to be initialized outside of constructor, initialize 53 // here with methods that don't exist in Q devices will result in crash. 54 55 // stats1 and stats2 will have some entries with common keys, which are expected to 56 // be merged if performing add on these 2 stats. 57 private lateinit var testStats1: NetworkStats 58 private lateinit var testStats2: NetworkStats 59 60 // This is a result of adding stats1 and stats2, while the merging of common key items is 61 // subject to test later, this should not be initialized with for a loop to add stats1 62 // and stats2 above. 63 private lateinit var testStats3: NetworkStats 64 65 companion object { 66 private const val TEST_IFACE = "test0" 67 private const val TEST_UID1 = 1001 68 private const val TEST_UID2 = 1002 69 } 70 71 @Before 72 fun setUp() { 73 testStats1 = NetworkStats(0L, 0) 74 // Entries which only appear in set1. 75 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 76 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3)) 77 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 78 METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8)) 79 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 80 METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2)) 81 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 82 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 37, 52, 1, 10, 4)) 83 // Entries which are common for set1 and set2. 84 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 85 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5)) 86 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 87 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 17, 2, 11, 1, 0)) 88 .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 89 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 40, 1, 0, 0, 8)) 90 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 91 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 1, 6, 2, 0)) 92 assertEquals(8, testStats1.size()) 93 94 testStats2 = NetworkStats(0L, 0) 95 // Entries which are common for set1 and set2. 96 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 97 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1)) 98 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 99 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45)) 100 .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 101 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7)) 102 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 103 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0)) 104 // Entry which only appears in set2. 105 .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, 106 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) 107 assertEquals(5, testStats2.size()) 108 109 testStats3 = NetworkStats(0L, 9) 110 // Entries which are unique either in stats1 or stats2. 111 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 112 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5)) 113 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 114 METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8)) 115 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 116 METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2)) 117 .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, 118 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) 119 // Entries which are common for stats1 and stats2 are being merged. 120 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, 121 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3)) 122 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 123 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 20, 17, 13, 32, 1)) 124 .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 125 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 50, 113, 11, 11, 49)) 126 .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 127 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 51, 3, 3, 4, 15)) 128 .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 129 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7, 4, 8, 3, 0)) 130 assertEquals(9, testStats3.size()) 131 } 132 133 @Test 134 fun testAddEntry() { 135 val expectedEntriesInStats2 = arrayOf( 136 Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, 137 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1), 138 Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 139 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45), 140 Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, 141 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7), 142 Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 143 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0), 144 Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, 145 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) 146 147 // While testStats* are already initialized with addEntry, verify content added 148 // matches expectation. 149 for (i in expectedEntriesInStats2.indices) { 150 val entry = testStats2.getValues(i, null) 151 assertEquals(expectedEntriesInStats2[i], entry) 152 } 153 154 // Verify entry updated with addEntry. 155 val stats = testStats2.addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 156 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12, -5, 7, 0, 9)) 157 assertEquals(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, 158 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16, -2, 9, 1, 9), 159 stats.getValues(3, null)) 160 } 161 162 @Test 163 fun testAdd() { 164 var stats = NetworkStats(0L, 0) 165 assertNetworkStatsEquals(testStatsEmpty, stats) 166 stats = stats.add(testStats2) 167 assertNetworkStatsEquals(testStats2, stats) 168 stats = stats.add(testStats1) 169 // EMPTY + STATS2 + STATS1 = STATS3 170 assertNetworkStatsEquals(testStats3, stats) 171 } 172 173 @Test 174 fun testParcelUnparcel() { 175 assertParcelingIsLossless(testStatsEmpty) 176 assertParcelingIsLossless(testStats1) 177 assertParcelingIsLossless(testStats2) 178 } 179 180 @Test 181 fun testDescribeContents() { 182 assertEquals(0, testStatsEmpty.describeContents()) 183 assertEquals(0, testStats1.describeContents()) 184 assertEquals(0, testStats2.describeContents()) 185 assertEquals(0, testStats3.describeContents()) 186 } 187 188 @Test 189 fun testSubtract() { 190 // STATS3 - STATS2 = STATS1 191 assertNetworkStatsEquals(testStats1, testStats3.subtract(testStats2)) 192 // STATS3 - STATS1 = STATS2 193 assertNetworkStatsEquals(testStats2, testStats3.subtract(testStats1)) 194 } 195 196 @Test 197 fun testMethodsDontModifyReceiver() { 198 listOf(testStatsEmpty, testStats1, testStats2, testStats3).forEach { 199 val origStats = it.clone() 200 it.addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, 201 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45)) 202 it.add(testStats3) 203 it.subtract(testStats1) 204 assertNetworkStatsEquals(origStats, it) 205 } 206 } 207 }