blob: a5f6852f85f78962ba9492a72e614e417f256741 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Unit tests for {@link com.android.server.wifi.WifiDataStall}.
*/
@SmallTest
public class WifiDataStallTest {
@Mock Context mContext;
@Mock FrameworkFacade mFacade;
@Mock WifiMetrics mWifiMetrics;
WifiDataStall mWifiDataStall;
private final WifiLinkLayerStats mOldLlStats = new WifiLinkLayerStats();
private final WifiLinkLayerStats mNewLlStats = new WifiLinkLayerStats();
/**
* Sets up for unit test
*/
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_DATA_STALL_MIN_TX_BAD,
WifiDataStall.MIN_TX_BAD_DEFAULT))
.thenReturn(WifiDataStall.MIN_TX_BAD_DEFAULT);
when(mFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX,
WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT))
.thenReturn(WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT);
mWifiDataStall = new WifiDataStall(mContext, mFacade, mWifiMetrics);
mOldLlStats.txmpdu_be = 1000;
mOldLlStats.retries_be = 2000;
mOldLlStats.lostmpdu_be = 3000;
mOldLlStats.rxmpdu_be = 4000;
mOldLlStats.timeStampInMs = 10000;
mNewLlStats.txmpdu_be = mOldLlStats.txmpdu_be;
mNewLlStats.retries_be = mOldLlStats.retries_be;
mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be;
mNewLlStats.rxmpdu_be = mOldLlStats.rxmpdu_be;
mNewLlStats.timeStampInMs = mOldLlStats.timeStampInMs
+ WifiDataStall.MAX_MS_DELTA_FOR_DATA_STALL - 1;
}
/**
* Verify that LinkLayerStats for WifiIsUnusableEvent is correctly updated
*/
private void verifyUpdateWifiIsUnusableLinkLayerStats() {
verify(mWifiMetrics).updateWifiIsUnusableLinkLayerStats(
mNewLlStats.txmpdu_be - mOldLlStats.txmpdu_be,
mNewLlStats.retries_be - mOldLlStats.retries_be,
mNewLlStats.lostmpdu_be - mOldLlStats.lostmpdu_be,
mNewLlStats.rxmpdu_be - mOldLlStats.rxmpdu_be,
mNewLlStats.timeStampInMs - mOldLlStats.timeStampInMs);
}
/**
* Verify there is data stall from tx failures
*/
@Test
public void verifyDataStallTxFailure() throws Exception {
mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be + WifiDataStall.MIN_TX_BAD_DEFAULT;
assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics).logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX);
}
/**
* Verify there is data stall from rx failures
*/
@Test
public void verifyDataStallRxFailure() throws Exception {
mNewLlStats.txmpdu_be =
mOldLlStats.txmpdu_be + WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT;
assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics).logWifiIsUnusableEvent(
WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX);
}
/**
* Verify there is data stall from both tx and rx failures
*/
@Test
public void verifyDataStallBothTxRxFailure() throws Exception {
mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be + WifiDataStall.MIN_TX_BAD_DEFAULT;
mNewLlStats.txmpdu_be =
mOldLlStats.txmpdu_be + WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT;
assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics).logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH);
}
/**
* Verify that we can change the minimum number of tx failures
* to trigger data stall from settings
*/
@Test
public void verifyDataStallTxFailureSettingsChange() throws Exception {
when(mFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_DATA_STALL_MIN_TX_BAD,
WifiDataStall.MIN_TX_BAD_DEFAULT))
.thenReturn(WifiDataStall.MIN_TX_BAD_DEFAULT + 1);
mWifiDataStall.loadSettings();
verify(mWifiMetrics).setWifiDataStallMinTxBad(WifiDataStall.MIN_TX_BAD_DEFAULT + 1);
verify(mWifiMetrics, times(2)).setWifiDataStallMinRxWithoutTx(
WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT);
mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be + WifiDataStall.MIN_TX_BAD_DEFAULT;
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics, never()).logWifiIsUnusableEvent(anyInt());
}
/**
* Verify that we can change the minimum number of tx successes when rx success is 0
* to trigger data stall from settings
*/
@Test
public void verifyDataStallRxFailureSettingsChange() throws Exception {
when(mFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX,
WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT))
.thenReturn(WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT + 1);
mWifiDataStall.loadSettings();
verify(mWifiMetrics, times(2)).setWifiDataStallMinTxBad(WifiDataStall.MIN_TX_BAD_DEFAULT);
verify(mWifiMetrics).setWifiDataStallMinRxWithoutTx(
WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT + 1);
mNewLlStats.txmpdu_be =
mOldLlStats.txmpdu_be + WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT;
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics, never()).logWifiIsUnusableEvent(anyInt());
}
/**
* Verify there is no data stall when there are no new tx/rx failures
*/
@Test
public void verifyNoDataStallWhenNoFail() throws Exception {
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verify(mWifiMetrics, never()).resetWifiIsUnusableLinkLayerStats();
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics, never()).logWifiIsUnusableEvent(anyInt());
}
/**
* Verify there is no data stall when the time difference between
* two WifiLinkLayerStats is too big.
*/
@Test
public void verifyNoDataStallBigTimeGap() throws Exception {
mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be + WifiDataStall.MIN_TX_BAD_DEFAULT;
mNewLlStats.timeStampInMs = mOldLlStats.timeStampInMs
+ WifiDataStall.MAX_MS_DELTA_FOR_DATA_STALL + 1;
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verifyUpdateWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics, never()).logWifiIsUnusableEvent(anyInt());
}
/**
* Verify that metrics get reset when there is a reset in WifiLinkLayerStats
*/
@Test
public void verifyReset() throws Exception {
mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be - 1;
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats));
verify(mWifiMetrics).resetWifiIsUnusableLinkLayerStats();
verify(mWifiMetrics, never()).updateWifiIsUnusableLinkLayerStats(
anyLong(), anyLong(), anyLong(), anyLong(), anyLong());
verify(mWifiMetrics, never()).logWifiIsUnusableEvent(anyInt());
}
}