• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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