NetworkStatsFactoryTest.java revision 4a0c5d7ef7144280fe8a209a871bbd4ef90d6368
1/*
2 * Copyright (C) 2011 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
17package com.android.internal.net;
18
19import static android.net.NetworkStats.METERED_NO;
20import static android.net.NetworkStats.ROAMING_NO;
21import static android.net.NetworkStats.SET_ALL;
22import static android.net.NetworkStats.SET_DEFAULT;
23import static android.net.NetworkStats.SET_FOREGROUND;
24import static android.net.NetworkStats.TAG_NONE;
25import static android.net.NetworkStats.UID_ALL;
26import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
27import static org.junit.Assert.assertEquals;
28import static org.junit.Assert.fail;
29
30import android.content.res.Resources;
31import android.net.NetworkStats;
32import android.net.TrafficStats;
33import android.support.test.InstrumentationRegistry;
34import android.support.test.filters.SmallTest;
35import android.support.test.runner.AndroidJUnit4;
36
37import com.android.frameworks.tests.net.R;
38
39import java.io.File;
40import java.io.FileOutputStream;
41import java.io.FileWriter;
42import java.io.InputStream;
43import java.io.OutputStream;
44
45import libcore.io.IoUtils;
46import libcore.io.Streams;
47
48import org.junit.runner.RunWith;
49import org.junit.After;
50import org.junit.Before;
51import org.junit.Test;
52
53/**
54 * Tests for {@link NetworkStatsFactory}.
55 */
56@RunWith(AndroidJUnit4.class)
57@SmallTest
58public class NetworkStatsFactoryTest {
59    private File mTestProc;
60    private NetworkStatsFactory mFactory;
61
62    @Before
63    public void setUp() throws Exception {
64        mTestProc = new File(InstrumentationRegistry.getContext().getFilesDir(), "proc");
65        if (mTestProc.exists()) {
66            IoUtils.deleteContents(mTestProc);
67        }
68
69        mFactory = new NetworkStatsFactory(mTestProc);
70    }
71
72    @After
73    public void tearDown() throws Exception {
74        mFactory = null;
75
76        if (mTestProc.exists()) {
77            IoUtils.deleteContents(mTestProc);
78        }
79    }
80
81    @Test
82    public void testNetworkStatsDetail() throws Exception {
83        final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
84
85        assertEquals(70, stats.size());
86        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 18621L, 2898L);
87        assertStatsEntry(stats, "wlan0", 10011, SET_DEFAULT, 0x0, 35777L, 5718L);
88        assertStatsEntry(stats, "wlan0", 10021, SET_DEFAULT, 0x7fffff01, 562386L, 49228L);
89        assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 227423L);
90        assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L);
91    }
92
93    @Test
94    public void testKernelTags() throws Exception {
95        assertEquals(0, kernelToTag("0x0000000000000000"));
96        assertEquals(0x32, kernelToTag("0x0000003200000000"));
97        assertEquals(2147483647, kernelToTag("0x7fffffff00000000"));
98        assertEquals(0, kernelToTag("0x0000000000000000"));
99        assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000"));
100
101        assertEquals(0, kernelToTag("0x0"));
102        assertEquals(0, kernelToTag("0xf00d"));
103        assertEquals(1, kernelToTag("0x100000000"));
104        assertEquals(14438007, kernelToTag("0xdc4e7700000000"));
105        assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000"));
106    }
107
108    @Test
109    public void testNetworkStatsWithSet() throws Exception {
110        final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
111        assertEquals(70, stats.size());
112        assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L,
113                676L);
114        assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
115    }
116
117    @Test
118    public void testNetworkStatsSingle() throws Exception {
119        stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all"));
120
121        final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
122        assertEquals(6, stats.size());
123        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 2112L, 24L, 700L, 10L);
124        assertStatsEntry(stats, "test1", UID_ALL, SET_ALL, TAG_NONE, 6L, 8L, 10L, 12L);
125        assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
126    }
127
128    @Test
129    public void testNetworkStatsXt() throws Exception {
130        stageFile(R.raw.xt_qtaguid_iface_fmt_typical, file("net/xt_qtaguid/iface_stat_fmt"));
131
132        final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
133        assertEquals(3, stats.size());
134        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L);
135        assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L,
136                2468L);
137        assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
138    }
139
140    @Test
141    public void testDoubleClatAccounting() throws Exception {
142        NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
143
144        // xt_qtaguid_with_clat_simple is a synthetic file that simulates
145        //  - 213 received 464xlat packets of size 200 bytes
146        //  - 41 sent 464xlat packets of size 100 bytes
147        //  - no other traffic on base interface for root uid.
148        NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_simple);
149        assertEquals(4, stats.size());
150
151        assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 46860L, 4920L);
152        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L);
153
154        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat);
155        assertEquals(42, stats.size());
156
157        assertStatsEntry(stats, "v4-wlan0", 0, SET_DEFAULT, 0x0, 356L, 276L);
158        assertStatsEntry(stats, "v4-wlan0", 1000, SET_DEFAULT, 0x0, 30812L, 2310L);
159        assertStatsEntry(stats, "v4-wlan0", 10102, SET_DEFAULT, 0x0, 10022L, 3330L);
160        assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 9532772L, 254112L);
161        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 15229L, 5766L);
162        assertStatsEntry(stats, "wlan0", 1000, SET_DEFAULT, 0x0, 6126L, 2013L);
163        assertStatsEntry(stats, "wlan0", 10013, SET_DEFAULT, 0x0, 0L, 144L);
164        assertStatsEntry(stats, "wlan0", 10018, SET_DEFAULT, 0x0, 5980263L, 167667L);
165        assertStatsEntry(stats, "wlan0", 10060, SET_DEFAULT, 0x0, 134356L, 8705L);
166        assertStatsEntry(stats, "wlan0", 10079, SET_DEFAULT, 0x0, 10926L, 1507L);
167        assertStatsEntry(stats, "wlan0", 10102, SET_DEFAULT, 0x0, 25038L, 8245L);
168        assertStatsEntry(stats, "wlan0", 10103, SET_DEFAULT, 0x0, 0L, 192L);
169        assertStatsEntry(stats, "dummy0", 0, SET_DEFAULT, 0x0, 0L, 168L);
170        assertStatsEntry(stats, "lo", 0, SET_DEFAULT, 0x0, 1288L, 1288L);
171
172        NetworkStatsFactory.noteStackedIface("v4-wlan0", null);
173    }
174
175    @Test
176    public void testDoubleClatAccounting100MBDownload() throws Exception {
177        // Downloading 100mb from an ipv4 only destination in a foreground activity
178
179        long appRxBytesBefore = 328684029L;
180        long appRxBytesAfter = 439237478L;
181        assertEquals("App traffic should be ~100MB", 110553449, appRxBytesAfter - appRxBytesBefore);
182
183        long rootRxBytesBefore = 1394011L;
184        long rootRxBytesAfter = 1398634L;
185        assertEquals("UID 0 traffic should be ~0", 4623, rootRxBytesAfter - rootRxBytesBefore);
186
187        NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
188        NetworkStats stats;
189
190        // Stats snapshot before the download
191        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_before);
192        assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesBefore, 5199872L);
193        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytesBefore, 647888L);
194
195        // Stats snapshot after the download
196        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_after);
197        assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesAfter, 7867488L);
198        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytesAfter, 647587L);
199
200        NetworkStatsFactory.noteStackedIface("v4-wlan0", null);
201    }
202
203    /**
204     * Copy a {@link Resources#openRawResource(int)} into {@link File} for
205     * testing purposes.
206     */
207    private void stageFile(int rawId, File file) throws Exception {
208        new File(file.getParent()).mkdirs();
209        InputStream in = null;
210        OutputStream out = null;
211        try {
212            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
213            out = new FileOutputStream(file);
214            Streams.copy(in, out);
215        } finally {
216            IoUtils.closeQuietly(in);
217            IoUtils.closeQuietly(out);
218        }
219    }
220
221    private void stageLong(long value, File file) throws Exception {
222        new File(file.getParent()).mkdirs();
223        FileWriter out = null;
224        try {
225            out = new FileWriter(file);
226            out.write(Long.toString(value));
227        } finally {
228            IoUtils.closeQuietly(out);
229        }
230    }
231
232    private File file(String path) throws Exception {
233        return new File(mTestProc, path);
234    }
235
236    private NetworkStats parseDetailedStats(int resourceId) throws Exception {
237        stageFile(resourceId, file("net/xt_qtaguid/stats"));
238        return mFactory.readNetworkStatsDetail();
239    }
240
241    private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
242            int tag, long rxBytes, long txBytes) {
243        final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
244        if (i < 0) {
245            fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)",
246                    iface, uid, set, tag));
247        }
248        final NetworkStats.Entry entry = stats.getValues(i, null);
249        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
250        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
251    }
252
253    private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
254            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
255        final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
256        if (i < 0) {
257            fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)",
258                    iface, uid, set, tag));
259        }
260        final NetworkStats.Entry entry = stats.getValues(i, null);
261        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
262        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
263        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
264        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
265    }
266}
267