NetworkStatsServiceTest.java revision 8fc27e8b87bd1def854a03d84009143b315d4176
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.server;
18
19import static android.content.Intent.ACTION_UID_REMOVED;
20import static android.content.Intent.EXTRA_UID;
21import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
22import static android.net.ConnectivityManager.TYPE_MOBILE;
23import static android.net.ConnectivityManager.TYPE_WIFI;
24import static android.net.ConnectivityManager.TYPE_WIMAX;
25import static android.net.NetworkStats.IFACE_ALL;
26import static android.net.NetworkStats.SET_ALL;
27import static android.net.NetworkStats.SET_DEFAULT;
28import static android.net.NetworkStats.SET_FOREGROUND;
29import static android.net.NetworkStats.TAG_NONE;
30import static android.net.NetworkStats.UID_ALL;
31import static android.net.NetworkStatsHistory.FIELD_ALL;
32import static android.net.NetworkTemplate.buildTemplateMobileAll;
33import static android.net.NetworkTemplate.buildTemplateWifi;
34import static android.net.TrafficStats.MB_IN_BYTES;
35import static android.net.TrafficStats.UID_REMOVED;
36import static android.net.TrafficStats.UID_TETHERING;
37import static android.text.format.DateUtils.DAY_IN_MILLIS;
38import static android.text.format.DateUtils.HOUR_IN_MILLIS;
39import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
40import static android.text.format.DateUtils.WEEK_IN_MILLIS;
41import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
42import static org.easymock.EasyMock.anyLong;
43import static org.easymock.EasyMock.aryEq;
44import static org.easymock.EasyMock.capture;
45import static org.easymock.EasyMock.createMock;
46import static org.easymock.EasyMock.eq;
47import static org.easymock.EasyMock.expect;
48import static org.easymock.EasyMock.expectLastCall;
49import static org.easymock.EasyMock.isA;
50
51import android.app.AlarmManager;
52import android.app.IAlarmManager;
53import android.app.PendingIntent;
54import android.content.Intent;
55import android.net.IConnectivityManager;
56import android.net.INetworkManagementEventObserver;
57import android.net.LinkProperties;
58import android.net.NetworkInfo;
59import android.net.NetworkInfo.DetailedState;
60import android.net.NetworkState;
61import android.net.NetworkStats;
62import android.net.NetworkStatsHistory;
63import android.net.NetworkTemplate;
64import android.os.INetworkManagementService;
65import android.telephony.TelephonyManager;
66import android.test.AndroidTestCase;
67import android.test.suitebuilder.annotation.LargeTest;
68import android.test.suitebuilder.annotation.Suppress;
69import android.util.TrustedTime;
70
71import com.android.server.net.NetworkStatsService;
72import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
73import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
74
75import org.easymock.Capture;
76import org.easymock.EasyMock;
77
78import java.io.File;
79
80import libcore.io.IoUtils;
81
82/**
83 * Tests for {@link NetworkStatsService}.
84 */
85@LargeTest
86public class NetworkStatsServiceTest extends AndroidTestCase {
87    private static final String TAG  = "NetworkStatsServiceTest";
88
89    private static final String TEST_IFACE = "test0";
90    private static final String TEST_IFACE2 = "test1";
91    private static final long TEST_START = 1194220800000L;
92
93    private static final String IMSI_1 = "310004";
94    private static final String IMSI_2 = "310260";
95
96    private static NetworkTemplate sTemplateWifi = buildTemplateWifi();
97    private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
98    private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
99
100    private static final int UID_RED = 1001;
101    private static final int UID_BLUE = 1002;
102    private static final int UID_GREEN = 1003;
103
104    private long mElapsedRealtime;
105
106    private BroadcastInterceptingContext mServiceContext;
107    private File mStatsDir;
108
109    private INetworkManagementService mNetManager;
110    private IAlarmManager mAlarmManager;
111    private TrustedTime mTime;
112    private NetworkStatsSettings mSettings;
113    private IConnectivityManager mConnManager;
114
115    private NetworkStatsService mService;
116    private INetworkManagementEventObserver mNetworkObserver;
117
118    @Override
119    public void setUp() throws Exception {
120        super.setUp();
121
122        mServiceContext = new BroadcastInterceptingContext(getContext());
123        mStatsDir = getContext().getFilesDir();
124        if (mStatsDir.exists()) {
125            IoUtils.deleteContents(mStatsDir);
126        }
127
128        mNetManager = createMock(INetworkManagementService.class);
129        mAlarmManager = createMock(IAlarmManager.class);
130        mTime = createMock(TrustedTime.class);
131        mSettings = createMock(NetworkStatsSettings.class);
132        mConnManager = createMock(IConnectivityManager.class);
133
134        mService = new NetworkStatsService(
135                mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
136        mService.bindConnectivityManager(mConnManager);
137
138        mElapsedRealtime = 0L;
139
140        expectCurrentTime();
141        expectDefaultSettings();
142        expectNetworkStatsSummary(buildEmptyStats());
143        expectNetworkStatsUidDetail(buildEmptyStats());
144        expectSystemReady();
145
146        // catch INetworkManagementEventObserver during systemReady()
147        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
148                INetworkManagementEventObserver>();
149        mNetManager.registerObserver(capture(networkObserver));
150        expectLastCall().atLeastOnce();
151
152        replay();
153        mService.systemReady();
154        verifyAndReset();
155
156        mNetworkObserver = networkObserver.getValue();
157
158    }
159
160    @Override
161    public void tearDown() throws Exception {
162        for (File file : mStatsDir.listFiles()) {
163            file.delete();
164        }
165
166        mServiceContext = null;
167        mStatsDir = null;
168
169        mNetManager = null;
170        mAlarmManager = null;
171        mTime = null;
172        mSettings = null;
173        mConnManager = null;
174
175        mService = null;
176
177        super.tearDown();
178    }
179
180    public void testNetworkStatsWifi() throws Exception {
181        // pretend that wifi network comes online; service should ask about full
182        // network state, and poll any existing interfaces before updating.
183        expectCurrentTime();
184        expectDefaultSettings();
185        expectNetworkState(buildWifiState());
186        expectNetworkStatsSummary(buildEmptyStats());
187        expectNetworkStatsUidDetail(buildEmptyStats());
188        expectNetworkStatsPoll();
189
190        replay();
191        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
192
193        // verify service has empty history for wifi
194        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
195        verifyAndReset();
196
197        // modify some number on wifi, and trigger poll event
198        incrementCurrentTime(HOUR_IN_MILLIS);
199        expectCurrentTime();
200        expectDefaultSettings();
201        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
202                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
203        expectNetworkStatsUidDetail(buildEmptyStats());
204        expectNetworkStatsPoll();
205
206        replay();
207        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
208
209        // verify service recorded history
210        assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
211        verifyAndReset();
212
213        // and bump forward again, with counters going higher. this is
214        // important, since polling should correctly subtract last snapshot.
215        incrementCurrentTime(DAY_IN_MILLIS);
216        expectCurrentTime();
217        expectDefaultSettings();
218        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
219                .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
220        expectNetworkStatsUidDetail(buildEmptyStats());
221        expectNetworkStatsPoll();
222
223        replay();
224        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
225
226        // verify service recorded history
227        assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
228        verifyAndReset();
229
230    }
231
232    public void testStatsRebootPersist() throws Exception {
233        assertStatsFilesExist(false);
234
235        // pretend that wifi network comes online; service should ask about full
236        // network state, and poll any existing interfaces before updating.
237        expectCurrentTime();
238        expectDefaultSettings();
239        expectNetworkState(buildWifiState());
240        expectNetworkStatsSummary(buildEmptyStats());
241        expectNetworkStatsUidDetail(buildEmptyStats());
242        expectNetworkStatsPoll();
243
244        replay();
245        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
246
247        // verify service has empty history for wifi
248        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
249        verifyAndReset();
250
251        // modify some number on wifi, and trigger poll event
252        incrementCurrentTime(HOUR_IN_MILLIS);
253        expectCurrentTime();
254        expectDefaultSettings();
255        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
256                .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
257        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
258                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
259                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
260                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
261                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
262                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
263        expectNetworkStatsPoll();
264
265        mService.setUidForeground(UID_RED, false);
266        mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
267        mService.setUidForeground(UID_RED, true);
268        mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
269
270        replay();
271        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
272
273        // verify service recorded history
274        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
275        assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
276        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
277        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
278        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
279        verifyAndReset();
280
281        // graceful shutdown system, which should trigger persist of stats, and
282        // clear any values in memory.
283        expectCurrentTime();
284        expectDefaultSettings();
285        replay();
286        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
287        verifyAndReset();
288
289        assertStatsFilesExist(true);
290
291        // boot through serviceReady() again
292        expectCurrentTime();
293        expectDefaultSettings();
294        expectNetworkStatsSummary(buildEmptyStats());
295        expectNetworkStatsUidDetail(buildEmptyStats());
296        expectSystemReady();
297
298        // catch INetworkManagementEventObserver during systemReady()
299        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
300                INetworkManagementEventObserver>();
301        mNetManager.registerObserver(capture(networkObserver));
302        expectLastCall().atLeastOnce();
303
304        replay();
305        mService.systemReady();
306
307        mNetworkObserver = networkObserver.getValue();
308
309        // after systemReady(), we should have historical stats loaded again
310        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
311        assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
312        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
313        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
314        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
315        verifyAndReset();
316
317    }
318
319    // TODO: simulate reboot to test bucket resize
320    @Suppress
321    public void testStatsBucketResize() throws Exception {
322        NetworkStatsHistory history = null;
323
324        assertStatsFilesExist(false);
325
326        // pretend that wifi network comes online; service should ask about full
327        // network state, and poll any existing interfaces before updating.
328        expectCurrentTime();
329        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
330        expectNetworkState(buildWifiState());
331        expectNetworkStatsSummary(buildEmptyStats());
332        expectNetworkStatsUidDetail(buildEmptyStats());
333        expectNetworkStatsPoll();
334
335        replay();
336        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
337        verifyAndReset();
338
339        // modify some number on wifi, and trigger poll event
340        incrementCurrentTime(2 * HOUR_IN_MILLIS);
341        expectCurrentTime();
342        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
343        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
344                .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
345        expectNetworkStatsUidDetail(buildEmptyStats());
346        expectNetworkStatsPoll();
347
348        replay();
349        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
350
351        // verify service recorded history
352        history = mService.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
353        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
354        assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
355        assertEquals(2, history.size());
356        verifyAndReset();
357
358        // now change bucket duration setting and trigger another poll with
359        // exact same values, which should resize existing buckets.
360        expectCurrentTime();
361        expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
362        expectNetworkStatsSummary(buildEmptyStats());
363        expectNetworkStatsUidDetail(buildEmptyStats());
364        expectNetworkStatsPoll();
365
366        replay();
367        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
368
369        // verify identical stats, but spread across 4 buckets now
370        history = mService.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
371        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
372        assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
373        assertEquals(4, history.size());
374        verifyAndReset();
375
376    }
377
378    public void testUidStatsAcrossNetworks() throws Exception {
379        // pretend first mobile network comes online
380        expectCurrentTime();
381        expectDefaultSettings();
382        expectNetworkState(buildMobile3gState(IMSI_1));
383        expectNetworkStatsSummary(buildEmptyStats());
384        expectNetworkStatsUidDetail(buildEmptyStats());
385        expectNetworkStatsPoll();
386
387        replay();
388        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
389        verifyAndReset();
390
391        // create some traffic on first network
392        incrementCurrentTime(HOUR_IN_MILLIS);
393        expectCurrentTime();
394        expectDefaultSettings();
395        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
396                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
397        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
398                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
399                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
400                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
401        expectNetworkStatsPoll();
402
403        mService.incrementOperationCount(UID_RED, 0xF00D, 10);
404
405        replay();
406        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
407
408        // verify service recorded history
409        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
410        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
411        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
412        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
413        verifyAndReset();
414
415        // now switch networks; this also tests that we're okay with interfaces
416        // disappearing, to verify we don't count backwards.
417        incrementCurrentTime(HOUR_IN_MILLIS);
418        expectCurrentTime();
419        expectDefaultSettings();
420        expectNetworkState(buildMobile3gState(IMSI_2));
421        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
422                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
423        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
424                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
425                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
426                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
427        expectNetworkStatsPoll();
428
429        replay();
430        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
431        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
432        verifyAndReset();
433
434        // create traffic on second network
435        incrementCurrentTime(HOUR_IN_MILLIS);
436        expectCurrentTime();
437        expectDefaultSettings();
438        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
439                .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
440        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
441                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
442                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
443                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
444                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
445        expectNetworkStatsPoll();
446
447        mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
448
449        replay();
450        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
451
452        // verify original history still intact
453        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
454        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
455        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
456
457        // and verify new history also recorded under different template, which
458        // verifies that we didn't cross the streams.
459        assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
460        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
461        assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
462        verifyAndReset();
463
464    }
465
466    public void testUidRemovedIsMoved() throws Exception {
467        // pretend that network comes online
468        expectCurrentTime();
469        expectDefaultSettings();
470        expectNetworkState(buildWifiState());
471        expectNetworkStatsSummary(buildEmptyStats());
472        expectNetworkStatsUidDetail(buildEmptyStats());
473        expectNetworkStatsPoll();
474
475        replay();
476        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
477        verifyAndReset();
478
479        // create some traffic
480        incrementCurrentTime(HOUR_IN_MILLIS);
481        expectCurrentTime();
482        expectDefaultSettings();
483        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
484                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
485        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
486                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
487                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
488                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
489                .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
490        expectNetworkStatsPoll();
491
492        mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
493
494        replay();
495        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
496
497        // verify service recorded history
498        assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
499        assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
500        assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
501        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
502        verifyAndReset();
503
504        // now pretend two UIDs are uninstalled, which should migrate stats to
505        // special "removed" bucket.
506        expectCurrentTime();
507        expectDefaultSettings();
508        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
509                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
510        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
511                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
512                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
513                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
514                .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
515        expectNetworkStatsPoll();
516
517        replay();
518        final Intent intent = new Intent(ACTION_UID_REMOVED);
519        intent.putExtra(EXTRA_UID, UID_BLUE);
520        mServiceContext.sendBroadcast(intent);
521        intent.putExtra(EXTRA_UID, UID_RED);
522        mServiceContext.sendBroadcast(intent);
523
524        // existing uid and total should remain unchanged; but removed UID
525        // should be gone completely.
526        assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
527        assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
528        assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
529        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
530        assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10);
531        verifyAndReset();
532
533    }
534
535    public void testUid3g4gCombinedByTemplate() throws Exception {
536        // pretend that network comes online
537        expectCurrentTime();
538        expectDefaultSettings();
539        expectNetworkState(buildMobile3gState(IMSI_1));
540        expectNetworkStatsSummary(buildEmptyStats());
541        expectNetworkStatsUidDetail(buildEmptyStats());
542        expectNetworkStatsPoll();
543
544        replay();
545        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
546        verifyAndReset();
547
548        // create some traffic
549        incrementCurrentTime(HOUR_IN_MILLIS);
550        expectCurrentTime();
551        expectDefaultSettings();
552        expectNetworkStatsSummary(buildEmptyStats());
553        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
554                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
555                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
556        expectNetworkStatsPoll();
557
558        mService.incrementOperationCount(UID_RED, 0xF00D, 5);
559
560        replay();
561        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
562
563        // verify service recorded history
564        assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
565        verifyAndReset();
566
567        // now switch over to 4g network
568        incrementCurrentTime(HOUR_IN_MILLIS);
569        expectCurrentTime();
570        expectDefaultSettings();
571        expectNetworkState(buildMobile4gState(TEST_IFACE2));
572        expectNetworkStatsSummary(buildEmptyStats());
573        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
574                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
575                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
576        expectNetworkStatsPoll();
577
578        replay();
579        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
580        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
581        verifyAndReset();
582
583        // create traffic on second network
584        incrementCurrentTime(HOUR_IN_MILLIS);
585        expectCurrentTime();
586        expectDefaultSettings();
587        expectNetworkStatsSummary(buildEmptyStats());
588        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
589                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
590                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
591                .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
592                .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
593        expectNetworkStatsPoll();
594
595        mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
596
597        replay();
598        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
599
600        // verify that ALL_MOBILE template combines both
601        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
602
603        verifyAndReset();
604    }
605
606    public void testSummaryForAllUid() throws Exception {
607        // pretend that network comes online
608        expectCurrentTime();
609        expectDefaultSettings();
610        expectNetworkState(buildWifiState());
611        expectNetworkStatsSummary(buildEmptyStats());
612        expectNetworkStatsUidDetail(buildEmptyStats());
613        expectNetworkStatsPoll();
614
615        replay();
616        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
617        verifyAndReset();
618
619        // create some traffic for two apps
620        incrementCurrentTime(HOUR_IN_MILLIS);
621        expectCurrentTime();
622        expectDefaultSettings();
623        expectNetworkStatsSummary(buildEmptyStats());
624        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
625                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
626                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
627                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
628        expectNetworkStatsPoll();
629
630        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
631
632        replay();
633        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
634
635        // verify service recorded history
636        assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
637        assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
638        verifyAndReset();
639
640        // now create more traffic in next hour, but only for one app
641        incrementCurrentTime(HOUR_IN_MILLIS);
642        expectCurrentTime();
643        expectDefaultSettings();
644        expectNetworkStatsSummary(buildEmptyStats());
645        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
646                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
647                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
648                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
649        expectNetworkStatsPoll();
650
651        replay();
652        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
653
654        // first verify entire history present
655        NetworkStats stats = mService.getSummaryForAllUid(
656                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
657        assertEquals(3, stats.size());
658        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 1);
659        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 1);
660        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0);
661
662        // now verify that recent history only contains one uid
663        final long currentTime = currentTimeMillis();
664        stats = mService.getSummaryForAllUid(
665                sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
666        assertEquals(1, stats.size());
667        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0);
668
669        verifyAndReset();
670    }
671
672    public void testForegroundBackground() throws Exception {
673        // pretend that network comes online
674        expectCurrentTime();
675        expectDefaultSettings();
676        expectNetworkState(buildWifiState());
677        expectNetworkStatsSummary(buildEmptyStats());
678        expectNetworkStatsUidDetail(buildEmptyStats());
679        expectNetworkStatsPoll();
680
681        replay();
682        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
683        verifyAndReset();
684
685        // create some initial traffic
686        incrementCurrentTime(HOUR_IN_MILLIS);
687        expectCurrentTime();
688        expectDefaultSettings();
689        expectNetworkStatsSummary(buildEmptyStats());
690        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
691                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
692                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
693        expectNetworkStatsPoll();
694
695        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
696
697        replay();
698        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
699
700        // verify service recorded history
701        assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
702        verifyAndReset();
703
704        // now switch to foreground
705        incrementCurrentTime(HOUR_IN_MILLIS);
706        expectCurrentTime();
707        expectDefaultSettings();
708        expectNetworkStatsSummary(buildEmptyStats());
709        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
710                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
711                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
712                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
713                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
714        expectNetworkStatsPoll();
715
716        mService.setUidForeground(UID_RED, true);
717        mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
718
719        replay();
720        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
721
722        // test that we combined correctly
723        assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2);
724
725        // verify entire history present
726        final NetworkStats stats = mService.getSummaryForAllUid(
727                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
728        assertEquals(4, stats.size());
729        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 1);
730        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 1);
731        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 1);
732        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 1);
733
734        verifyAndReset();
735    }
736
737    public void testTethering() throws Exception {
738        // pretend first mobile network comes online
739        expectCurrentTime();
740        expectDefaultSettings();
741        expectNetworkState(buildMobile3gState(IMSI_1));
742        expectNetworkStatsSummary(buildEmptyStats());
743        expectNetworkStatsUidDetail(buildEmptyStats());
744        expectNetworkStatsPoll();
745
746        replay();
747        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
748        verifyAndReset();
749
750        // create some tethering traffic
751        incrementCurrentTime(HOUR_IN_MILLIS);
752        expectCurrentTime();
753        expectDefaultSettings();
754        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
755                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
756
757        final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
758                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
759        final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
760        final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
761                .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
762
763        expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
764        expectNetworkStatsPoll();
765
766        replay();
767        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
768
769        // verify service recorded history
770        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
771        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
772        assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
773        verifyAndReset();
774
775    }
776
777    private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
778            long txBytes, long txPackets, int operations) {
779        final NetworkStatsHistory history = mService.getHistoryForNetwork(template, FIELD_ALL);
780        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
781                txPackets, operations);
782    }
783
784    private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
785            long txBytes, long txPackets, int operations) {
786        assertUidTotal(template, uid, SET_ALL, rxBytes, rxPackets, txBytes, txPackets, operations);
787    }
788
789    private void assertUidTotal(NetworkTemplate template, int uid, int set, long rxBytes,
790            long rxPackets, long txBytes, long txPackets, int operations) {
791        final NetworkStatsHistory history = mService.getHistoryForUid(
792                template, uid, set, TAG_NONE, FIELD_ALL);
793        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
794                txPackets, operations);
795    }
796
797    private void expectSystemReady() throws Exception {
798        mAlarmManager.remove(isA(PendingIntent.class));
799        expectLastCall().anyTimes();
800
801        mAlarmManager.setInexactRepeating(
802                eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
803        expectLastCall().atLeastOnce();
804
805        mNetManager.setGlobalAlert(anyLong());
806        expectLastCall().atLeastOnce();
807
808        expect(mNetManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
809    }
810
811    private void expectNetworkState(NetworkState... state) throws Exception {
812        expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
813
814        final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
815        expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
816    }
817
818    private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
819        expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
820    }
821
822    private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
823        expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
824    }
825
826    private void expectNetworkStatsUidDetail(
827            NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
828            throws Exception {
829        expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
830
831        // also include tethering details, since they are folded into UID
832        expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).atLeastOnce();
833        expect(mNetManager.getNetworkStatsTethering(aryEq(tetherIfacePairs)))
834                .andReturn(tetherStats).atLeastOnce();
835    }
836
837    private void expectDefaultSettings() throws Exception {
838        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
839    }
840
841    private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
842            throws Exception {
843        expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
844        expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
845        expect(mSettings.getGlobalAlertBytes()).andReturn(MB_IN_BYTES).anyTimes();
846        expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
847
848        final Config config = new Config(bucketDuration, persistBytes, deleteAge, deleteAge);
849        expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
850        expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
851        expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
852    }
853
854    private void expectCurrentTime() throws Exception {
855        expect(mTime.forceRefresh()).andReturn(false).anyTimes();
856        expect(mTime.hasCache()).andReturn(true).anyTimes();
857        expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
858        expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
859        expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
860    }
861
862    private void expectNetworkStatsPoll() throws Exception {
863        mNetManager.setGlobalAlert(anyLong());
864        expectLastCall().anyTimes();
865    }
866
867    private void assertStatsFilesExist(boolean exist) {
868        final File basePath = new File(mStatsDir, "netstats");
869        if (exist) {
870            assertTrue(basePath.list().length > 0);
871        } else {
872            assertTrue(basePath.list().length == 0);
873        }
874    }
875
876    private static void assertValues(NetworkStats stats, String iface, int uid, int set,
877            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
878        final int i = stats.findIndex(iface, uid, set, tag);
879        final NetworkStats.Entry entry = stats.getValues(i, null);
880        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
881        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
882        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
883        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
884        assertEquals("unexpected operations", operations, entry.operations);
885    }
886
887    private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
888            long rxPackets, long txBytes, long txPackets, int operations) {
889        final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
890        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
891        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
892        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
893        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
894        assertEquals("unexpected operations", operations, entry.operations);
895    }
896
897    private static NetworkState buildWifiState() {
898        final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
899        info.setDetailedState(DetailedState.CONNECTED, null, null);
900        final LinkProperties prop = new LinkProperties();
901        prop.setInterfaceName(TEST_IFACE);
902        return new NetworkState(info, prop, null);
903    }
904
905    private static NetworkState buildMobile3gState(String subscriberId) {
906        final NetworkInfo info = new NetworkInfo(
907                TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null);
908        info.setDetailedState(DetailedState.CONNECTED, null, null);
909        final LinkProperties prop = new LinkProperties();
910        prop.setInterfaceName(TEST_IFACE);
911        return new NetworkState(info, prop, null, subscriberId);
912    }
913
914    private static NetworkState buildMobile4gState(String iface) {
915        final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null);
916        info.setDetailedState(DetailedState.CONNECTED, null, null);
917        final LinkProperties prop = new LinkProperties();
918        prop.setInterfaceName(iface);
919        return new NetworkState(info, prop, null);
920    }
921
922    private NetworkStats buildEmptyStats() {
923        return new NetworkStats(getElapsedRealtime(), 0);
924    }
925
926    private long getElapsedRealtime() {
927        return mElapsedRealtime;
928    }
929
930    private long startTimeMillis() {
931        return TEST_START;
932    }
933
934    private long currentTimeMillis() {
935        return startTimeMillis() + mElapsedRealtime;
936    }
937
938    private void incrementCurrentTime(long duration) {
939        mElapsedRealtime += duration;
940    }
941
942    private void replay() {
943        EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
944    }
945
946    private void verifyAndReset() {
947        EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
948        EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
949    }
950}
951