blob: 1d2634c1f870d136ecf39d8cb12fb92bdf6ac9b8 [file] [log] [blame]
Jeff Sharkey3f391352011-06-05 17:42:53 -07001/*
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.net.ConnectivityManager.CONNECTIVITY_ACTION;
20import static android.net.ConnectivityManager.TYPE_WIFI;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070021import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey3f391352011-06-05 17:42:53 -070022import static android.net.NetworkStats.UID_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070023import static android.net.NetworkTemplate.MATCH_WIFI;
Jeff Sharkey3f391352011-06-05 17:42:53 -070024import static android.text.format.DateUtils.DAY_IN_MILLIS;
25import static android.text.format.DateUtils.HOUR_IN_MILLIS;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070026import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
27import static android.text.format.DateUtils.WEEK_IN_MILLIS;
Jeff Sharkey3f391352011-06-05 17:42:53 -070028import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
29import static org.easymock.EasyMock.anyLong;
30import static org.easymock.EasyMock.createMock;
31import static org.easymock.EasyMock.eq;
32import static org.easymock.EasyMock.expect;
33import static org.easymock.EasyMock.expectLastCall;
34import static org.easymock.EasyMock.isA;
35
36import android.app.AlarmManager;
37import android.app.IAlarmManager;
38import android.app.PendingIntent;
39import android.content.Intent;
40import android.net.IConnectivityManager;
41import android.net.LinkProperties;
42import android.net.NetworkInfo;
43import android.net.NetworkInfo.DetailedState;
44import android.net.NetworkState;
45import android.net.NetworkStats;
46import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070047import android.net.NetworkTemplate;
Jeff Sharkey3f391352011-06-05 17:42:53 -070048import android.os.INetworkManagementService;
49import android.test.AndroidTestCase;
50import android.test.suitebuilder.annotation.LargeTest;
51import android.util.TrustedTime;
52
53import com.android.server.net.NetworkStatsService;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070054import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
Jeff Sharkey3f391352011-06-05 17:42:53 -070055
56import org.easymock.EasyMock;
57
58import java.io.File;
59
60/**
61 * Tests for {@link NetworkStatsService}.
62 */
63@LargeTest
64public class NetworkStatsServiceTest extends AndroidTestCase {
65 private static final String TAG = "NetworkStatsServiceTest";
66
67 private static final String TEST_IFACE = "test0";
68 private static final long TEST_START = 1194220800000L;
69
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070070 private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null);
71
Jeff Sharkey39ebc212011-06-11 17:25:42 -070072 private static final int TEST_UID_1 = 1001;
73 private static final int TEST_UID_2 = 1002;
74
Jeff Sharkey3f391352011-06-05 17:42:53 -070075 private BroadcastInterceptingContext mServiceContext;
76 private File mStatsDir;
77
78 private INetworkManagementService mNetManager;
79 private IAlarmManager mAlarmManager;
80 private TrustedTime mTime;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070081 private NetworkStatsSettings mSettings;
Jeff Sharkey3f391352011-06-05 17:42:53 -070082 private IConnectivityManager mConnManager;
83
84 private NetworkStatsService mService;
85
86 @Override
87 public void setUp() throws Exception {
88 super.setUp();
89
90 mServiceContext = new BroadcastInterceptingContext(getContext());
91 mStatsDir = getContext().getFilesDir();
92
93 mNetManager = createMock(INetworkManagementService.class);
94 mAlarmManager = createMock(IAlarmManager.class);
95 mTime = createMock(TrustedTime.class);
Jeff Sharkey39ebc212011-06-11 17:25:42 -070096 mSettings = createMock(NetworkStatsSettings.class);
Jeff Sharkey3f391352011-06-05 17:42:53 -070097 mConnManager = createMock(IConnectivityManager.class);
98
99 mService = new NetworkStatsService(
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700100 mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700101 mService.bindConnectivityManager(mConnManager);
102
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700103 expectDefaultSettings();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700104 expectSystemReady();
105
106 replay();
107 mService.systemReady();
108 verifyAndReset();
109
110 }
111
112 @Override
113 public void tearDown() throws Exception {
114 for (File file : mStatsDir.listFiles()) {
115 file.delete();
116 }
117
118 mServiceContext = null;
119 mStatsDir = null;
120
121 mNetManager = null;
122 mAlarmManager = null;
123 mTime = null;
124
125 mService = null;
126
127 super.tearDown();
128 }
129
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700130 public void testSummaryStatsWifi() throws Exception {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700131 long elapsedRealtime = 0;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700132
133 // pretend that wifi network comes online; service should ask about full
134 // network state, and poll any existing interfaces before updating.
Jeff Sharkey3f391352011-06-05 17:42:53 -0700135 expectTime(TEST_START + elapsedRealtime);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700136 expectDefaultSettings();
137 expectNetworkState(buildWifiState());
138 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700139
140 replay();
141 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700142
143 // verify service has empty history for wifi
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700144 assertNetworkTotal(sTemplateWifi, 0L, 0L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700145 verifyAndReset();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700146
147 // modify some number on wifi, and trigger poll event
148 elapsedRealtime += HOUR_IN_MILLIS;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700149 expectTime(TEST_START + elapsedRealtime);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700150 expectDefaultSettings();
Jeff Sharkey4a971222011-06-11 22:16:55 -0700151 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700152 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700153 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700154
155 replay();
156 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700157
158 // verify service recorded history
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700159 assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700160 verifyAndReset();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700161
162 // and bump forward again, with counters going higher. this is
163 // important, since polling should correctly subtract last snapshot.
164 elapsedRealtime += DAY_IN_MILLIS;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700165 expectTime(TEST_START + elapsedRealtime);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700166 expectDefaultSettings();
Jeff Sharkey4a971222011-06-11 22:16:55 -0700167 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700168 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 8192L));
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700169 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700170
171 replay();
172 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700173
174 // verify service recorded history
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700175 assertNetworkTotal(sTemplateWifi, 4096L, 8192L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700176 verifyAndReset();
177
Jeff Sharkey3f391352011-06-05 17:42:53 -0700178 }
179
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700180 public void testStatsRebootPersist() throws Exception {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700181 long elapsedRealtime = 0;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700182 assertStatsFilesExist(false);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700183
184 // pretend that wifi network comes online; service should ask about full
185 // network state, and poll any existing interfaces before updating.
Jeff Sharkey3f391352011-06-05 17:42:53 -0700186 expectTime(TEST_START + elapsedRealtime);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700187 expectDefaultSettings();
188 expectNetworkState(buildWifiState());
189 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700190
191 replay();
192 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700193
194 // verify service has empty history for wifi
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700195 assertNetworkTotal(sTemplateWifi, 0L, 0L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700196 verifyAndReset();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700197
198 // modify some number on wifi, and trigger poll event
199 elapsedRealtime += HOUR_IN_MILLIS;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700200 expectTime(TEST_START + elapsedRealtime);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700201 expectDefaultSettings();
Jeff Sharkey4a971222011-06-11 22:16:55 -0700202 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700203 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
Jeff Sharkey4a971222011-06-11 22:16:55 -0700204 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700205 .addEntry(TEST_IFACE, TEST_UID_1, TAG_NONE, 512L, 256L)
206 .addEntry(TEST_IFACE, TEST_UID_2, TAG_NONE, 128L, 128L));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700207
208 replay();
209 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
Jeff Sharkey3f391352011-06-05 17:42:53 -0700210
211 // verify service recorded history
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700212 assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
213 assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
214 assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700215 verifyAndReset();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700216
217 // graceful shutdown system, which should trigger persist of stats, and
218 // clear any values in memory.
219 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
220
221 // talk with zombie service to assert stats have gone; and assert that
222 // we persisted them to file.
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700223 expectDefaultSettings();
224 replay();
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700225 assertNetworkTotal(sTemplateWifi, 0L, 0L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700226 verifyAndReset();
227
228 assertStatsFilesExist(true);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700229
230 // boot through serviceReady() again
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700231 expectDefaultSettings();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700232 expectSystemReady();
233
234 replay();
235 mService.systemReady();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700236
237 // after systemReady(), we should have historical stats loaded again
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700238 assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
239 assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
240 assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700241 verifyAndReset();
242
243 }
244
245 public void testStatsBucketResize() throws Exception {
246 long elapsedRealtime = 0;
247 NetworkStatsHistory history = null;
248 long[] total = null;
249
250 assertStatsFilesExist(false);
251
252 // pretend that wifi network comes online; service should ask about full
253 // network state, and poll any existing interfaces before updating.
254 expectTime(TEST_START + elapsedRealtime);
255 expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
256 expectNetworkState(buildWifiState());
257 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
258
259 replay();
260 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
261 verifyAndReset();
262
263 // modify some number on wifi, and trigger poll event
264 elapsedRealtime += 2 * HOUR_IN_MILLIS;
265 expectTime(TEST_START + elapsedRealtime);
266 expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
Jeff Sharkey4a971222011-06-11 22:16:55 -0700267 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700268 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 512L));
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700269 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
270
271 replay();
272 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
273
274 // verify service recorded history
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700275 history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700276 total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
277 assertEquals(512L, total[0]);
278 assertEquals(512L, total[1]);
279 assertEquals(HOUR_IN_MILLIS, history.bucketDuration);
280 assertEquals(2, history.bucketCount);
281 verifyAndReset();
282
283 // now change bucket duration setting and trigger another poll with
284 // exact same values, which should resize existing buckets.
285 expectTime(TEST_START + elapsedRealtime);
286 expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
287 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
288 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
289
290 replay();
291 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
292
293 // verify identical stats, but spread across 4 buckets now
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700294 history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700295 total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
296 assertEquals(512L, total[0]);
297 assertEquals(512L, total[1]);
298 assertEquals(30 * MINUTE_IN_MILLIS, history.bucketDuration);
299 assertEquals(4, history.bucketCount);
300 verifyAndReset();
Jeff Sharkey3f391352011-06-05 17:42:53 -0700301
302 }
303
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700304 private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700305 final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
306 final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
307 assertEquals(rx, total[0]);
308 assertEquals(tx, total[1]);
309 }
310
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700311 private void assertUidTotal(NetworkTemplate template, int uid, long rx, long tx) {
312 final NetworkStatsHistory history = mService.getHistoryForUid(template, uid);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700313 final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
314 assertEquals(rx, total[0]);
315 assertEquals(tx, total[1]);
316 }
317
Jeff Sharkey3f391352011-06-05 17:42:53 -0700318 private void expectSystemReady() throws Exception {
319 mAlarmManager.remove(isA(PendingIntent.class));
320 expectLastCall().anyTimes();
321
322 mAlarmManager.setInexactRepeating(
323 eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
324 expectLastCall().atLeastOnce();
325 }
326
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700327 private void expectNetworkState(NetworkState... state) throws Exception {
328 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
329 }
330
331 private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
332 expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
333 }
334
335 private void expectNetworkStatsDetail(NetworkStats detail) throws Exception {
336 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
337 }
338
339 private void expectDefaultSettings() throws Exception {
340 expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
341 }
342
343 private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory)
344 throws Exception {
345 expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
346 expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes();
347 expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes();
348 expect(mSettings.getNetworkMaxHistory()).andReturn(maxHistory).anyTimes();
349 expect(mSettings.getUidBucketDuration()).andReturn(bucketDuration).anyTimes();
350 expect(mSettings.getUidMaxHistory()).andReturn(maxHistory).anyTimes();
351 expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
352 }
353
354 private void expectTime(long currentTime) throws Exception {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700355 expect(mTime.forceRefresh()).andReturn(false).anyTimes();
356 expect(mTime.hasCache()).andReturn(true).anyTimes();
357 expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes();
358 expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
359 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
360 }
361
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700362 private void assertStatsFilesExist(boolean exist) {
363 final File summaryFile = new File(mStatsDir, "netstats.bin");
364 final File detailFile = new File(mStatsDir, "netstats_uid.bin");
365 if (exist) {
366 assertTrue(summaryFile.exists());
367 assertTrue(detailFile.exists());
368 } else {
369 assertFalse(summaryFile.exists());
370 assertFalse(detailFile.exists());
371 }
372 }
373
374 private static NetworkState buildWifiState() {
375 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
376 info.setDetailedState(DetailedState.CONNECTED, null, null);
377 final LinkProperties prop = new LinkProperties();
378 prop.setInterfaceName(TEST_IFACE);
379 return new NetworkState(info, prop, null);
380 }
381
382 private static NetworkStats buildEmptyStats(long elapsedRealtime) {
Jeff Sharkey4a971222011-06-11 22:16:55 -0700383 return new NetworkStats(elapsedRealtime, 0);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700384 }
385
Jeff Sharkey3f391352011-06-05 17:42:53 -0700386 private void replay() {
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700387 EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700388 }
389
390 private void verifyAndReset() {
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700391 EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
392 EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700393 }
394}