blob: 3db50c5f28d35bd311fd8a88caa04194512d63fb [file] [log] [blame]
/*
* Copyright 2019 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.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.WifiCandidates.Candidate;
import com.android.server.wifi.WifiCandidates.CandidateScorer;
import com.android.server.wifi.WifiCandidates.ScoredCandidate;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.List;
/**
* Unit tests for implementations of
* {@link com.android.server.wifi.WifiCandidates.CandidateScorer}.
*
* Runs tests that any reasonable CandidateScorer should pass.
* Individual scorers may have additional tests of their own.
*/
@SmallTest
@RunWith(Parameterized.class)
public class CandidateScorerTest {
@Parameters(name = "{index}: {0}")
public static List<Object[]> listOfObjectArraysBecauseJUnitMadeUs() {
ScoringParams sp;
ArrayList<Object[]> ans = new ArrayList<>();
sp = new ScoringParams();
ans.add(new Object[]{
"Compatibility Scorer",
CompatibilityScorer.COMPATIBILITY_SCORER_DEFAULT_EXPID,
new CompatibilityScorer(sp),
sp});
sp = new ScoringParams();
ans.add(new Object[]{
"Score Card Based Scorer",
ScoreCardBasedScorer.SCORE_CARD_BASED_SCORER_DEFAULT_EXPID,
new ScoreCardBasedScorer(sp),
sp});
sp = new ScoringParams();
ans.add(new Object[]{
"Bubble Function Scorer",
BubbleFunScorer.BUBBLE_FUN_SCORER_DEFAULT_EXPID,
new BubbleFunScorer(sp),
sp});
return ans;
}
@Parameter(0)
public String mTitleForUseInGeneratedParameterNames;
@Parameter(1)
public int mExpectedExpId;
@Parameter(2)
public CandidateScorer mCandidateScorer;
@Parameter(3)
public ScoringParams mScoringParams;
private static final double TOL = 1e-6; // for assertEquals(double, double, tolerance)
private ConcreteCandidate mCandidate1;
private ConcreteCandidate mCandidate2;
/**
* Sets up for unit test
*/
@Before
public void setUp() throws Exception {
mScoringParams.update("");
mCandidate1 = new ConcreteCandidate().setEvaluatorId(0).setEvaluatorScore(66)
.setScanRssi(-50).setFrequency(5180);
mCandidate2 = new ConcreteCandidate().setEvaluatorId(0).setEvaluatorScore(99)
.setScanRssi(-50).setFrequency(5180);
}
/**
* Test that the expected expid is computed with the built-in defaults.
*/
@Test
public void testExpid() throws Exception {
String identifier = mCandidateScorer.getIdentifier();
assertEquals(identifier,
mExpectedExpId,
WifiNetworkSelector.experimentIdFromIdentifier(identifier));
}
/**
* Utility function to build and evaluate a candidate.
*/
private double evaluate(ConcreteCandidate candidate) {
ArrayList<Candidate> candidates = new ArrayList<>(1);
candidates.add(candidate);
ScoredCandidate choice = mCandidateScorer.scoreCandidates(candidates);
return Math.max(-999999999.0, choice.value);
}
/**
* Evaluating equal inputs should give the same result.
*/
@Test
public void testEqualInputsShouldGiveTheSameResult() throws Exception {
assertEquals(evaluate(mCandidate1), evaluate(mCandidate2), TOL);
}
/**
* Prefer 5 GHz over 2.4 GHz in non-fringe conditions, similar rssi.
*/
@Test
public void testPrefer5GhzOver2GhzInNonFringeConditionsSimilarRssi() throws Exception {
assertThat(evaluate(mCandidate1.setFrequency(5180).setScanRssi(-44)),
greaterThan(evaluate(mCandidate2.setFrequency(2024).setScanRssi(-44))));
}
/**
* Prefer higher rssi.
*/
@Test
public void testPreferHigherRssi() throws Exception {
assertThat(evaluate(mCandidate1.setScanRssi(-63)),
greaterThan(evaluate(mCandidate2.setScanRssi(-64))));
}
/**
* Prefer a secure network over an open one.
*/
@Test
public void testPreferASecureNetworkOverAnOpenOne() throws Exception {
assertThat(evaluate(mCandidate1),
greaterThan(evaluate(mCandidate2.setOpenNetwork(true))));
}
/**
* Prefer the current network, even if rssi difference is significant.
*/
@Test
public void testPreferTheCurrentNetworkEvenIfRssiDifferenceIsSignificant() throws Exception {
assertThat(evaluate(mCandidate1.setScanRssi(-77).setCurrentNetwork(true)),
greaterThan(evaluate(mCandidate2.setScanRssi(-68))));
}
/**
* Above saturation, don't switch from current even with a large rssi difference.
*/
@Test
public void testAboveSaturationDoNotSwitchAwayEvenWithALargeRssiDifference() throws Exception {
int goodRssi = mScoringParams.getGoodRssi(mCandidate1.getFrequency());
int unbelievablyGoodRssi = -1;
assertThat(evaluate(mCandidate1.setScanRssi(goodRssi).setCurrentNetwork(true)),
greaterThan(evaluate(mCandidate2.setScanRssi(unbelievablyGoodRssi))));
}
}