Home | History | Annotate | Download | only in server
      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
     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.getNetworkStatsSummary().toString());
    236         Log.d(TAG, nmService.getNetworkStatsDetail().toString());
    237     }
    238 
    239     /**
    240      * Persist the given {@link ThrottleService} policy into {@link Settings}.
    241      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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