1/*
2 t Copyright (C) 2016 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 android.net;
18
19import static org.junit.Assert.*;
20
21import android.os.Bundle;
22import android.os.Parcel;
23import android.support.test.runner.AndroidJUnit4;
24
25import org.junit.Test;
26import org.junit.runner.RunWith;
27
28import java.util.Arrays;
29
30/** Unit tests for {@link ScoredNetwork}. */
31@RunWith(AndroidJUnit4.class)
32public class ScoredNetworkTest {
33
34    private static final int RSSI_START = -110;
35    private static final int TEST_RSSI = -50;
36    private static final byte TEST_SCORE = 5;
37    private static final RssiCurve CURVE =
38            new RssiCurve(RSSI_START, 10, new byte[] {-1, 0, 1, 2, 3, 4, TEST_SCORE, 6, 7});
39
40    private static final byte RANKING_SCORE_OFFSET = 13;
41    private static final Bundle ATTRIBUTES;
42    static {
43        ATTRIBUTES = new Bundle();
44        ATTRIBUTES.putInt(
45                ScoredNetwork.ATTRIBUTES_KEY_RANKING_SCORE_OFFSET, RANKING_SCORE_OFFSET);
46    }
47
48    private static final NetworkKey KEY
49        = new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00"));
50
51    @Test
52    public void calculateRankingOffsetShouldThrowUnsupportedOperationException() {
53        // No curve or ranking score offset set in curve
54        ScoredNetwork scoredNetwork = new ScoredNetwork(KEY, null);
55        try {
56            scoredNetwork.calculateRankingScore(TEST_RSSI);
57            fail("Should have thrown UnsupportedOperationException");
58        } catch (UnsupportedOperationException e) {
59            // expected
60        }
61    }
62
63    @Test
64    public void calculateRankingOffsetWithRssiCurveShouldReturnExpectedScore() {
65        ScoredNetwork scoredNetwork = new ScoredNetwork(KEY, CURVE);
66        assertEquals(TEST_SCORE << Byte.SIZE, scoredNetwork.calculateRankingScore(TEST_RSSI));
67    }
68
69    @Test
70    public void rankingScoresShouldDifferByRankingScoreOffset() {
71        ScoredNetwork scoredNetwork1 = new ScoredNetwork(KEY, CURVE);
72        ScoredNetwork scoredNetwork2
73            = new ScoredNetwork(KEY, CURVE, false /* meteredHint */, ATTRIBUTES);
74        int scoreDifference =
75            scoredNetwork2.calculateRankingScore(TEST_RSSI)
76            - scoredNetwork1.calculateRankingScore(TEST_RSSI);
77        assertEquals(RANKING_SCORE_OFFSET, scoreDifference);
78    }
79
80    @Test
81    public void calculateRankingScoreShouldNotResultInIntegerOverflow() {
82        Bundle attr = new Bundle();
83        attr.putInt(ScoredNetwork.ATTRIBUTES_KEY_RANKING_SCORE_OFFSET, Integer.MAX_VALUE);
84        ScoredNetwork scoredNetwork
85            = new ScoredNetwork(KEY, CURVE, false /* meteredHint */, attr);
86        assertEquals(Integer.MAX_VALUE, scoredNetwork.calculateRankingScore(TEST_RSSI));
87    }
88
89    @Test
90    public void calculateRankingScoreShouldNotResultInIntegerUnderflow() {
91        Bundle attr = new Bundle();
92        attr.putInt(ScoredNetwork.ATTRIBUTES_KEY_RANKING_SCORE_OFFSET, Integer.MIN_VALUE);
93        ScoredNetwork scoredNetwork =
94                new ScoredNetwork(KEY, CURVE, false /* meteredHint */, attr);
95        assertEquals(Integer.MIN_VALUE, scoredNetwork.calculateRankingScore(RSSI_START));
96    }
97
98    @Test
99    public void hasRankingScoreShouldReturnFalse() {
100        ScoredNetwork network = new ScoredNetwork(KEY, null /* rssiCurve */);
101        assertFalse(network.hasRankingScore());
102    }
103
104    @Test
105    public void hasRankingScoreShouldReturnTrueWhenAttributesHasRankingScoreOffset() {
106        ScoredNetwork network =
107                new ScoredNetwork(KEY, null /* rssiCurve */, false /* meteredHint */, ATTRIBUTES);
108        assertTrue(network.hasRankingScore());
109    }
110
111    @Test
112    public void hasRankingScoreShouldReturnTrueWhenCurveIsPresent() {
113        ScoredNetwork network =
114                new ScoredNetwork(KEY, CURVE , false /* meteredHint */);
115        assertTrue(network.hasRankingScore());
116    }
117
118    @Test
119    public void shouldWriteAndReadFromParcelWhenAllFieldsSet() {
120        ScoredNetwork network = new ScoredNetwork(KEY, CURVE, true /* meteredHint */, ATTRIBUTES);
121        ScoredNetwork newNetwork;
122
123        Parcel parcel = null;
124        try {
125            parcel = Parcel.obtain();
126            network.writeToParcel(parcel, 0 /* flags */);
127            parcel.setDataPosition(0);
128            newNetwork = ScoredNetwork.CREATOR.createFromParcel(parcel);
129        } finally {
130            if (parcel != null) {
131                parcel.recycle();
132            }
133        }
134        assertEquals(CURVE.start, newNetwork.rssiCurve.start);
135        assertEquals(CURVE.bucketWidth, newNetwork.rssiCurve.bucketWidth);
136        assertTrue(Arrays.equals(CURVE.rssiBuckets, newNetwork.rssiCurve.rssiBuckets));
137        assertTrue(newNetwork.meteredHint);
138        assertNotNull(newNetwork.attributes);
139        assertEquals(
140                RANKING_SCORE_OFFSET,
141                newNetwork.attributes.getInt(ScoredNetwork.ATTRIBUTES_KEY_RANKING_SCORE_OFFSET));
142    }
143
144    @Test
145    public void shouldWriteAndReadFromParcelWithoutBundle() {
146        ScoredNetwork network = new ScoredNetwork(KEY, CURVE, true /* meteredHint */);
147        ScoredNetwork newNetwork;
148
149        Parcel parcel = null;
150        try {
151            parcel = Parcel.obtain();
152            network.writeToParcel(parcel, 0 /* flags */);
153            parcel.setDataPosition(0);
154            newNetwork = ScoredNetwork.CREATOR.createFromParcel(parcel);
155        } finally {
156            if (parcel != null) {
157                parcel.recycle();
158            }
159        }
160        assertEquals(CURVE.start, newNetwork.rssiCurve.start);
161        assertEquals(CURVE.bucketWidth, newNetwork.rssiCurve.bucketWidth);
162        assertTrue(Arrays.equals(CURVE.rssiBuckets, newNetwork.rssiCurve.rssiBuckets));
163        assertTrue(newNetwork.meteredHint);
164        assertNull(newNetwork.attributes);
165    }
166
167    @Test
168    public void calculateBadgeShouldReturnNoBadgeWhenNoAttributesBundle() {
169        ScoredNetwork network = new ScoredNetwork(KEY, CURVE);
170        assertEquals(NetworkBadging.BADGING_NONE, network.calculateBadge(TEST_RSSI));
171    }
172
173    @Test
174    public void calculateBadgeShouldReturnNoBadgeWhenNoBadgingCurveInBundle() {
175        ScoredNetwork network = new ScoredNetwork(KEY, CURVE, false /* meteredHint */, ATTRIBUTES);
176        assertEquals(NetworkBadging.BADGING_NONE, network.calculateBadge(TEST_RSSI));
177    }
178
179    @Test
180    public void calculateBadgeShouldReturn4kBadge() {
181        ScoredNetwork network =
182            buildScoredNetworkWithGivenBadgeForTestRssi(NetworkBadging.BADGING_4K);
183        assertEquals(NetworkBadging.BADGING_4K, network.calculateBadge(TEST_RSSI));
184    }
185
186    @Test
187    public void calculateBadgeShouldReturnHdBadge() {
188        ScoredNetwork network =
189            buildScoredNetworkWithGivenBadgeForTestRssi(NetworkBadging.BADGING_HD);
190        assertEquals(NetworkBadging.BADGING_HD, network.calculateBadge(TEST_RSSI));
191    }
192
193    @Test
194    public void calculateBadgeShouldReturnSdBadge() {
195        ScoredNetwork network =
196            buildScoredNetworkWithGivenBadgeForTestRssi(NetworkBadging.BADGING_SD);
197        assertEquals(NetworkBadging.BADGING_SD, network.calculateBadge(TEST_RSSI));
198    }
199
200    @Test
201    public void calculateBadgeShouldReturnNoBadge() {
202        ScoredNetwork network =
203            buildScoredNetworkWithGivenBadgeForTestRssi(NetworkBadging.BADGING_NONE);
204        assertEquals(NetworkBadging.BADGING_NONE, network.calculateBadge(TEST_RSSI));
205    }
206
207    private ScoredNetwork buildScoredNetworkWithGivenBadgeForTestRssi(int badge) {
208        RssiCurve badgingCurve =
209               new RssiCurve(RSSI_START, 10, new byte[] {0, 0, 0, 0, 0, 0, (byte) badge});
210        Bundle attr = new Bundle();
211        attr.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgingCurve);
212        return new ScoredNetwork(KEY, CURVE, false /* meteredHint */, attr);
213    }
214}
215