196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius/* 296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * Copyright (C) 2017 The Android Open Source Project 396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * 496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * Licensed under the Apache License, Version 2.0 (the "License"); 596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * you may not use this file except in compliance with the License. 696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * You may obtain a copy of the License at 796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * 896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * http://www.apache.org/licenses/LICENSE-2.0 996a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * 1096a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * Unless required by applicable law or agreed to in writing, software 1196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * distributed under the License is distributed on an "AS IS" BASIS, 1296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * See the License for the specific language governing permissions and 1496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * limitations under the License. 1596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius */ 1696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 1796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piuspackage com.android.server.wifi; 1896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 1996a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piusimport static org.mockito.Mockito.*; 2096a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piusimport static org.mockito.MockitoAnnotations.*; 2196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 2296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piusimport android.test.suitebuilder.annotation.SmallTest; 2396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 2496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piusimport org.junit.Before; 2596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piusimport org.junit.Test; 2696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piusimport org.mockito.Mock; 2796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 2896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius/** 2996a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * Unit tests for {@link com.android.server.wifi.SelfRecovery}. 3096a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius */ 3196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius@SmallTest 3296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Piuspublic class SelfRecoveryTest { 3396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius SelfRecovery mSelfRecovery; 3496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius @Mock WifiController mWifiController; 35e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne @Mock Clock mClock; 3696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 3796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius @Before 3896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius public void setUp() throws Exception { 3996a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius initMocks(this); 40e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery = new SelfRecovery(mWifiController, mClock); 4196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius } 4296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 4396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius /** 4496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * Verifies that invocations of {@link SelfRecovery#trigger(int)} with valid reasons will send 4596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * the restart message to {@link WifiController}. 4696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius */ 4796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius @Test 4896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius public void testValidTriggerReasonsSendMessageToWifiController() { 4996a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 5096a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 5196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius reset(mWifiController); 5296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 53e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne when(mClock.getElapsedSinceBootMillis()) 54e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); 5596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 5696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 5796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius reset(mWifiController); 5896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 59e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne when(mClock.getElapsedSinceBootMillis()) 60e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne .thenReturn(2 * (SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1)); 6196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 6296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 6396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius reset(mWifiController); 6496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 6596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius } 6696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 6796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius /** 6896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * Verifies that invocations of {@link SelfRecovery#trigger(int)} with invalid reasons will not 6996a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius * send the restart message to {@link WifiController}. 7096a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius */ 7196a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius @Test 7296a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius public void testInvalidTriggerReasonsDoesNotSendMessageToWifiController() { 7396a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius mSelfRecovery.trigger(-1); 7496a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius verify(mWifiController, never()).sendMessage(anyInt()); 7596a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius 7696a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius mSelfRecovery.trigger(8); 7796a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius verify(mWifiController, never()).sendMessage(anyInt()); 7896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius } 79e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 80e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne /** 81e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * Verifies that invocations of {@link SelfRecovery#trigger(int)} for REASON_HAL_CRASH & 82e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * REASON_WIFICOND_CRASH are limited to {@link SelfRecovery#MAX_RESTARTS_IN_TIME_WINDOW} in a 83e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * {@link SelfRecovery#MAX_RESTARTS_TIME_WINDOW_MILLIS} millisecond time window. 84e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne */ 85e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne @Test 86e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne public void testTimeWindowLimiting_typicalUse() { 87e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); 88e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne // Fill up the SelfRecovery's restart time window buffer, ensure all the restart triggers 89e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne // aren't ignored 90e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW / 2; i++) { 91e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 92e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 93e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 94e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 95e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 96e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 97e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 98e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne } 99e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne if ((SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW % 2) == 1) { 100e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 101e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 102e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 103e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne } 104e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 105e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne // Verify that further attempts to trigger restarts for are ignored 106e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 107e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 108e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 109e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 110e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 111e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 112e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 113e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 114e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne // Verify L.R.Watchdog can still restart things (It has its own complex limiter) 115e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 116e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 117e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 118e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 119e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne // now TRAVEL FORWARDS IN TIME and ensure that more restarts can occur 120e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne when(mClock.getElapsedSinceBootMillis()) 121e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); 122e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 123e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 124e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 125e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 126e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne when(mClock.getElapsedSinceBootMillis()) 127e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); 128e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 129e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 130e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 131e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne } 132e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne 133e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne /** 134e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * Verifies that invocations of {@link SelfRecovery#trigger(int)} for 135e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * REASON_LAST_RESORT_WATCHDOG are NOT limited to 136e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * {@link SelfRecovery#MAX_RESTARTS_IN_TIME_WINDOW} in a 137e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne * {@link SelfRecovery#MAX_RESTARTS_TIME_WINDOW_MILLIS} millisecond time window. 138e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne */ 139e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne @Test 140e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne public void testTimeWindowLimiting_lastResortWatchdog_noEffect() { 141e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW * 2; i++) { 142e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne // Verify L.R.Watchdog can still restart things (It has it's own complex limiter) 143e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 144e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 145e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne reset(mWifiController); 146e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne } 147e8cf3b95869b71ff4719b037f79d74b74d2a2fc3Glen Kuhne } 14896a9dbeb3a622e44c13ff7be8decf36d06ff7dbbRoshan Pius} 149