NetworkStatsServiceTest.java revision d37948f6ed1667d077e0e3a38808f42f981ddcc2
1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch/* 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Copyright (C) 2011 The Android Open Source Project 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * you may not use this file except in compliance with the License. 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * You may obtain a copy of the License at 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Unless required by applicable law or agreed to in writing, software 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * distributed under the License is distributed on an "AS IS" BASIS, 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * See the License for the specific language governing permissions and 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * limitations under the License. 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch */ 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)package com.android.server; 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.content.Intent.ACTION_UID_REMOVED; 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.content.Intent.EXTRA_UID; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.ConnectivityManager.TYPE_MOBILE; 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import static android.net.ConnectivityManager.TYPE_WIFI; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.ConnectivityManager.TYPE_WIMAX; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.NetworkStats.IFACE_ALL; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.NetworkStats.TAG_NONE; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.NetworkStats.UID_ALL; 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.NetworkTemplate.MATCH_WIFI; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.net.TrafficStats.UID_REMOVED; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.text.format.DateUtils.DAY_IN_MILLIS; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.text.format.DateUtils.HOUR_IN_MILLIS; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static android.text.format.DateUtils.WEEK_IN_MILLIS; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static com.android.server.net.NetworkStatsService.packUidAndTag; 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import static com.android.server.net.NetworkStatsService.unpackTag; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static com.android.server.net.NetworkStatsService.unpackUid; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static org.easymock.EasyMock.anyLong; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static org.easymock.EasyMock.createMock; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static org.easymock.EasyMock.eq; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static org.easymock.EasyMock.expect; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static org.easymock.EasyMock.expectLastCall; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import static org.easymock.EasyMock.isA; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import android.app.AlarmManager; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.app.IAlarmManager; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.app.PendingIntent; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.content.Intent; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.IConnectivityManager; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.LinkProperties; 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.NetworkInfo; 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import android.net.NetworkInfo.DetailedState; 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.NetworkState; 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.NetworkStats; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.NetworkStatsHistory; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.NetworkTemplate; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.os.INetworkManagementService; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.telephony.TelephonyManager; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.test.AndroidTestCase; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.test.suitebuilder.annotation.LargeTest; 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import android.util.TrustedTime; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import com.android.server.net.NetworkStatsService; 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import com.android.server.net.NetworkStatsService.NetworkStatsSettings; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.easymock.EasyMock; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import java.io.File; 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Tests for {@link NetworkStatsService}. 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@LargeTest 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public class NetworkStatsServiceTest extends AndroidTestCase { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static final String TAG = "NetworkStatsServiceTest"; 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private static final String TEST_IFACE = "test0"; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static final long TEST_START = 1194220800000L; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static final String IMSI_1 = "310004"; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static final String IMSI_2 = "310260"; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static NetworkTemplate sTemplateImsi1 = new NetworkTemplate(MATCH_MOBILE_ALL, IMSI_1); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static NetworkTemplate sTemplateImsi2 = new NetworkTemplate(MATCH_MOBILE_ALL, IMSI_2); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static final int UID_RED = 1001; 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private static final int UID_BLUE = 1002; 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private static final int UID_GREEN = 1003; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private BroadcastInterceptingContext mServiceContext; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private File mStatsDir; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private INetworkManagementService mNetManager; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private IAlarmManager mAlarmManager; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private TrustedTime mTime; 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private NetworkStatsSettings mSettings; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private IConnectivityManager mConnManager; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private NetworkStatsService mService; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @Override 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public void setUp() throws Exception { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) super.setUp(); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mServiceContext = new BroadcastInterceptingContext(getContext()); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mStatsDir = getContext().getFilesDir(); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mNetManager = createMock(INetworkManagementService.class); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mAlarmManager = createMock(IAlarmManager.class); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mTime = createMock(TrustedTime.class); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mSettings = createMock(NetworkStatsSettings.class); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mConnManager = createMock(IConnectivityManager.class); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mService = new NetworkStatsService( 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings); 118 mService.bindConnectivityManager(mConnManager); 119 120 expectDefaultSettings(); 121 expectSystemReady(); 122 123 replay(); 124 mService.systemReady(); 125 verifyAndReset(); 126 127 } 128 129 @Override 130 public void tearDown() throws Exception { 131 for (File file : mStatsDir.listFiles()) { 132 file.delete(); 133 } 134 135 mServiceContext = null; 136 mStatsDir = null; 137 138 mNetManager = null; 139 mAlarmManager = null; 140 mTime = null; 141 mSettings = null; 142 mConnManager = null; 143 144 mService = null; 145 146 super.tearDown(); 147 } 148 149 public void testNetworkStatsWifi() throws Exception { 150 long elapsedRealtime = 0; 151 152 // pretend that wifi network comes online; service should ask about full 153 // network state, and poll any existing interfaces before updating. 154 expectTime(TEST_START + elapsedRealtime); 155 expectDefaultSettings(); 156 expectNetworkState(buildWifiState()); 157 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 158 159 replay(); 160 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 161 162 // verify service has empty history for wifi 163 assertNetworkTotal(sTemplateWifi, 0L, 0L); 164 verifyAndReset(); 165 166 // modify some number on wifi, and trigger poll event 167 elapsedRealtime += HOUR_IN_MILLIS; 168 expectTime(TEST_START + elapsedRealtime); 169 expectDefaultSettings(); 170 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 171 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 1L, 2048L, 2L)); 172 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 173 174 replay(); 175 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 176 177 // verify service recorded history 178 assertNetworkTotal(sTemplateWifi, 1024L, 2048L); 179 verifyAndReset(); 180 181 // and bump forward again, with counters going higher. this is 182 // important, since polling should correctly subtract last snapshot. 183 elapsedRealtime += DAY_IN_MILLIS; 184 expectTime(TEST_START + elapsedRealtime); 185 expectDefaultSettings(); 186 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 187 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 4L, 8192L, 8L)); 188 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 189 190 replay(); 191 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 192 193 // verify service recorded history 194 assertNetworkTotal(sTemplateWifi, 4096L, 8192L); 195 verifyAndReset(); 196 197 } 198 199 public void testStatsRebootPersist() throws Exception { 200 long elapsedRealtime = 0; 201 assertStatsFilesExist(false); 202 203 // pretend that wifi network comes online; service should ask about full 204 // network state, and poll any existing interfaces before updating. 205 expectTime(TEST_START + elapsedRealtime); 206 expectDefaultSettings(); 207 expectNetworkState(buildWifiState()); 208 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 209 210 replay(); 211 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 212 213 // verify service has empty history for wifi 214 assertNetworkTotal(sTemplateWifi, 0L, 0L); 215 verifyAndReset(); 216 217 // modify some number on wifi, and trigger poll event 218 elapsedRealtime += HOUR_IN_MILLIS; 219 expectTime(TEST_START + elapsedRealtime); 220 expectDefaultSettings(); 221 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 222 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 8L, 2048L, 16L)); 223 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2) 224 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L) 225 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 128L, 1L)); 226 227 replay(); 228 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 229 230 // verify service recorded history 231 assertNetworkTotal(sTemplateWifi, 1024L, 2048L); 232 assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L); 233 assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L); 234 verifyAndReset(); 235 236 // graceful shutdown system, which should trigger persist of stats, and 237 // clear any values in memory. 238 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN)); 239 240 // talk with zombie service to assert stats have gone; and assert that 241 // we persisted them to file. 242 expectDefaultSettings(); 243 replay(); 244 assertNetworkTotal(sTemplateWifi, 0L, 0L); 245 verifyAndReset(); 246 247 assertStatsFilesExist(true); 248 249 // boot through serviceReady() again 250 expectDefaultSettings(); 251 expectSystemReady(); 252 253 replay(); 254 mService.systemReady(); 255 256 // after systemReady(), we should have historical stats loaded again 257 assertNetworkTotal(sTemplateWifi, 1024L, 2048L); 258 assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L); 259 assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L); 260 verifyAndReset(); 261 262 } 263 264 public void testStatsBucketResize() throws Exception { 265 long elapsedRealtime = 0; 266 NetworkStatsHistory history = null; 267 long[] total = null; 268 269 assertStatsFilesExist(false); 270 271 // pretend that wifi network comes online; service should ask about full 272 // network state, and poll any existing interfaces before updating. 273 expectTime(TEST_START + elapsedRealtime); 274 expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); 275 expectNetworkState(buildWifiState()); 276 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 277 278 replay(); 279 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 280 verifyAndReset(); 281 282 // modify some number on wifi, and trigger poll event 283 elapsedRealtime += 2 * HOUR_IN_MILLIS; 284 expectTime(TEST_START + elapsedRealtime); 285 expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); 286 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 287 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 4L, 512L, 4L)); 288 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 289 290 replay(); 291 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 292 293 // verify service recorded history 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(HOUR_IN_MILLIS, history.getBucketDuration()); 299 assertEquals(2, history.size()); 300 verifyAndReset(); 301 302 // now change bucket duration setting and trigger another poll with 303 // exact same values, which should resize existing buckets. 304 expectTime(TEST_START + elapsedRealtime); 305 expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS); 306 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 307 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 308 309 replay(); 310 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 311 312 // verify identical stats, but spread across 4 buckets now 313 history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null)); 314 total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); 315 assertEquals(512L, total[0]); 316 assertEquals(512L, total[1]); 317 assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration()); 318 assertEquals(4, history.size()); 319 verifyAndReset(); 320 321 } 322 323 public void testUidStatsAcrossNetworks() throws Exception { 324 long elapsedRealtime = 0; 325 326 // pretend first mobile network comes online 327 expectTime(TEST_START + elapsedRealtime); 328 expectDefaultSettings(); 329 expectNetworkState(buildMobile3gState(IMSI_1)); 330 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 331 332 replay(); 333 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 334 verifyAndReset(); 335 336 // create some traffic on first network 337 elapsedRealtime += HOUR_IN_MILLIS; 338 expectTime(TEST_START + elapsedRealtime); 339 expectDefaultSettings(); 340 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 341 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 2048L, 16L, 512L, 4L)); 342 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 3) 343 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 1536L, 12L, 512L, 4L) 344 .addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L) 345 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 512L, 4L, 0L, 0L)); 346 347 replay(); 348 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 349 350 // verify service recorded history 351 assertNetworkTotal(sTemplateImsi1, 2048L, 512L); 352 assertNetworkTotal(sTemplateWifi, 0L, 0L); 353 assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L); 354 assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L); 355 verifyAndReset(); 356 357 // now switch networks; this also tests that we're okay with interfaces 358 // disappearing, to verify we don't count backwards. 359 elapsedRealtime += HOUR_IN_MILLIS; 360 expectTime(TEST_START + elapsedRealtime); 361 expectDefaultSettings(); 362 expectNetworkState(buildMobile3gState(IMSI_2)); 363 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 364 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 365 366 replay(); 367 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 368 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 369 verifyAndReset(); 370 371 // create traffic on second network 372 elapsedRealtime += HOUR_IN_MILLIS; 373 expectTime(TEST_START + elapsedRealtime); 374 expectDefaultSettings(); 375 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 376 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 128L, 1L, 1024L, 8L)); 377 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1) 378 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 1024L, 8L)); 379 380 replay(); 381 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 382 383 // verify original history still intact 384 assertNetworkTotal(sTemplateImsi1, 2048L, 512L); 385 assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L); 386 assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L); 387 388 // and verify new history also recorded under different template, which 389 // verifies that we didn't cross the streams. 390 assertNetworkTotal(sTemplateImsi2, 128L, 1024L); 391 assertNetworkTotal(sTemplateWifi, 0L, 0L); 392 assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1024L); 393 verifyAndReset(); 394 395 } 396 397 public void testUidRemovedIsMoved() throws Exception { 398 long elapsedRealtime = 0; 399 400 // pretend that network comes online 401 expectTime(TEST_START + elapsedRealtime); 402 expectDefaultSettings(); 403 expectNetworkState(buildWifiState()); 404 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 405 406 replay(); 407 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 408 verifyAndReset(); 409 410 // create some traffic 411 elapsedRealtime += HOUR_IN_MILLIS; 412 expectTime(TEST_START + elapsedRealtime); 413 expectDefaultSettings(); 414 expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) 415 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4128L, 258L, 544L, 34L)); 416 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1) 417 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 16L, 1L, 16L, 1L) 418 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 4096L, 258L, 512L, 32L) 419 .addValues(TEST_IFACE, UID_GREEN, TAG_NONE, 16L, 1L, 16L, 1L)); 420 421 replay(); 422 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 423 424 // verify service recorded history 425 assertNetworkTotal(sTemplateWifi, 4128L, 544L); 426 assertUidTotal(sTemplateWifi, UID_RED, 16L, 16L); 427 assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 512L); 428 assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L); 429 verifyAndReset(); 430 431 // now pretend two UIDs are uninstalled, which should migrate stats to 432 // special "removed" bucket. 433 expectDefaultSettings(); 434 replay(); 435 final Intent intent = new Intent(ACTION_UID_REMOVED); 436 intent.putExtra(EXTRA_UID, UID_BLUE); 437 mServiceContext.sendBroadcast(intent); 438 intent.putExtra(EXTRA_UID, UID_RED); 439 mServiceContext.sendBroadcast(intent); 440 441 // existing uid and total should remain unchanged; but removed UID 442 // should be gone completely. 443 assertNetworkTotal(sTemplateWifi, 4128L, 544L); 444 assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L); 445 assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L); 446 assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L); 447 assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 528L); 448 verifyAndReset(); 449 450 } 451 452 public void testUid3g4gCombinedByTemplate() throws Exception { 453 long elapsedRealtime = 0; 454 455 // pretend that network comes online 456 expectTime(TEST_START + elapsedRealtime); 457 expectDefaultSettings(); 458 expectNetworkState(buildMobile3gState(IMSI_1)); 459 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 460 461 replay(); 462 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 463 verifyAndReset(); 464 465 // create some traffic 466 elapsedRealtime += HOUR_IN_MILLIS; 467 expectTime(TEST_START + elapsedRealtime); 468 expectDefaultSettings(); 469 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 470 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1) 471 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 1024L, 8L, 1024L, 8L) 472 .addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L)); 473 474 replay(); 475 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 476 477 // verify service recorded history 478 assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 1024L); 479 verifyAndReset(); 480 481 // now switch over to 4g network 482 elapsedRealtime += HOUR_IN_MILLIS; 483 expectTime(TEST_START + elapsedRealtime); 484 expectDefaultSettings(); 485 expectNetworkState(buildMobile4gState()); 486 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 487 expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime)); 488 489 replay(); 490 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 491 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 492 verifyAndReset(); 493 494 // create traffic on second network 495 elapsedRealtime += HOUR_IN_MILLIS; 496 expectTime(TEST_START + elapsedRealtime); 497 expectDefaultSettings(); 498 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 499 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1) 500 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L)); 501 502 replay(); 503 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 504 505 // verify that ALL_MOBILE template combines both 506 assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 1280L); 507 508 verifyAndReset(); 509 510 } 511 512 public void testPackedUidAndTag() throws Exception { 513 assertEquals(0x0000000000000000L, packUidAndTag(0, 0x0)); 514 assertEquals(0x000003E900000000L, packUidAndTag(1001, 0x0)); 515 assertEquals(0x000003E90000F00DL, packUidAndTag(1001, 0xF00D)); 516 517 long packed; 518 packed = packUidAndTag(Integer.MAX_VALUE, Integer.MIN_VALUE); 519 assertEquals(Integer.MAX_VALUE, unpackUid(packed)); 520 assertEquals(Integer.MIN_VALUE, unpackTag(packed)); 521 522 packed = packUidAndTag(Integer.MIN_VALUE, Integer.MAX_VALUE); 523 assertEquals(Integer.MIN_VALUE, unpackUid(packed)); 524 assertEquals(Integer.MAX_VALUE, unpackTag(packed)); 525 526 packed = packUidAndTag(10005, 0xFFFFFFFF); 527 assertEquals(10005, unpackUid(packed)); 528 assertEquals(0xFFFFFFFF, unpackTag(packed)); 529 530 } 531 532 public void testSummaryForAllUid() throws Exception { 533 long elapsedRealtime = 0; 534 535 // pretend that network comes online 536 expectTime(TEST_START + elapsedRealtime); 537 expectDefaultSettings(); 538 expectNetworkState(buildWifiState()); 539 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 540 541 replay(); 542 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 543 verifyAndReset(); 544 545 // create some traffic for two apps 546 elapsedRealtime += HOUR_IN_MILLIS; 547 expectTime(TEST_START + elapsedRealtime); 548 expectDefaultSettings(); 549 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 550 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1) 551 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L) 552 .addValues(TEST_IFACE, UID_RED, 0xF00D, 10L, 1L, 10L, 1L) 553 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L)); 554 555 replay(); 556 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 557 558 // verify service recorded history 559 assertUidTotal(sTemplateWifi, UID_RED, 50L, 50L); 560 assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 512L); 561 verifyAndReset(); 562 563 // now create more traffic in next hour, but only for one app 564 elapsedRealtime += HOUR_IN_MILLIS; 565 expectTime(TEST_START + elapsedRealtime); 566 expectDefaultSettings(); 567 expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); 568 expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1) 569 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L)); 570 571 replay(); 572 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); 573 574 // first verify entire history present 575 NetworkStats stats = mService.getSummaryForAllUid( 576 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); 577 assertEquals(3, stats.size()); 578 assertEntry(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L); 579 assertEntry(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L); 580 assertEntry(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L); 581 582 // now verify that recent history only contains one uid 583 final long currentTime = TEST_START + elapsedRealtime; 584 stats = mService.getSummaryForAllUid( 585 sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true); 586 assertEquals(1, stats.size()); 587 assertEntry(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L); 588 589 verifyAndReset(); 590 } 591 592 private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) { 593 final NetworkStatsHistory history = mService.getHistoryForNetwork(template); 594 final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); 595 assertEquals(rx, total[0]); 596 assertEquals(tx, total[1]); 597 } 598 599 private void assertUidTotal(NetworkTemplate template, int uid, long rx, long tx) { 600 final NetworkStatsHistory history = mService.getHistoryForUid(template, uid, TAG_NONE); 601 final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); 602 assertEquals(rx, total[0]); 603 assertEquals(tx, total[1]); 604 } 605 606 private void expectSystemReady() throws Exception { 607 mAlarmManager.remove(isA(PendingIntent.class)); 608 expectLastCall().anyTimes(); 609 610 mAlarmManager.setInexactRepeating( 611 eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class)); 612 expectLastCall().atLeastOnce(); 613 } 614 615 private void expectNetworkState(NetworkState... state) throws Exception { 616 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 617 } 618 619 private void expectNetworkStatsSummary(NetworkStats summary) throws Exception { 620 expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce(); 621 } 622 623 private void expectNetworkStatsDetail(NetworkStats detail) throws Exception { 624 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce(); 625 } 626 627 private void expectDefaultSettings() throws Exception { 628 expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); 629 } 630 631 private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory) 632 throws Exception { 633 expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes(); 634 expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes(); 635 expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes(); 636 expect(mSettings.getNetworkMaxHistory()).andReturn(maxHistory).anyTimes(); 637 expect(mSettings.getUidBucketDuration()).andReturn(bucketDuration).anyTimes(); 638 expect(mSettings.getUidMaxHistory()).andReturn(maxHistory).anyTimes(); 639 expect(mSettings.getTagMaxHistory()).andReturn(maxHistory).anyTimes(); 640 expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes(); 641 } 642 643 private void expectTime(long currentTime) throws Exception { 644 expect(mTime.forceRefresh()).andReturn(false).anyTimes(); 645 expect(mTime.hasCache()).andReturn(true).anyTimes(); 646 expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); 647 expect(mTime.getCacheAge()).andReturn(0L).anyTimes(); 648 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); 649 } 650 651 private void assertStatsFilesExist(boolean exist) { 652 final File networkFile = new File(mStatsDir, "netstats.bin"); 653 final File uidFile = new File(mStatsDir, "netstats_uid.bin"); 654 if (exist) { 655 assertTrue(networkFile.exists()); 656 assertTrue(uidFile.exists()); 657 } else { 658 assertFalse(networkFile.exists()); 659 assertFalse(uidFile.exists()); 660 } 661 } 662 663 private static void assertEntry(NetworkStats stats, int i, String iface, int uid, int tag, 664 long rxBytes, long rxPackets, long txBytes, long txPackets) { 665 final NetworkStats.Entry entry = stats.getValues(i, null); 666 assertEquals(iface, entry.iface); 667 assertEquals(uid, entry.uid); 668 assertEquals(tag, entry.tag); 669 assertEquals(rxBytes, entry.rxBytes); 670 // TODO: enable testing packet counts once stored in history 671// assertEquals(rxPackets, entry.rxPackets); 672 assertEquals(txBytes, entry.txBytes); 673// assertEquals(txPackets, entry.txPackets); 674 } 675 676 private static NetworkState buildWifiState() { 677 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 678 info.setDetailedState(DetailedState.CONNECTED, null, null); 679 final LinkProperties prop = new LinkProperties(); 680 prop.setInterfaceName(TEST_IFACE); 681 return new NetworkState(info, prop, null); 682 } 683 684 private static NetworkState buildMobile3gState(String subscriberId) { 685 final NetworkInfo info = new NetworkInfo( 686 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null); 687 info.setDetailedState(DetailedState.CONNECTED, null, null); 688 final LinkProperties prop = new LinkProperties(); 689 prop.setInterfaceName(TEST_IFACE); 690 return new NetworkState(info, prop, null, subscriberId); 691 } 692 693 private static NetworkState buildMobile4gState() { 694 final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null); 695 info.setDetailedState(DetailedState.CONNECTED, null, null); 696 final LinkProperties prop = new LinkProperties(); 697 prop.setInterfaceName(TEST_IFACE); 698 return new NetworkState(info, prop, null); 699 } 700 701 private static NetworkStats buildEmptyStats(long elapsedRealtime) { 702 return new NetworkStats(elapsedRealtime, 0); 703 } 704 705 private void replay() { 706 EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager); 707 } 708 709 private void verifyAndReset() { 710 EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager); 711 EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager); 712 } 713} 714