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 org.mockito.Mockito.doReturn; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.reset; 22 import static org.mockito.Mockito.timeout; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.verifyNoMoreInteractions; 25 26 import android.content.Context; 27 import android.net.INetd; 28 import android.net.LinkAddress; 29 import android.net.LocalSocket; 30 import android.net.LocalServerSocket; 31 import android.os.BatteryStats; 32 import android.os.Binder; 33 import android.os.IBinder; 34 import android.support.test.runner.AndroidJUnit4; 35 import android.test.suitebuilder.annotation.SmallTest; 36 37 import com.android.internal.app.IBatteryStats; 38 import com.android.server.NetworkManagementService.SystemServices; 39 import com.android.server.net.BaseNetworkObserver; 40 41 import java.io.IOException; 42 import java.io.OutputStream; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.Mock; 49 import org.mockito.MockitoAnnotations; 50 51 /** 52 * Tests for {@link NetworkManagementService}. 53 */ 54 @RunWith(AndroidJUnit4.class) 55 @SmallTest 56 public class NetworkManagementServiceTest { 57 58 private static final String SOCKET_NAME = "__test__NetworkManagementServiceTest"; 59 private NetworkManagementService mNMService; 60 private LocalServerSocket mServerSocket; 61 private LocalSocket mSocket; 62 private OutputStream mOutputStream; 63 64 @Mock private Context mContext; 65 @Mock private IBatteryStats.Stub mBatteryStatsService; 66 @Mock private INetd.Stub mNetdService; 67 68 private final SystemServices mServices = new SystemServices() { 69 @Override 70 public IBinder getService(String name) { 71 switch (name) { 72 case BatteryStats.SERVICE_NAME: 73 return mBatteryStatsService; 74 default: 75 throw new UnsupportedOperationException("Unknown service " + name); 76 } 77 } 78 @Override 79 public void registerLocalService(NetworkManagementInternal nmi) { 80 } 81 @Override 82 public INetd getNetd() { 83 return mNetdService; 84 } 85 }; 86 87 @Before setUp()88 public void setUp() throws Exception { 89 MockitoAnnotations.initMocks(this); 90 91 // Set up a sheltered test environment. 92 mServerSocket = new LocalServerSocket(SOCKET_NAME); 93 94 // Start the service and wait until it connects to our socket. 95 mNMService = NetworkManagementService.create(mContext, SOCKET_NAME, mServices); 96 mSocket = mServerSocket.accept(); 97 mOutputStream = mSocket.getOutputStream(); 98 } 99 100 @After tearDown()101 public void tearDown() throws Exception { 102 mNMService.shutdown(); 103 // Once NetworkManagementService#shutdown() actually does something and shutdowns 104 // the underlying NativeDaemonConnector, the block below should be uncommented. 105 // if (mOutputStream != null) mOutputStream.close(); 106 // if (mSocket != null) mSocket.close(); 107 // if (mServerSocket != null) mServerSocket.close(); 108 } 109 110 /** 111 * Sends a message on the netd socket and gives the events some time to make it back. 112 */ sendMessage(String message)113 private void sendMessage(String message) throws IOException { 114 // Strings are null-terminated, so add "\0" at the end. 115 mOutputStream.write((message + "\0").getBytes()); 116 } 117 expectSoon(T mock)118 private static <T> T expectSoon(T mock) { 119 return verify(mock, timeout(200)); 120 } 121 122 /** 123 * Tests that network observers work properly. 124 */ 125 @Test testNetworkObservers()126 public void testNetworkObservers() throws Exception { 127 BaseNetworkObserver observer = mock(BaseNetworkObserver.class); 128 doReturn(new Binder()).when(observer).asBinder(); // Used by registerObserver. 129 mNMService.registerObserver(observer); 130 131 // Forget everything that happened to the mock so far, so we can explicitly verify 132 // everything that happens and does not happen to it from now on. 133 reset(observer); 134 135 // Now send NetworkManagementService messages and ensure that the observer methods are 136 // called. After every valid message we expect a callback soon after; to ensure that 137 // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end. 138 139 /** 140 * Interface changes. 141 */ 142 sendMessage("600 Iface added rmnet12"); 143 expectSoon(observer).interfaceAdded("rmnet12"); 144 145 sendMessage("600 Iface removed eth1"); 146 expectSoon(observer).interfaceRemoved("eth1"); 147 148 sendMessage("607 Iface removed eth1"); 149 // Invalid code. 150 151 sendMessage("600 Iface borked lo down"); 152 // Invalid event. 153 154 sendMessage("600 Iface changed clat4 up again"); 155 // Extra tokens. 156 157 sendMessage("600 Iface changed clat4 up"); 158 expectSoon(observer).interfaceStatusChanged("clat4", true); 159 160 sendMessage("600 Iface linkstate rmnet0 down"); 161 expectSoon(observer).interfaceLinkStateChanged("rmnet0", false); 162 163 sendMessage("600 IFACE linkstate clat4 up"); 164 // Invalid group. 165 166 /** 167 * Bandwidth control events. 168 */ 169 sendMessage("601 limit alert data rmnet_usb0"); 170 expectSoon(observer).limitReached("data", "rmnet_usb0"); 171 172 sendMessage("601 invalid alert data rmnet0"); 173 // Invalid group. 174 175 sendMessage("601 limit increased data rmnet0"); 176 // Invalid event. 177 178 179 /** 180 * Interface class activity. 181 */ 182 183 sendMessage("613 IfaceClass active 1 1234 10012"); 184 expectSoon(observer).interfaceClassDataActivityChanged("1", true, 1234); 185 186 sendMessage("613 IfaceClass idle 9 5678"); 187 expectSoon(observer).interfaceClassDataActivityChanged("9", false, 5678); 188 189 sendMessage("613 IfaceClass reallyactive 9 4321"); 190 expectSoon(observer).interfaceClassDataActivityChanged("9", false, 4321); 191 192 sendMessage("613 InterfaceClass reallyactive 1"); 193 // Invalid group. 194 195 196 /** 197 * IP address changes. 198 */ 199 sendMessage("614 Address updated fe80::1/64 wlan0 128 253"); 200 expectSoon(observer).addressUpdated("wlan0", new LinkAddress("fe80::1/64", 128, 253)); 201 202 // There is no "added", so we take this as "removed". 203 sendMessage("614 Address added fe80::1/64 wlan0 128 253"); 204 expectSoon(observer).addressRemoved("wlan0", new LinkAddress("fe80::1/64", 128, 253)); 205 206 sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0"); 207 expectSoon(observer).addressRemoved("wlan0", new LinkAddress("2001:db8::1/64", 1, 0)); 208 209 sendMessage("614 Address removed 2001:db8::1/64 wlan0 1"); 210 // Not enough arguments. 211 212 sendMessage("666 Address removed 2001:db8::1/64 wlan0 1 0"); 213 // Invalid code. 214 215 216 /** 217 * DNS information broadcasts. 218 */ 219 sendMessage("615 DnsInfo servers rmnet_usb0 3600 2001:db8::1"); 220 expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600, 221 new String[]{"2001:db8::1"}); 222 223 sendMessage("615 DnsInfo servers wlan0 14400 2001:db8::1,2001:db8::2"); 224 expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400, 225 new String[]{"2001:db8::1", "2001:db8::2"}); 226 227 // We don't check for negative lifetimes, only for parse errors. 228 sendMessage("615 DnsInfo servers wlan0 -3600 ::1"); 229 expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600, 230 new String[]{"::1"}); 231 232 sendMessage("615 DnsInfo servers wlan0 SIXHUNDRED ::1"); 233 // Non-numeric lifetime. 234 235 sendMessage("615 DnsInfo servers wlan0 2001:db8::1"); 236 // Missing lifetime. 237 238 sendMessage("615 DnsInfo servers wlan0 3600"); 239 // No servers. 240 241 sendMessage("615 DnsInfo servers 3600 wlan0 2001:db8::1,2001:db8::2"); 242 // Non-numeric lifetime. 243 244 sendMessage("615 DnsInfo wlan0 7200 2001:db8::1,2001:db8::2"); 245 // Invalid tokens. 246 247 sendMessage("666 DnsInfo servers wlan0 5400 2001:db8::1"); 248 // Invalid code. 249 250 // No syntax checking on the addresses. 251 sendMessage("615 DnsInfo servers wlan0 600 ,::,,foo,::1,"); 252 expectSoon(observer).interfaceDnsServerInfo("wlan0", 600, 253 new String[]{"", "::", "", "foo", "::1"}); 254 255 // Make sure nothing else was called. 256 verifyNoMoreInteractions(observer); 257 } 258 } 259