ThrottleServiceTest.java revision bdfce2ec05a3e9ca6acd6711de6133e06f2446e6
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.NetworkStats.SET_DEFAULT; 20import static android.net.NetworkStats.TAG_NONE; 21import static android.net.NetworkStats.UID_ALL; 22import static org.easymock.EasyMock.createMock; 23import static org.easymock.EasyMock.eq; 24import static org.easymock.EasyMock.expect; 25import static org.easymock.EasyMock.expectLastCall; 26import static org.easymock.EasyMock.isA; 27import static org.easymock.EasyMock.replay; 28import static org.easymock.EasyMock.reset; 29import static org.easymock.EasyMock.verify; 30 31import android.content.ContentResolver; 32import android.content.Context; 33import android.content.Intent; 34import android.net.INetworkManagementEventObserver; 35import android.net.NetworkStats; 36import android.net.ThrottleManager; 37import android.os.IBinder; 38import android.os.INetworkManagementService; 39import android.os.ServiceManager; 40import android.os.SystemClock; 41import android.provider.Settings; 42import android.test.AndroidTestCase; 43import android.test.suitebuilder.annotation.LargeTest; 44import android.test.suitebuilder.annotation.Suppress; 45import android.text.format.DateUtils; 46import android.util.Log; 47import android.util.TrustedTime; 48 49import java.util.concurrent.Future; 50 51/** 52 * Tests for {@link ThrottleService}. 53 */ 54@LargeTest 55public class ThrottleServiceTest extends AndroidTestCase { 56 private static final String TAG = "ThrottleServiceTest"; 57 58 private static final long MB_IN_BYTES = 1024 * 1024; 59 60 private static final int TEST_KBITPS = 222; 61 private static final int TEST_RESET_DAY = 11; 62 63 private static final String TEST_IFACE = "test0"; 64 65 private BroadcastInterceptingContext mWatchingContext; 66 private INetworkManagementService mMockNMService; 67 private TrustedTime mMockTime; 68 69 private ThrottleService mThrottleService; 70 71 @Override 72 public void setUp() throws Exception { 73 super.setUp(); 74 75 mWatchingContext = new BroadcastInterceptingContext(getContext()); 76 77 mMockNMService = createMock(INetworkManagementService.class); 78 mMockTime = createMock(TrustedTime.class); 79 80 mThrottleService = new ThrottleService( 81 mWatchingContext, mMockNMService, mMockTime, TEST_IFACE); 82 } 83 84 @Override 85 public void tearDown() throws Exception { 86 mWatchingContext = null; 87 mMockNMService = null; 88 89 mThrottleService.shutdown(); 90 mThrottleService = null; 91 92 clearThrottlePolicy(); 93 94 super.tearDown(); 95 } 96 97 public void testNoPolicyNotThrottled() throws Exception { 98 expectTimeCurrent(); 99 expectSystemReady(); 100 101 // provide stats without policy, verify not throttled 102 expectGetInterfaceCounter(1 * MB_IN_BYTES, 2 * MB_IN_BYTES); 103 expectSetInterfaceThrottle(-1, -1); 104 105 replay(mMockTime, mMockNMService); 106 systemReady(); 107 verify(mMockTime, mMockNMService); 108 } 109 110 public void testUnderLimitNotThrottled() throws Exception { 111 setThrottlePolicy(200 * MB_IN_BYTES, TEST_KBITPS, TEST_RESET_DAY); 112 113 expectTimeCurrent(); 114 expectSystemReady(); 115 116 // provide stats under limits, and verify not throttled 117 expectGetInterfaceCounter(1 * MB_IN_BYTES, 2 * MB_IN_BYTES); 118 expectSetInterfaceThrottle(-1, -1); 119 120 replay(mMockTime, mMockNMService); 121 systemReady(); 122 verify(mMockTime, mMockNMService); 123 } 124 125 public void testOverLimitThrottled() throws Exception { 126 setThrottlePolicy(200 * MB_IN_BYTES, TEST_KBITPS, TEST_RESET_DAY); 127 128 expectTimeCurrent(); 129 expectSystemReady(); 130 131 // provide stats over limits, and verify throttled 132 expectGetInterfaceCounter(500 * MB_IN_BYTES, 600 * MB_IN_BYTES); 133 expectSetInterfaceThrottle(TEST_KBITPS, TEST_KBITPS); 134 135 replay(mMockTime, mMockNMService); 136 systemReady(); 137 verify(mMockTime, mMockNMService); 138 } 139 140 public void testUnderThenOverLimitThrottled() throws Exception { 141 setThrottlePolicy(201 * MB_IN_BYTES, TEST_KBITPS, TEST_RESET_DAY); 142 143 expectTimeCurrent(); 144 expectSystemReady(); 145 146 // provide stats right under 201MB limit, verify not throttled 147 expectGetInterfaceCounter(100 * MB_IN_BYTES, 100 * MB_IN_BYTES); 148 expectSetInterfaceThrottle(-1, -1); 149 150 replay(mMockTime, mMockNMService); 151 systemReady(); 152 verify(mMockTime, mMockNMService); 153 reset(mMockTime, mMockNMService); 154 155 expectTimeCurrent(); 156 157 // adjust usage to bump over limit, verify throttle kicks in 158 expectGetInterfaceCounter(105 * MB_IN_BYTES, 100 * MB_IN_BYTES); 159 expectSetInterfaceThrottle(TEST_KBITPS, TEST_KBITPS); 160 161 // and kick poll event which should throttle 162 replay(mMockTime, mMockNMService); 163 forceServicePoll(); 164 verify(mMockTime, mMockNMService); 165 } 166 167 public void testUpdatedPolicyThrottled() throws Exception { 168 setThrottlePolicy(500 * MB_IN_BYTES, TEST_KBITPS, TEST_RESET_DAY); 169 170 expectTimeCurrent(); 171 expectSystemReady(); 172 173 // provide stats under limit, verify not throttled 174 expectGetInterfaceCounter(50 * MB_IN_BYTES, 50 * MB_IN_BYTES); 175 expectSetInterfaceThrottle(-1, -1); 176 177 replay(mMockTime, mMockNMService); 178 systemReady(); 179 verify(mMockTime, mMockNMService); 180 reset(mMockTime, mMockNMService); 181 182 expectTimeCurrent(); 183 184 // provide same stats, but verify that modified policy will throttle 185 expectGetInterfaceCounter(50 * MB_IN_BYTES, 50 * MB_IN_BYTES); 186 expectSetInterfaceThrottle(TEST_KBITPS, TEST_KBITPS); 187 188 replay(mMockTime, mMockNMService); 189 190 // now adjust policy to bump usage over limit 191 setThrottlePolicy(5 * MB_IN_BYTES, TEST_KBITPS, TEST_RESET_DAY); 192 193 // and wait for policy updated broadcast 194 mWatchingContext.nextBroadcastIntent(ThrottleManager.POLICY_CHANGED_ACTION).get(); 195 196 verify(mMockTime, mMockNMService); 197 } 198 199 public void testWithPolicyOverLimitThrottledAndRemovedAfterCycle() throws Exception { 200 setThrottlePolicy(90 * MB_IN_BYTES, TEST_KBITPS, TEST_RESET_DAY); 201 202 final long baseTime = System.currentTimeMillis(); 203 204 expectTime(baseTime); 205 expectSystemReady(); 206 207 // provide stats over limit, verify throttle kicks in 208 expectGetInterfaceCounter(50 * MB_IN_BYTES, 50 * MB_IN_BYTES); 209 expectSetInterfaceThrottle(TEST_KBITPS, TEST_KBITPS); 210 211 replay(mMockTime, mMockNMService); 212 systemReady(); 213 verify(mMockTime, mMockNMService); 214 reset(mMockTime, mMockNMService); 215 216 // pretend that time has jumped forward two months 217 expectTime(baseTime + DateUtils.WEEK_IN_MILLIS * 8); 218 219 // provide slightly updated stats, but verify throttle is removed 220 expectGetInterfaceCounter(60 * MB_IN_BYTES, 60 * MB_IN_BYTES); 221 expectSetInterfaceThrottle(-1, -1); 222 223 // and kick poll event which should throttle 224 replay(mMockTime, mMockNMService); 225 forceServiceReset(); 226 verify(mMockTime, mMockNMService); 227 } 228 229 @Suppress 230 public void testReturnStats() throws Exception { 231 final IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 232 final INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b); 233 234 // test is currently no-op, just exercises stats apis 235 Log.d(TAG, nmService.getNetworkStatsSummaryDev().toString()); 236 Log.d(TAG, nmService.getNetworkStatsSummaryXt().toString()); 237 Log.d(TAG, nmService.getNetworkStatsDetail().toString()); 238 } 239 240 /** 241 * Persist the given {@link ThrottleService} policy into {@link Settings}. 242 */ 243 public void setThrottlePolicy(long thresholdBytes, int valueKbitps, int resetDay) { 244 final ContentResolver resolver = getContext().getContentResolver(); 245 Settings.Global.putLong(resolver, Settings.Global.THROTTLE_THRESHOLD_BYTES, thresholdBytes); 246 Settings.Global.putInt(resolver, Settings.Global.THROTTLE_VALUE_KBITSPS, valueKbitps); 247 Settings.Global.putInt(resolver, Settings.Global.THROTTLE_RESET_DAY, resetDay); 248 } 249 250 /** 251 * Clear any {@link ThrottleService} policy from {@link Settings}. 252 */ 253 public void clearThrottlePolicy() { 254 final ContentResolver resolver = getContext().getContentResolver(); 255 Settings.Global.putString(resolver, Settings.Global.THROTTLE_THRESHOLD_BYTES, null); 256 Settings.Global.putString(resolver, Settings.Global.THROTTLE_VALUE_KBITSPS, null); 257 Settings.Global.putString(resolver, Settings.Global.THROTTLE_RESET_DAY, null); 258 } 259 260 /** 261 * Expect any {@link TrustedTime} mock calls, and respond with 262 * {@link System#currentTimeMillis()}. 263 */ 264 public void expectTimeCurrent() throws Exception { 265 expectTime(System.currentTimeMillis()); 266 } 267 268 /** 269 * Expect any {@link TrustedTime} mock calls, and respond with the given 270 * time in response to {@link TrustedTime#currentTimeMillis()}. 271 */ 272 public void expectTime(long currentTime) throws Exception { 273 expect(mMockTime.forceRefresh()).andReturn(false).anyTimes(); 274 expect(mMockTime.hasCache()).andReturn(true).anyTimes(); 275 expect(mMockTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); 276 expect(mMockTime.getCacheAge()).andReturn(0L).anyTimes(); 277 expect(mMockTime.getCacheCertainty()).andReturn(0L).anyTimes(); 278 } 279 280 /** 281 * Expect {@link ThrottleService#systemReady()} generated calls, such as 282 * connecting with {@link NetworkManagementService} mock. 283 */ 284 public void expectSystemReady() throws Exception { 285 mMockNMService.registerObserver(isA(INetworkManagementEventObserver.class)); 286 expectLastCall().atLeastOnce(); 287 } 288 289 /** 290 * Expect {@link NetworkManagementService#getNetworkStatsSummaryDev()} mock 291 * calls, responding with the given counter values. 292 */ 293 public void expectGetInterfaceCounter(long rx, long tx) throws Exception { 294 // TODO: provide elapsedRealtime mock to match TimeAuthority 295 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); 296 stats.addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, rx, 0L, tx, 0L, 0); 297 298 expect(mMockNMService.getNetworkStatsSummaryDev()).andReturn(stats).atLeastOnce(); 299 } 300 301 /** 302 * Expect {@link NetworkManagementService#setInterfaceThrottle} mock call 303 * with the specified parameters. 304 */ 305 public void expectSetInterfaceThrottle(int rx, int tx) throws Exception { 306 mMockNMService.setInterfaceThrottle(isA(String.class), eq(rx), eq(tx)); 307 expectLastCall().atLeastOnce(); 308 } 309 310 /** 311 * Dispatch {@link ThrottleService#systemReady()} and block until finished. 312 */ 313 public void systemReady() throws Exception { 314 final Future<Intent> policyChanged = mWatchingContext.nextBroadcastIntent( 315 ThrottleManager.POLICY_CHANGED_ACTION); 316 final Future<Intent> pollAction = mWatchingContext.nextBroadcastIntent( 317 ThrottleManager.THROTTLE_POLL_ACTION); 318 319 mThrottleService.systemReady(); 320 321 // wait for everything to settle; for policy to update and for first poll 322 policyChanged.get(); 323 pollAction.get(); 324 } 325 326 /** 327 * Dispatch {@link ThrottleService#dispatchPoll()} and block until finished. 328 */ 329 public void forceServicePoll() throws Exception { 330 // during systemReady() service already pushed a sticky broadcast, so we 331 // need to skip the immediate and wait for the updated sticky. 332 final Future<Intent> pollAction = mWatchingContext.nextBroadcastIntent( 333 ThrottleManager.THROTTLE_POLL_ACTION); 334 335 mThrottleService.dispatchPoll(); 336 337 pollAction.get(); 338 } 339 340 /** 341 * Dispatch {@link ThrottleService#dispatchReset()} and block until finished. 342 */ 343 public void forceServiceReset() throws Exception { 344 // during systemReady() service already pushed a sticky broadcast, so we 345 // need to skip the immediate and wait for the updated sticky. 346 final Future<Intent> pollAction = mWatchingContext.nextBroadcastIntent( 347 ThrottleManager.THROTTLE_POLL_ACTION); 348 349 mThrottleService.dispatchReset(); 350 351 pollAction.get(); 352 } 353} 354