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 17 package com.android.server; 18 19 import static android.net.NetworkStats.SET_DEFAULT; 20 import static android.net.NetworkStats.TAG_NONE; 21 import static android.net.NetworkStats.UID_ALL; 22 import static org.easymock.EasyMock.createMock; 23 import static org.easymock.EasyMock.eq; 24 import static org.easymock.EasyMock.expect; 25 import static org.easymock.EasyMock.expectLastCall; 26 import static org.easymock.EasyMock.isA; 27 import static org.easymock.EasyMock.replay; 28 import static org.easymock.EasyMock.reset; 29 import static org.easymock.EasyMock.verify; 30 31 import android.content.ContentResolver; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.net.INetworkManagementEventObserver; 35 import android.net.NetworkStats; 36 import android.net.ThrottleManager; 37 import android.os.IBinder; 38 import android.os.INetworkManagementService; 39 import android.os.ServiceManager; 40 import android.os.SystemClock; 41 import android.provider.Settings; 42 import android.test.AndroidTestCase; 43 import android.test.suitebuilder.annotation.LargeTest; 44 import android.test.suitebuilder.annotation.Suppress; 45 import android.text.format.DateUtils; 46 import android.util.Log; 47 import android.util.TrustedTime; 48 49 import java.util.concurrent.Future; 50 51 /** 52 * Tests for {@link ThrottleService}. 53 */ 54 @LargeTest 55 public 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 setUp()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 tearDown()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 testNoPolicyNotThrottled()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 testUnderLimitNotThrottled()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 testOverLimitThrottled()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 testUnderThenOverLimitThrottled()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 testUpdatedPolicyThrottled()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 testWithPolicyOverLimitThrottledAndRemovedAfterCycle()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 testReturnStats()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.getNetworkStatsSummary().toString()); 236 Log.d(TAG, nmService.getNetworkStatsDetail().toString()); 237 } 238 239 /** 240 * Persist the given {@link ThrottleService} policy into {@link Settings}. 241 */ setThrottlePolicy(long thresholdBytes, int valueKbitps, int resetDay)242 public void setThrottlePolicy(long thresholdBytes, int valueKbitps, int resetDay) { 243 final ContentResolver resolver = getContext().getContentResolver(); 244 Settings.Secure.putLong(resolver, Settings.Secure.THROTTLE_THRESHOLD_BYTES, thresholdBytes); 245 Settings.Secure.putInt(resolver, Settings.Secure.THROTTLE_VALUE_KBITSPS, valueKbitps); 246 Settings.Secure.putInt(resolver, Settings.Secure.THROTTLE_RESET_DAY, resetDay); 247 } 248 249 /** 250 * Clear any {@link ThrottleService} policy from {@link Settings}. 251 */ clearThrottlePolicy()252 public void clearThrottlePolicy() { 253 final ContentResolver resolver = getContext().getContentResolver(); 254 Settings.Secure.putString(resolver, Settings.Secure.THROTTLE_THRESHOLD_BYTES, null); 255 Settings.Secure.putString(resolver, Settings.Secure.THROTTLE_VALUE_KBITSPS, null); 256 Settings.Secure.putString(resolver, Settings.Secure.THROTTLE_RESET_DAY, null); 257 } 258 259 /** 260 * Expect any {@link TrustedTime} mock calls, and respond with 261 * {@link System#currentTimeMillis()}. 262 */ expectTimeCurrent()263 public void expectTimeCurrent() throws Exception { 264 expectTime(System.currentTimeMillis()); 265 } 266 267 /** 268 * Expect any {@link TrustedTime} mock calls, and respond with the given 269 * time in response to {@link TrustedTime#currentTimeMillis()}. 270 */ expectTime(long currentTime)271 public void expectTime(long currentTime) throws Exception { 272 expect(mMockTime.forceRefresh()).andReturn(false).anyTimes(); 273 expect(mMockTime.hasCache()).andReturn(true).anyTimes(); 274 expect(mMockTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); 275 expect(mMockTime.getCacheAge()).andReturn(0L).anyTimes(); 276 expect(mMockTime.getCacheCertainty()).andReturn(0L).anyTimes(); 277 } 278 279 /** 280 * Expect {@link ThrottleService#systemReady()} generated calls, such as 281 * connecting with {@link NetworkManagementService} mock. 282 */ expectSystemReady()283 public void expectSystemReady() throws Exception { 284 mMockNMService.registerObserver(isA(INetworkManagementEventObserver.class)); 285 expectLastCall().atLeastOnce(); 286 } 287 288 /** 289 * Expect {@link NetworkManagementService#getNetworkStatsSummary()} mock 290 * calls, responding with the given counter values. 291 */ expectGetInterfaceCounter(long rx, long tx)292 public void expectGetInterfaceCounter(long rx, long tx) throws Exception { 293 // TODO: provide elapsedRealtime mock to match TimeAuthority 294 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); 295 stats.addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, rx, 0L, tx, 0L, 0); 296 297 expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats).atLeastOnce(); 298 } 299 300 /** 301 * Expect {@link NetworkManagementService#setInterfaceThrottle} mock call 302 * with the specified parameters. 303 */ expectSetInterfaceThrottle(int rx, int tx)304 public void expectSetInterfaceThrottle(int rx, int tx) throws Exception { 305 mMockNMService.setInterfaceThrottle(isA(String.class), eq(rx), eq(tx)); 306 expectLastCall().atLeastOnce(); 307 } 308 309 /** 310 * Dispatch {@link ThrottleService#systemReady()} and block until finished. 311 */ systemReady()312 public void systemReady() throws Exception { 313 final Future<Intent> policyChanged = mWatchingContext.nextBroadcastIntent( 314 ThrottleManager.POLICY_CHANGED_ACTION); 315 final Future<Intent> pollAction = mWatchingContext.nextBroadcastIntent( 316 ThrottleManager.THROTTLE_POLL_ACTION); 317 318 mThrottleService.systemReady(); 319 320 // wait for everything to settle; for policy to update and for first poll 321 policyChanged.get(); 322 pollAction.get(); 323 } 324 325 /** 326 * Dispatch {@link ThrottleService#dispatchPoll()} and block until finished. 327 */ forceServicePoll()328 public void forceServicePoll() throws Exception { 329 // during systemReady() service already pushed a sticky broadcast, so we 330 // need to skip the immediate and wait for the updated sticky. 331 final Future<Intent> pollAction = mWatchingContext.nextBroadcastIntent( 332 ThrottleManager.THROTTLE_POLL_ACTION); 333 334 mThrottleService.dispatchPoll(); 335 336 pollAction.get(); 337 } 338 339 /** 340 * Dispatch {@link ThrottleService#dispatchReset()} and block until finished. 341 */ forceServiceReset()342 public void forceServiceReset() throws Exception { 343 // during systemReady() service already pushed a sticky broadcast, so we 344 // need to skip the immediate and wait for the updated sticky. 345 final Future<Intent> pollAction = mWatchingContext.nextBroadcastIntent( 346 ThrottleManager.THROTTLE_POLL_ACTION); 347 348 mThrottleService.dispatchReset(); 349 350 pollAction.get(); 351 } 352 } 353