NetworkStatsServiceTest.java revision 1b5a2a96f793211bfbd39aa29cc41031dfa23950
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.net.ConnectivityManager.CONNECTIVITY_ACTION; 20import static android.net.ConnectivityManager.TYPE_WIFI; 21import static android.net.NetworkStats.TAG_NONE; 22import static android.net.NetworkStats.UID_ALL; 23import static android.net.NetworkTemplate.MATCH_WIFI; 24import static android.text.format.DateUtils.DAY_IN_MILLIS; 25import static android.text.format.DateUtils.HOUR_IN_MILLIS; 26import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 27import static android.text.format.DateUtils.WEEK_IN_MILLIS; 28import 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; 47import android.net.NetworkTemplate; 48import android.os.INetworkManagementService; 49import android.test.AndroidTestCase; 50import android.test.suitebuilder.annotation.LargeTest; 51import android.util.TrustedTime; 52 53import com.android.server.net.NetworkStatsService; 54import com.android.server.net.NetworkStatsService.NetworkStatsSettings; 55 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 70 private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null); 71 72 private static final int TEST_UID_1 = 1001; 73 private static final int TEST_UID_2 = 1002; 74 75 private BroadcastInterceptingContext mServiceContext; 76 private File mStatsDir; 77 78 private INetworkManagementService mNetManager; 79 private IAlarmManager mAlarmManager; 80 private TrustedTime mTime; 81 private NetworkStatsSettings mSettings; 82 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); 96 mSettings = createMock(NetworkStatsSettings.class); 97 mConnManager = createMock(IConnectivityManager.class); 98 99 mService = new NetworkStatsService( 100 mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings); 101 mService.bindConnectivityManager(mConnManager); 102 103 expectDefaultSettings(); 104 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 130 public void testSummaryStatsWifi() throws Exception { 131 long elapsedRealtime = 0; 132 133 // pretend that wifi network comes online; service should ask about full 134 // network state, and poll any existing interfaces before updating. 135 expectTime(TEST_START + elapsedRealtime); 136 expectDefaultSettings(); 137 expectNetworkState(buildWifiState()); 138 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 139 140 replay(); 141 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 142 143 // verify service has empty history for wifi 144 assertNetworkTotal(sTemplateWifi, 0L, 0L); 145 verifyAndReset(); 146 147 // modify some number on wifi, and trigger poll event 148 elapsedRealtime += HOUR_IN_MILLIS; 149 expectTime(TEST_START + elapsedRealtime); 150 expectDefaultSettings(); 151 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 152 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L)); 153 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 154 155 replay(); 156 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 157 158 // verify service recorded history 159 assertNetworkTotal(sTemplateWifi, 1024L, 2048L); 160 verifyAndReset(); 161 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; 165 expectTime(TEST_START + elapsedRealtime); 166 expectDefaultSettings(); 167 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 168 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 8192L)); 169 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 170 171 replay(); 172 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 173 174 // verify service recorded history 175 assertNetworkTotal(sTemplateWifi, 4096L, 8192L); 176 verifyAndReset(); 177 178 } 179 180 public void testStatsRebootPersist() throws Exception { 181 long elapsedRealtime = 0; 182 assertStatsFilesExist(false); 183 184 // pretend that wifi network comes online; service should ask about full 185 // network state, and poll any existing interfaces before updating. 186 expectTime(TEST_START + elapsedRealtime); 187 expectDefaultSettings(); 188 expectNetworkState(buildWifiState()); 189 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 190 191 replay(); 192 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 193 194 // verify service has empty history for wifi 195 assertNetworkTotal(sTemplateWifi, 0L, 0L); 196 verifyAndReset(); 197 198 // modify some number on wifi, and trigger poll event 199 elapsedRealtime += HOUR_IN_MILLIS; 200 expectTime(TEST_START + elapsedRealtime); 201 expectDefaultSettings(); 202 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 203 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L)); 204 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2) 205 .addEntry(TEST_IFACE, TEST_UID_1, TAG_NONE, 512L, 256L) 206 .addEntry(TEST_IFACE, TEST_UID_2, TAG_NONE, 128L, 128L)); 207 208 replay(); 209 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 210 211 // verify service recorded history 212 assertNetworkTotal(sTemplateWifi, 1024L, 2048L); 213 assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L); 214 assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L); 215 verifyAndReset(); 216 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. 223 expectDefaultSettings(); 224 replay(); 225 assertNetworkTotal(sTemplateWifi, 0L, 0L); 226 verifyAndReset(); 227 228 assertStatsFilesExist(true); 229 230 // boot through serviceReady() again 231 expectDefaultSettings(); 232 expectSystemReady(); 233 234 replay(); 235 mService.systemReady(); 236 237 // after systemReady(), we should have historical stats loaded again 238 assertNetworkTotal(sTemplateWifi, 1024L, 2048L); 239 assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L); 240 assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L); 241 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); 267 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 268 .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 512L)); 269 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 270 271 replay(); 272 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 273 274 // verify service recorded history 275 history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null)); 276 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 294 history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null)); 295 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(); 301 302 } 303 304 private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) { 305 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 311 private void assertUidTotal(NetworkTemplate template, int uid, long rx, long tx) { 312 final NetworkStatsHistory history = mService.getHistoryForUid(template, uid); 313 final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); 314 assertEquals(rx, total[0]); 315 assertEquals(tx, total[1]); 316 } 317 318 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 327 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 { 355 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 362 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) { 383 return new NetworkStats(elapsedRealtime, 0); 384 } 385 386 private void replay() { 387 EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager); 388 } 389 390 private void verifyAndReset() { 391 EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager); 392 EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager); 393 } 394} 395