1/* 2 * Copyright (C) 2017 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.mockito.Mockito.*; 20import static org.mockito.MockitoAnnotations.*; 21 22import android.test.suitebuilder.annotation.SmallTest; 23 24import org.junit.Before; 25import org.junit.Test; 26import org.mockito.Mock; 27 28/** 29 * Unit tests for {@link com.android.server.wifi.SelfRecovery}. 30 */ 31@SmallTest 32public class SelfRecoveryTest { 33 SelfRecovery mSelfRecovery; 34 @Mock WifiController mWifiController; 35 @Mock Clock mClock; 36 37 @Before 38 public void setUp() throws Exception { 39 initMocks(this); 40 mSelfRecovery = new SelfRecovery(mWifiController, mClock); 41 } 42 43 /** 44 * Verifies that invocations of {@link SelfRecovery#trigger(int)} with valid reasons will send 45 * the restart message to {@link WifiController}. 46 */ 47 @Test 48 public void testValidTriggerReasonsSendMessageToWifiController() { 49 mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 50 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 51 reset(mWifiController); 52 53 when(mClock.getElapsedSinceBootMillis()) 54 .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); 55 mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 56 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 57 reset(mWifiController); 58 59 when(mClock.getElapsedSinceBootMillis()) 60 .thenReturn(2 * (SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1)); 61 mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 62 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 63 reset(mWifiController); 64 65 } 66 67 /** 68 * Verifies that invocations of {@link SelfRecovery#trigger(int)} with invalid reasons will not 69 * send the restart message to {@link WifiController}. 70 */ 71 @Test 72 public void testInvalidTriggerReasonsDoesNotSendMessageToWifiController() { 73 mSelfRecovery.trigger(-1); 74 verify(mWifiController, never()).sendMessage(anyInt()); 75 76 mSelfRecovery.trigger(8); 77 verify(mWifiController, never()).sendMessage(anyInt()); 78 } 79 80 /** 81 * Verifies that invocations of {@link SelfRecovery#trigger(int)} for REASON_HAL_CRASH & 82 * REASON_WIFICOND_CRASH are limited to {@link SelfRecovery#MAX_RESTARTS_IN_TIME_WINDOW} in a 83 * {@link SelfRecovery#MAX_RESTARTS_TIME_WINDOW_MILLIS} millisecond time window. 84 */ 85 @Test 86 public void testTimeWindowLimiting_typicalUse() { 87 when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); 88 // Fill up the SelfRecovery's restart time window buffer, ensure all the restart triggers 89 // aren't ignored 90 for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW / 2; i++) { 91 mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 92 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 93 reset(mWifiController); 94 95 mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 96 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 97 reset(mWifiController); 98 } 99 if ((SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW % 2) == 1) { 100 mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 101 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 102 reset(mWifiController); 103 } 104 105 // Verify that further attempts to trigger restarts for are ignored 106 mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 107 verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 108 reset(mWifiController); 109 110 mSelfRecovery.trigger(SelfRecovery.REASON_WIFICOND_CRASH); 111 verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 112 reset(mWifiController); 113 114 // Verify L.R.Watchdog can still restart things (It has its own complex limiter) 115 mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 116 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 117 reset(mWifiController); 118 119 // now TRAVEL FORWARDS IN TIME and ensure that more restarts can occur 120 when(mClock.getElapsedSinceBootMillis()) 121 .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); 122 mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 123 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 124 reset(mWifiController); 125 126 when(mClock.getElapsedSinceBootMillis()) 127 .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); 128 mSelfRecovery.trigger(SelfRecovery.REASON_HAL_CRASH); 129 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 130 reset(mWifiController); 131 } 132 133 /** 134 * Verifies that invocations of {@link SelfRecovery#trigger(int)} for 135 * REASON_LAST_RESORT_WATCHDOG are NOT limited to 136 * {@link SelfRecovery#MAX_RESTARTS_IN_TIME_WINDOW} in a 137 * {@link SelfRecovery#MAX_RESTARTS_TIME_WINDOW_MILLIS} millisecond time window. 138 */ 139 @Test 140 public void testTimeWindowLimiting_lastResortWatchdog_noEffect() { 141 for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW * 2; i++) { 142 // Verify L.R.Watchdog can still restart things (It has it's own complex limiter) 143 mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); 144 verify(mWifiController).sendMessage(eq(WifiController.CMD_RESTART_WIFI)); 145 reset(mWifiController); 146 } 147 } 148} 149