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