1 /*
2  * Copyright (C) 2022 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.NetworkStatsCollection
20 import androidx.test.InstrumentationRegistry
21 import androidx.test.filters.SmallTest
22 import com.android.frameworks.tests.net.R
23 import com.android.testutils.DevSdkIgnoreRule
24 import com.android.testutils.DevSdkIgnoreRunner
25 import com.android.testutils.SC_V2
26 import org.junit.Before
27 import org.junit.Test
28 import org.junit.runner.RunWith
29 import org.mockito.MockitoAnnotations
30 import java.io.DataInputStream
31 import java.net.ProtocolException
32 import kotlin.test.assertEquals
33 import kotlin.test.assertFailsWith
34 import kotlin.test.fail
35 
36 private const val BUCKET_DURATION_MS = 2 * 60 * 60 * 1000L
37 
38 @RunWith(DevSdkIgnoreRunner::class)
39 @SmallTest
40 @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
41 class NetworkStatsDataMigrationUtilsTest {
42     @Before
setupnull43     fun setup() {
44         MockitoAnnotations.initMocks(this)
45     }
46 
47     @Test
testReadPlatformCollectionnull48     fun testReadPlatformCollection() {
49         // Verify the method throws for wrong file format.
50         assertFailsWith<ProtocolException> {
51             NetworkStatsDataMigrationUtils.readPlatformCollection(
52                     NetworkStatsCollection.Builder(BUCKET_DURATION_MS),
53                     getInputStreamForResource(R.raw.netstats_uid_v4))
54         }
55 
56         val builder = NetworkStatsCollection.Builder(BUCKET_DURATION_MS)
57         NetworkStatsDataMigrationUtils.readPlatformCollection(builder,
58                 getInputStreamForResource(R.raw.netstats_uid_v16))
59         // The values are obtained by dumping from NetworkStatsCollection that
60         // read by the logic inside the service.
61         assertValues(builder.build(), 55, 1814302L, 21050L, 31001636L, 26152L)
62     }
63 
assertValuesnull64     private fun assertValues(
65         collection: NetworkStatsCollection,
66         expectedSize: Int,
67         expectedTxBytes: Long,
68         expectedTxPackets: Long,
69         expectedRxBytes: Long,
70         expectedRxPackets: Long
71     ) {
72         var txBytes = 0L
73         var txPackets = 0L
74         var rxBytes = 0L
75         var rxPackets = 0L
76         val entries = collection.entries
77 
78         for (history in entries.values) {
79             for (historyEntry in history.entries) {
80                 txBytes += historyEntry.txBytes
81                 txPackets += historyEntry.txPackets
82                 rxBytes += historyEntry.rxBytes
83                 rxPackets += historyEntry.rxPackets
84             }
85         }
86         if (expectedSize != entries.size ||
87                 expectedTxBytes != txBytes ||
88                 expectedTxPackets != txPackets ||
89                 expectedRxBytes != rxBytes ||
90                 expectedRxPackets != rxPackets) {
91             fail("expected size=$expectedSize" +
92                     "txb=$expectedTxBytes txp=$expectedTxPackets " +
93                     "rxb=$expectedRxBytes rxp=$expectedRxPackets bus was " +
94                     "size=${entries.size} txb=$txBytes txp=$txPackets " +
95                     "rxb=$rxBytes rxp=$rxPackets")
96         }
97         assertEquals(txBytes + rxBytes, collection.totalBytes)
98     }
99 
getInputStreamForResourcenull100     private fun getInputStreamForResource(resourceId: Int): DataInputStream {
101         return DataInputStream(InstrumentationRegistry.getContext()
102                 .getResources().openRawResource(resourceId))
103     }
104 }
105