WifiStateMachinePrimeTest.java revision bfc30bd4c2ff0c62d6cfff22088a935878966a46
1/* 2 * Copyright (C) 2016 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.wifi; 18 19import static org.junit.Assert.assertEquals; 20import static org.mockito.Mockito.*; 21 22import android.net.wifi.IApInterface; 23import android.net.wifi.IWificond; 24import android.net.wifi.WifiConfiguration; 25import android.net.wifi.WifiManager; 26import android.os.INetworkManagementService; 27import android.os.test.TestLooper; 28import android.test.suitebuilder.annotation.SmallTest; 29import android.util.Log; 30 31import org.junit.After; 32import org.junit.Before; 33import org.junit.Test; 34import org.mockito.Mock; 35import org.mockito.MockitoAnnotations; 36import org.mockito.invocation.InvocationOnMock; 37import org.mockito.stubbing.Answer; 38 39/** 40 * Unit tests for {@link com.android.server.wifi.WifiStateMachinePrime}. 41 */ 42@SmallTest 43public class WifiStateMachinePrimeTest { 44 public static final String TAG = "WifiStateMachinePrimeTest"; 45 46 private static final String CLIENT_MODE_STATE_STRING = "ClientModeState"; 47 private static final String SCAN_ONLY_MODE_STATE_STRING = "ScanOnlyModeState"; 48 private static final String SOFT_AP_MODE_STATE_STRING = "SoftAPModeState"; 49 private static final String WIFI_DISABLED_STATE_STRING = "WifiDisabledState"; 50 private static final String CLIENT_MODE_ACTIVE_STATE_STRING = "ClientModeActiveState"; 51 private static final String SCAN_ONLY_MODE_ACTIVE_STATE_STRING = "ScanOnlyModeActiveState"; 52 private static final String SOFT_AP_MODE_ACTIVE_STATE_STRING = "SoftAPModeActiveState"; 53 54 @Mock WifiInjector mWifiInjector; 55 TestLooper mLooper; 56 @Mock IWificond mWificond; 57 @Mock IApInterface mApInterface; 58 @Mock INetworkManagementService mNMService; 59 @Mock SoftApManager mSoftApManager; 60 SoftApManager.Listener mSoftApListener; 61 @Mock WifiConfiguration mApConfig; 62 WifiStateMachinePrime mWifiStateMachinePrime; 63 64 /** 65 * Set up the test environment. 66 */ 67 @Before 68 public void setUp() throws Exception { 69 Log.d(TAG, "Setting up ..."); 70 71 MockitoAnnotations.initMocks(this); 72 mLooper = new TestLooper(); 73 74 mWifiInjector = mock(WifiInjector.class); 75 mWifiStateMachinePrime = createWifiStateMachinePrime(); 76 } 77 78 private WifiStateMachinePrime createWifiStateMachinePrime() { 79 when(mWifiInjector.makeWificond()).thenReturn(null); 80 return new WifiStateMachinePrime(mWifiInjector, mLooper.getLooper(), mNMService); 81 } 82 83 /** 84 * Clean up after tests - explicitly set tested object to null. 85 */ 86 @After 87 public void cleanUp() throws Exception { 88 mWifiStateMachinePrime = null; 89 } 90 91 /** 92 * Helper method to enter the SoftApActiveMode for WifiStateMachinePrime. 93 * 94 * This method puts the test object into the correct state and verifies steps along the way. 95 */ 96 private void enterSoftApActiveMode() throws Exception { 97 String fromState = mWifiStateMachinePrime.getCurrentMode(); 98 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 99 when(mWificond.createApInterface()).thenReturn(mApInterface); 100 doAnswer( 101 new Answer<Object>() { 102 public SoftApManager answer(InvocationOnMock invocation) { 103 mSoftApListener = (SoftApManager.Listener) invocation.getArguments()[1]; 104 return mSoftApManager; 105 } 106 }).when(mWifiInjector).makeSoftApManager(any(INetworkManagementService.class), 107 any(SoftApManager.Listener.class), 108 any(IApInterface.class), 109 any(WifiConfiguration.class)); 110 mWifiStateMachinePrime.enterSoftAPMode(); 111 mLooper.dispatchNext(); 112 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 113 Log.e("WifiStateMachinePrimeTest", "check fromState: " + fromState); 114 if (!fromState.equals(WIFI_DISABLED_STATE_STRING)) { 115 verify(mWificond).tearDownInterfaces(); 116 } 117 mLooper.dispatchNext(); 118 assertEquals(SOFT_AP_MODE_ACTIVE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 119 verify(mSoftApManager).start(); 120 } 121 122 /** 123 * Test that when a new instance of WifiStateMachinePrime is created, any existing interfaces in 124 * the retrieved Wificond instance are cleaned up. 125 * Expectations: When the new WifiStateMachinePrime instance is created a call to 126 * Wificond.tearDownInterfaces() is made. 127 */ 128 @Test 129 public void testWificondExistsOnStartup() throws Exception { 130 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 131 WifiStateMachinePrime testWifiStateMachinePrime = 132 new WifiStateMachinePrime(mWifiInjector, mLooper.getLooper(), mNMService); 133 verify(mWificond).tearDownInterfaces(); 134 } 135 136 /** 137 * Test that WifiStateMachinePrime properly enters the SoftApModeActiveState from the 138 * WifiDisabled state. 139 */ 140 @Test 141 public void testEnterSoftApModeFromDisabled() throws Exception { 142 enterSoftApActiveMode(); 143 } 144 145 /** 146 * Test that WifiStateMachinePrime properly enters the SoftApModeActiveState from another state. 147 * Expectations: When going from one state to another, any interfaces that are still up are torn 148 * down. 149 */ 150 @Test 151 public void testEnterSoftApModeFromDifferentState() throws Exception { 152 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 153 mWifiStateMachinePrime.enterClientMode(); 154 mLooper.dispatchNext(); 155 assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 156 enterSoftApActiveMode(); 157 } 158 159 /** 160 * Test that we can disable wifi fully from the SoftApModeActiveState. 161 */ 162 @Test 163 public void testDisableWifiFromSoftApModeActiveState() throws Exception { 164 enterSoftApActiveMode(); 165 166 mWifiStateMachinePrime.disableWifi(); 167 mLooper.dispatchNext(); 168 verify(mSoftApManager).stop(); 169 verify(mWificond).tearDownInterfaces(); 170 assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 171 } 172 173 /** 174 * Test that we can disable wifi fully from the SoftApModeState. 175 */ 176 @Test 177 public void testDisableWifiFromSoftApModeState() throws Exception { 178 // Use a failure getting wificond to stay in the SoftAPModeState 179 when(mWifiInjector.makeWificond()).thenReturn(null); 180 mWifiStateMachinePrime.enterSoftAPMode(); 181 mLooper.dispatchNext(); 182 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 183 mLooper.dispatchNext(); 184 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 185 186 mWifiStateMachinePrime.disableWifi(); 187 mLooper.dispatchNext(); 188 // mWificond will be null due to this test, no call to tearDownInterfaces here. 189 assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 190 } 191 192 /** 193 * Test that we can switch from SoftApActiveMode to another mode. 194 * Expectation: When switching out of SoftApModeActiveState we stop the SoftApManager and tear 195 * down existing interfaces. 196 */ 197 @Test 198 public void testSwitchModeWhenSoftApActiveMode() throws Exception { 199 enterSoftApActiveMode(); 200 201 mWifiStateMachinePrime.enterClientMode(); 202 mLooper.dispatchNext(); 203 verify(mSoftApManager).stop(); 204 verify(mWificond).tearDownInterfaces(); 205 assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 206 } 207 208 /** 209 * Test that we do not attempt to enter SoftApModeActiveState when we cannot get a reference to 210 * wificond. 211 * Expectations: After a failed attempt to get wificond from WifiInjector, we should remain in 212 * the SoftApModeState. 213 */ 214 @Test 215 public void testWificondNullWhenSwitchingToApMode() throws Exception { 216 when(mWifiInjector.makeWificond()).thenReturn(null); 217 mWifiStateMachinePrime.enterSoftAPMode(); 218 mLooper.dispatchNext(); 219 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 220 mLooper.dispatchNext(); 221 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 222 } 223 224 /** 225 * Test that we do not attempt to enter SoftApModeActiveState when we cannot get an ApInterface 226 * from wificond. 227 * Expectations: After a failed attempt to get an ApInterface from WifiInjector, we should 228 * remain in the SoftApModeState. 229 */ 230 @Test 231 public void testAPInterfaceFailedWhenSwitchingToApMode() throws Exception { 232 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 233 when(mWificond.createApInterface()).thenReturn(null); 234 mWifiStateMachinePrime.enterSoftAPMode(); 235 mLooper.dispatchNext(); 236 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 237 mLooper.dispatchNext(); 238 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 239 } 240 241 /** 242 * Test that we do can enter the SoftApModeActiveState if we are already in the SoftApModeState. 243 * Expectations: We should exit the current SoftApModeState and re-enter before successfully 244 * entering the SoftApModeActiveState. 245 */ 246 @Test 247 public void testEnterSoftApModeActiveWhenAlreadyInSoftApMode() throws Exception { 248 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 249 when(mWificond.createApInterface()).thenReturn(null); 250 mWifiStateMachinePrime.enterSoftAPMode(); 251 mLooper.dispatchNext(); 252 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 253 mLooper.dispatchNext(); 254 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 255 256 enterSoftApActiveMode(); 257 verify(mWificond).tearDownInterfaces(); 258 } 259 260 /** 261 * Test that we return to the SoftApModeState after a failure is reported when in the 262 * SoftApModeActiveState. 263 * Expectations: We should exit the SoftApModeActiveState and stop the SoftApManager. 264 */ 265 @Test 266 public void testSoftApFailureWhenActive() throws Exception { 267 enterSoftApActiveMode(); 268 // now inject failure through the SoftApManager.Listener 269 mSoftApListener.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0); 270 mLooper.dispatchNext(); 271 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 272 verify(mSoftApManager).stop(); 273 } 274 275 /** 276 * Test that we return to the SoftApModeState after the SoftApManager is stopped in the 277 * SoftApModeActiveState. 278 * Expectations: We should exit the SoftApModeActiveState and stop the SoftApManager. 279 */ 280 @Test 281 public void testSoftApDisabledWhenActive() throws Exception { 282 enterSoftApActiveMode(); 283 // now inject failure through the SoftApManager.Listener 284 mSoftApListener.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0); 285 mLooper.dispatchNext(); 286 assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode()); 287 verify(mSoftApManager).stop(); 288 } 289 290 /** 291 * Test that we safely disable wifi if it is already disabled. 292 * Expectations: We should not interact with wificond since we should have already cleaned up 293 * everything. 294 */ 295 @Test 296 public void disableWifiWhenAlreadyOff() throws Exception { 297 verifyNoMoreInteractions(mWificond); 298 mWifiStateMachinePrime.disableWifi(); 299 } 300} 301