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