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