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 android.content.Context; 20import android.net.LocalSocket; 21import android.net.LocalServerSocket; 22import android.os.Binder; 23import android.test.AndroidTestCase; 24import android.test.suitebuilder.annotation.LargeTest; 25import com.android.server.net.BaseNetworkObserver; 26 27import static org.mockito.Mockito.doReturn; 28import static org.mockito.Mockito.mock; 29import static org.mockito.Mockito.reset; 30import static org.mockito.Mockito.timeout; 31import static org.mockito.Mockito.verify; 32import static org.mockito.Mockito.verifyNoMoreInteractions; 33 34import java.io.IOException; 35import java.io.OutputStream; 36 37/** 38 * Tests for {@link NetworkManagementService}. 39 */ 40@LargeTest 41public class NetworkManagementServiceTest extends AndroidTestCase { 42 43 private static final String SOCKET_NAME = "__test__NetworkManagementServiceTest"; 44 private NetworkManagementService mNMService; 45 private LocalServerSocket mServerSocket; 46 private LocalSocket mSocket; 47 private OutputStream mOutputStream; 48 49 @Override 50 public void setUp() throws Exception { 51 super.setUp(); 52 // TODO: make this unnecessary. runtest might already make it unnecessary. 53 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); 54 55 // Set up a sheltered test environment. 56 BroadcastInterceptingContext context = new BroadcastInterceptingContext(getContext()); 57 mServerSocket = new LocalServerSocket(SOCKET_NAME); 58 59 // Start the service and wait until it connects to our socket. 60 mNMService = NetworkManagementService.create(context, SOCKET_NAME); 61 mSocket = mServerSocket.accept(); 62 mOutputStream = mSocket.getOutputStream(); 63 } 64 65 @Override 66 public void tearDown() throws Exception { 67 if (mSocket != null) mSocket.close(); 68 if (mServerSocket != null) mServerSocket.close(); 69 super.tearDown(); 70 } 71 72 /** 73 * Sends a message on the netd socket and gives the events some time to make it back. 74 */ 75 private void sendMessage(String message) throws IOException { 76 // Strings are null-terminated, so add "\0" at the end. 77 mOutputStream.write((message + "\0").getBytes()); 78 } 79 80 private static <T> T expectSoon(T mock) { 81 return verify(mock, timeout(100)); 82 } 83 84 /** 85 * Tests that network observers work properly. 86 */ 87 public void testNetworkObservers() throws Exception { 88 BaseNetworkObserver observer = mock(BaseNetworkObserver.class); 89 doReturn(new Binder()).when(observer).asBinder(); // Used by registerObserver. 90 mNMService.registerObserver(observer); 91 92 // Forget everything that happened to the mock so far, so we can explicitly verify 93 // everything that happens and does not happen to it from now on. 94 reset(observer); 95 96 // Now send NetworkManagementService messages and ensure that the observer methods are 97 // called. After every valid message we expect a callback soon after; to ensure that 98 // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end. 99 100 /** 101 * Interface changes. 102 */ 103 sendMessage("600 Iface added rmnet12"); 104 expectSoon(observer).interfaceAdded("rmnet12"); 105 106 sendMessage("600 Iface removed eth1"); 107 expectSoon(observer).interfaceRemoved("eth1"); 108 109 sendMessage("607 Iface removed eth1"); 110 // Invalid code. 111 112 sendMessage("600 Iface borked lo down"); 113 // Invalid event. 114 115 sendMessage("600 Iface changed clat4 up again"); 116 // Extra tokens. 117 118 sendMessage("600 Iface changed clat4 up"); 119 expectSoon(observer).interfaceStatusChanged("clat4", true); 120 121 sendMessage("600 Iface linkstate rmnet0 down"); 122 expectSoon(observer).interfaceLinkStateChanged("rmnet0", false); 123 124 sendMessage("600 IFACE linkstate clat4 up"); 125 // Invalid group. 126 127 /** 128 * Bandwidth control events. 129 */ 130 sendMessage("601 limit alert data rmnet_usb0"); 131 expectSoon(observer).limitReached("data", "rmnet_usb0"); 132 133 sendMessage("601 invalid alert data rmnet0"); 134 // Invalid group. 135 136 sendMessage("601 limit increased data rmnet0"); 137 // Invalid event. 138 139 140 /** 141 * Interface class activity. 142 */ 143 sendMessage("613 IfaceClass active rmnet0"); 144 expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true); 145 146 sendMessage("613 IfaceClass idle eth0"); 147 expectSoon(observer).interfaceClassDataActivityChanged("eth0", false); 148 149 sendMessage("613 IfaceClass reallyactive rmnet0"); 150 expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false); 151 152 sendMessage("613 InterfaceClass reallyactive rmnet0"); 153 // Invalid group. 154 155 156 /** 157 * IP address changes. 158 */ 159 sendMessage("614 Address updated fe80::1/64 wlan0 128 253"); 160 expectSoon(observer).addressUpdated("fe80::1/64", "wlan0", 128, 253); 161 162 // There is no "added". 163 sendMessage("614 Address added fe80::1/64 wlan0 128 253"); 164 expectSoon(observer).addressRemoved("fe80::1/64", "wlan0", 128, 253); 165 166 sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0"); 167 expectSoon(observer).addressRemoved("2001:db8::1/64", "wlan0", 1, 0); 168 169 sendMessage("666 Address added 2001:db8::1/64 wlan0 1 0"); 170 // Invalid code. 171 172 // Make sure nothing else was called. 173 verifyNoMoreInteractions(observer); 174 } 175} 176