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
17package com.android.server;
18
19import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
20import static android.net.ConnectivityManager.TYPE_MOBILE;
21import static android.net.ConnectivityManager.TYPE_WIFI;
22import static android.net.ConnectivityManager.getNetworkTypeName;
23import static android.net.NetworkStateTracker.EVENT_STATE_CHANGED;
24import static org.mockito.Matchers.anyInt;
25import static org.mockito.Matchers.eq;
26import static org.mockito.Matchers.isA;
27import static org.mockito.Mockito.doNothing;
28import static org.mockito.Mockito.doReturn;
29import static org.mockito.Mockito.doThrow;
30import static org.mockito.Mockito.mock;
31import static org.mockito.Mockito.reset;
32import static org.mockito.Mockito.verify;
33
34import android.content.Context;
35import android.net.INetworkPolicyManager;
36import android.net.INetworkStatsService;
37import android.net.LinkProperties;
38import android.net.NetworkConfig;
39import android.net.NetworkInfo;
40import android.net.NetworkInfo.DetailedState;
41import android.net.RouteInfo;
42import android.os.Handler;
43import android.os.INetworkManagementService;
44import android.test.AndroidTestCase;
45import android.test.suitebuilder.annotation.LargeTest;
46import android.util.Log;
47import android.util.LogPrinter;
48
49import org.mockito.ArgumentCaptor;
50
51import java.net.InetAddress;
52import java.util.concurrent.Future;
53
54/**
55 * Tests for {@link ConnectivityService}.
56 */
57@LargeTest
58public class ConnectivityServiceTest extends AndroidTestCase {
59    private static final String TAG = "ConnectivityServiceTest";
60
61    private static final String MOBILE_IFACE = "rmnet3";
62    private static final String WIFI_IFACE = "wlan6";
63
64    private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33"),
65                                                                             MOBILE_IFACE);
66    private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33"),
67                                                                             MOBILE_IFACE);
68
69    private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute(parse("192.168.0.66"),
70                                                                           parse("192.168.0.1"),
71                                                                           WIFI_IFACE);
72    private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::66"),
73                                                                           parse("fd00::"),
74                                                                           WIFI_IFACE);
75
76    private INetworkManagementService mNetManager;
77    private INetworkStatsService mStatsService;
78    private INetworkPolicyManager mPolicyService;
79//    private ConnectivityService.NetworkFactory mNetFactory;
80
81    private BroadcastInterceptingContext mServiceContext;
82    private ConnectivityService mService;
83
84// TODO: rework with network factory
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);
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
166//        int mobileNetId = mMobile.tracker.getNetwork().netId;
167//        verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
168//        verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
169//    }
170//
171//    public void testMobileWifiHandoff() throws Exception {
172//        Future<?> nextConnBroadcast;
173//
174//        // bring up mobile network
175//        mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
176//        mMobile.link.setInterfaceName(MOBILE_IFACE);
177//        mMobile.link.addRoute(MOBILE_ROUTE_V4);
178//        mMobile.link.addRoute(MOBILE_ROUTE_V6);
179//        mMobile.doReturnDefaults();
180//
181//        nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
182//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
183//        nextConnBroadcast.get();
184//
185//        reset(mNetManager);
186//
187//        // now bring up wifi network
188//        mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null);
189//        mWifi.link.setInterfaceName(WIFI_IFACE);
190//        mWifi.link.addRoute(WIFI_ROUTE_V4);
191//        mWifi.link.addRoute(WIFI_ROUTE_V6);
192//        mWifi.doReturnDefaults();
193//
194//        // expect that mobile will be torn down
195//        doReturn(true).when(mMobile.tracker).teardown();
196//
197//        nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
198//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
199//        nextConnBroadcast.get();
200//
201//        // verify that wifi routes added, and teardown requested
202//        int wifiNetId = mWifi.tracker.getNetwork().netId;
203//        verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V4));
204//        verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V6));
205//        verify(mMobile.tracker).teardown();
206//
207//        int mobileNetId = mMobile.tracker.getNetwork().netId;
208//
209//        reset(mNetManager, mMobile.tracker);
210//
211//        // tear down mobile network, as requested
212//        mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null);
213//        mMobile.link.clear();
214//        mMobile.doReturnDefaults();
215//
216//        nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE);
217//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
218//        nextConnBroadcast.get();
219//
220//        verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
221//        verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
222//
223//    }
224
225    private static InetAddress parse(String addr) {
226        return InetAddress.parseNumericAddress(addr);
227    }
228
229}
230