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.junit.Assert.assertTrue; 20import static org.mockito.Mockito.doReturn; 21import static org.mockito.Mockito.when; 22 23import android.content.Context; 24import android.content.res.Resources; 25import android.net.wifi.WifiInfo; 26 27import com.android.internal.R; 28 29import org.junit.Before; 30import org.junit.Test; 31import org.mockito.Mock; 32import org.mockito.MockitoAnnotations; 33import org.mockito.Spy; 34 35/** 36 * Unit tests for {@link com.android.server.wifi.VelocityBasedConnectedScore}. 37 */ 38public class VelocityBasedConnectedScoreTest { 39 40 41 class FakeClock extends Clock { 42 long mWallClockMillis = 1500000000000L; 43 int mStepMillis = 3001; 44 45 @Override 46 public long getWallClockMillis() { 47 mWallClockMillis += mStepMillis; 48 return mWallClockMillis; 49 } 50 } 51 52 FakeClock mClock; 53 VelocityBasedConnectedScore mVelocityBasedConnectedScore; 54 ScanDetailCache mScanDetailCache; 55 WifiInfo mWifiInfo; 56 int mRssiExitThreshold2GHz; 57 int mRssiExitThreshold5GHz; 58 @Mock Context mContext; 59 @Spy private MockResources mResources = new MockResources(); 60 61 private int setupIntegerResource(int resourceName, int value) { 62 doReturn(value).when(mResources).getInteger(resourceName); 63 return value; 64 } 65 66 /** 67 * Sets up resource values for testing 68 * 69 * See frameworks/base/core/res/res/values/config.xml 70 */ 71 private void setUpResources(Resources resources) { 72 mRssiExitThreshold2GHz = setupIntegerResource( 73 R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz, -83); 74 mRssiExitThreshold5GHz = setupIntegerResource( 75 R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz, -80); 76 } 77 78 /** 79 * Sets up for unit test 80 */ 81 @Before 82 public void setUp() throws Exception { 83 MockitoAnnotations.initMocks(this); 84 setUpResources(mResources); 85 mWifiInfo = new WifiInfo(); 86 mWifiInfo.setFrequency(2412); 87 when(mContext.getResources()).thenReturn(mResources); 88 mClock = new FakeClock(); 89 mVelocityBasedConnectedScore = new VelocityBasedConnectedScore( 90 new ScoringParams(mContext), mClock); 91 } 92 93 /** 94 * Generate a score with no updates 95 * 96 * Expect no crash, passing score 97 */ 98 @Test 99 public void noCrashWhenNoData() throws Exception { 100 int score = mVelocityBasedConnectedScore.generateScore(); 101 assertTrue(score > ConnectedScore.WIFI_TRANSITION_SCORE); 102 } 103 104 /** 105 * 106 * Low RSSI, but some data is moving and error rate is low. 107 * 108 * Expect a score above threshold. 109 */ 110 @Test 111 public void allowLowRssiIfErrorRateIsLowAndSomeDataIsMoving() throws Exception { 112 mWifiInfo.setRssi(mRssiExitThreshold2GHz - 2); 113 mWifiInfo.setLinkSpeed(6); // Mbps 114 mWifiInfo.txSuccessRate = 2.1; // proportional to pps 115 mWifiInfo.txBadRate = .5; 116 mWifiInfo.rxSuccessRate = 2.1; 117 for (int i = 0; i < 10; i++) { 118 mVelocityBasedConnectedScore.updateUsingWifiInfo(mWifiInfo, 119 mClock.getWallClockMillis()); 120 } 121 int score = mVelocityBasedConnectedScore.generateScore(); 122 assertTrue(score > ConnectedScore.WIFI_TRANSITION_SCORE); 123 // If we reset, should be below threshold after the first input 124 mVelocityBasedConnectedScore.reset(); 125 mVelocityBasedConnectedScore.updateUsingWifiInfo(mWifiInfo, mClock.getWallClockMillis()); 126 score = mVelocityBasedConnectedScore.generateScore(); 127 assertTrue(score < ConnectedScore.WIFI_TRANSITION_SCORE); 128 } 129 130 /** 131 * 132 * Low RSSI, and almost no data is moving. 133 * 134 * Expect a score below threshold. 135 */ 136 @Test 137 public void disallowLowRssiIfDataIsNotMoving() throws Exception { 138 mWifiInfo.setRssi(mRssiExitThreshold2GHz - 1); 139 mWifiInfo.setLinkSpeed(6); // Mbps 140 mWifiInfo.txSuccessRate = .1; // proportional to pps 141 mWifiInfo.txBadRate = 0; 142 mWifiInfo.rxSuccessRate = .1; 143 for (int i = 0; i < 10; i++) { 144 mVelocityBasedConnectedScore.updateUsingWifiInfo(mWifiInfo, 145 mClock.getWallClockMillis()); 146 } 147 int score = mVelocityBasedConnectedScore.generateScore(); 148 assertTrue(score < ConnectedScore.WIFI_TRANSITION_SCORE); 149 } 150} 151