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