Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2012 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.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
     20 import static android.net.ConnectivityManager.TYPE_MOBILE;
     21 import static android.net.ConnectivityManager.TYPE_WIFI;
     22 import static android.net.ConnectivityManager.getNetworkTypeName;
     23 import static android.net.NetworkStateTracker.EVENT_STATE_CHANGED;
     24 import static org.mockito.Matchers.anyInt;
     25 import static org.mockito.Matchers.eq;
     26 import static org.mockito.Matchers.isA;
     27 import static org.mockito.Mockito.doNothing;
     28 import static org.mockito.Mockito.doReturn;
     29 import static org.mockito.Mockito.doThrow;
     30 import static org.mockito.Mockito.mock;
     31 import static org.mockito.Mockito.reset;
     32 import static org.mockito.Mockito.verify;
     33 
     34 import android.content.Context;
     35 import android.net.INetworkPolicyManager;
     36 import android.net.INetworkStatsService;
     37 import android.net.LinkProperties;
     38 import android.net.NetworkConfig;
     39 import android.net.NetworkInfo;
     40 import android.net.NetworkInfo.DetailedState;
     41 import android.net.NetworkStateTracker;
     42 import android.net.RouteInfo;
     43 import android.os.Handler;
     44 import android.os.INetworkManagementService;
     45 import android.test.AndroidTestCase;
     46 import android.test.suitebuilder.annotation.LargeTest;
     47 import android.util.Log;
     48 import android.util.LogPrinter;
     49 
     50 import org.mockito.ArgumentCaptor;
     51 
     52 import java.net.InetAddress;
     53 import java.util.concurrent.Future;
     54 
     55 /**
     56  * Tests for {@link ConnectivityService}.
     57  */
     58 @LargeTest
     59 public class ConnectivityServiceTest extends AndroidTestCase {
     60     private static final String TAG = "ConnectivityServiceTest";
     61 
     62     private static final String MOBILE_IFACE = "rmnet3";
     63     private static final String WIFI_IFACE = "wlan6";
     64 
     65     private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33"),
     66                                                                              MOBILE_IFACE);
     67     private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33"),
     68                                                                              MOBILE_IFACE);
     69 
     70     private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute(parse("192.168.0.66"),
     71                                                                            parse("192.168.0.1"),
     72                                                                            WIFI_IFACE);
     73     private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::66"),
     74                                                                            parse("fd00::"),
     75                                                                            WIFI_IFACE);
     76 
     77     private INetworkManagementService mNetManager;
     78     private INetworkStatsService mStatsService;
     79     private INetworkPolicyManager mPolicyService;
     80     private ConnectivityService.NetworkFactory mNetFactory;
     81 
     82     private BroadcastInterceptingContext mServiceContext;
     83     private ConnectivityService mService;
     84 
     85     private MockNetwork mMobile;
     86     private MockNetwork mWifi;
     87 
     88     private Handler mTrackerHandler;
     89 
     90     private static class MockNetwork {
     91         public NetworkStateTracker tracker;
     92         public NetworkInfo info;
     93         public LinkProperties link;
     94 
     95         public MockNetwork(int type) {
     96             tracker = mock(NetworkStateTracker.class);
     97             info = new NetworkInfo(type, -1, getNetworkTypeName(type), null);
     98             link = new LinkProperties();
     99         }
    100 
    101         public void doReturnDefaults() {
    102             // TODO: eventually CS should make defensive copies
    103             doReturn(new NetworkInfo(info)).when(tracker).getNetworkInfo();
    104             doReturn(new LinkProperties(link)).when(tracker).getLinkProperties();
    105 
    106             // fallback to default TCP buffers
    107             doReturn("").when(tracker).getTcpBufferSizesPropName();
    108         }
    109     }
    110 
    111     @Override
    112     public void setUp() throws Exception {
    113         super.setUp();
    114 
    115         mServiceContext = new BroadcastInterceptingContext(getContext());
    116 
    117         mNetManager = mock(INetworkManagementService.class);
    118         mStatsService = mock(INetworkStatsService.class);
    119         mPolicyService = mock(INetworkPolicyManager.class);
    120         mNetFactory = mock(ConnectivityService.NetworkFactory.class);
    121 
    122         mMobile = new MockNetwork(TYPE_MOBILE);
    123         mWifi = new MockNetwork(TYPE_WIFI);
    124 
    125         // omit most network trackers
    126         doThrow(new IllegalArgumentException("Not supported in test environment"))
    127                 .when(mNetFactory).createTracker(anyInt(), isA(NetworkConfig.class));
    128 
    129         doReturn(mMobile.tracker)
    130                 .when(mNetFactory).createTracker(eq(TYPE_MOBILE), isA(NetworkConfig.class));
    131         doReturn(mWifi.tracker)
    132                 .when(mNetFactory).createTracker(eq(TYPE_WIFI), isA(NetworkConfig.class));
    133 
    134         final ArgumentCaptor<Handler> trackerHandler = ArgumentCaptor.forClass(Handler.class);
    135         doNothing().when(mMobile.tracker)
    136                 .startMonitoring(isA(Context.class), trackerHandler.capture());
    137 
    138         mService = new ConnectivityService(
    139                 mServiceContext, mNetManager, mStatsService, mPolicyService, mNetFactory);
    140         mService.systemReady();
    141 
    142         mTrackerHandler = trackerHandler.getValue();
    143         mTrackerHandler.getLooper().setMessageLogging(new LogPrinter(Log.INFO, TAG));
    144     }
    145 
    146     @Override
    147     public void tearDown() throws Exception {
    148         super.tearDown();
    149     }
    150 
    151     public void testMobileConnectedAddedRoutes() throws Exception {
    152         Future<?> nextConnBroadcast;
    153 
    154         // bring up mobile network
    155         mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
    156         mMobile.link.setInterfaceName(MOBILE_IFACE);
    157         mMobile.link.addRoute(MOBILE_ROUTE_V4);
    158         mMobile.link.addRoute(MOBILE_ROUTE_V6);
    159         mMobile.doReturnDefaults();
    160 
    161         nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
    162         mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
    163         nextConnBroadcast.get();
    164 
    165         // verify that both routes were added and DNS was flushed
    166         verify(mNetManager).addRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V4));
    167         verify(mNetManager).addRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V6));
    168         verify(mNetManager).flushInterfaceDnsCache(MOBILE_IFACE);
    169 
    170     }
    171 
    172     public void testMobileWifiHandoff() throws Exception {
    173         Future<?> nextConnBroadcast;
    174 
    175         // bring up mobile network
    176         mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
    177         mMobile.link.setInterfaceName(MOBILE_IFACE);
    178         mMobile.link.addRoute(MOBILE_ROUTE_V4);
    179         mMobile.link.addRoute(MOBILE_ROUTE_V6);
    180         mMobile.doReturnDefaults();
    181 
    182         nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
    183         mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
    184         nextConnBroadcast.get();
    185 
    186         reset(mNetManager);
    187 
    188         // now bring up wifi network
    189         mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null);
    190         mWifi.link.setInterfaceName(WIFI_IFACE);
    191         mWifi.link.addRoute(WIFI_ROUTE_V4);
    192         mWifi.link.addRoute(WIFI_ROUTE_V6);
    193         mWifi.doReturnDefaults();
    194 
    195         // expect that mobile will be torn down
    196         doReturn(true).when(mMobile.tracker).teardown();
    197 
    198         nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
    199         mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
    200         nextConnBroadcast.get();
    201 
    202         // verify that wifi routes added, and teardown requested
    203         verify(mNetManager).addRoute(eq(WIFI_IFACE), eq(WIFI_ROUTE_V4));
    204         verify(mNetManager).addRoute(eq(WIFI_IFACE), eq(WIFI_ROUTE_V6));
    205         verify(mNetManager).flushInterfaceDnsCache(WIFI_IFACE);
    206         verify(mMobile.tracker).teardown();
    207 
    208         reset(mNetManager, mMobile.tracker);
    209 
    210         // tear down mobile network, as requested
    211         mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null);
    212         mMobile.link.clear();
    213         mMobile.doReturnDefaults();
    214 
    215         nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
    216         mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
    217         nextConnBroadcast.get();
    218 
    219         verify(mNetManager).removeRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V4));
    220         verify(mNetManager).removeRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V6));
    221 
    222     }
    223 
    224     private static InetAddress parse(String addr) {
    225         return InetAddress.parseNumericAddress(addr);
    226     }
    227 }
    228