• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
17 package android.net.wifi;
18 
19 import static android.net.wifi.QosCharacteristics.DELIVERY_RATIO_95;
20 import static android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_9999;
21 
22 import static junit.framework.Assert.assertFalse;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotEquals;
26 import static org.junit.Assert.assertThrows;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assume.assumeTrue;
29 
30 import android.os.Parcel;
31 
32 import com.android.modules.utils.build.SdkLevel;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 
37 public class QosCharacteristicsTest {
38     private static final int TEST_MIN_SERVICE_INTERVAL_MICROS = 2000;
39     private static final int TEST_MAX_SERVICE_INTERVAL_MICROS = 5000;
40     private static final int TEST_MIN_DATA_RATE_KBPS = 500;
41     private static final int TEST_BURST_SIZE_OCTETS = 2;
42     private static final int TEST_DELAY_BOUND_MICROS = 200;
43     private static final int TEST_MAX_MSDU_SIZE_OCTETS = 4;
44     private static final int TEST_SERVICE_START_TIME_MICROS = 250;
45     private static final int TEST_SERVICE_START_TIME_LINK_ID = 0x5;
46     private static final int TEST_MEAN_DATA_RATE_KBPS = 1500;
47     private static final int TEST_MSDU_LIFETIME_MILLIS = 400;
48     private static final int TEST_DELIVERY_RATIO = QosCharacteristics.DELIVERY_RATIO_99;
49     private static final int TEST_COUNT_EXPONENT = 5;
50 
51     @Before
setUp()52     public void setUp() {
53         assumeTrue(SdkLevel.isAtLeastV());
54     }
55 
56     /**
57      * Get a Builder with the mandatory fields set to the default test values.
58      */
getDefaultBuilder()59     private static QosCharacteristics.Builder getDefaultBuilder() {
60         return new QosCharacteristics.Builder(
61                 TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
62                 TEST_MIN_DATA_RATE_KBPS, TEST_DELAY_BOUND_MICROS);
63     }
64 
65     /**
66      * Get a QosCharacteristics with all fields set to the default test values.
67      */
getDefaultQosCharacteristics()68     private static QosCharacteristics getDefaultQosCharacteristics() {
69         return getDefaultBuilder()
70                 .setMaxMsduSizeOctets(TEST_MAX_MSDU_SIZE_OCTETS)
71                 .setServiceStartTimeInfo(
72                         TEST_SERVICE_START_TIME_MICROS, TEST_SERVICE_START_TIME_LINK_ID)
73                 .setMeanDataRateKbps(TEST_MEAN_DATA_RATE_KBPS)
74                 .setBurstSizeOctets(TEST_BURST_SIZE_OCTETS)
75                 .setMsduLifetimeMillis(TEST_MSDU_LIFETIME_MILLIS)
76                 .setMsduDeliveryInfo(TEST_DELIVERY_RATIO, TEST_COUNT_EXPONENT)
77                 .build();
78     }
79 
80     /**
81      * Verify that all fields in the QosCharacteristics object contain the default test values.
82      */
validateDefaultFields(QosCharacteristics qosCharacteristics)83     private static void validateDefaultFields(QosCharacteristics qosCharacteristics) {
84         assertEquals(TEST_MIN_SERVICE_INTERVAL_MICROS,
85                 qosCharacteristics.getMinServiceIntervalMicros());
86         assertEquals(TEST_MAX_SERVICE_INTERVAL_MICROS,
87                 qosCharacteristics.getMaxServiceIntervalMicros());
88         assertEquals(TEST_MIN_DATA_RATE_KBPS, qosCharacteristics.getMinDataRateKbps());
89         assertEquals(TEST_DELAY_BOUND_MICROS, qosCharacteristics.getDelayBoundMicros());
90 
91         assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MAX_MSDU_SIZE));
92         assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.SERVICE_START_TIME));
93         assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MEAN_DATA_RATE));
94         assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.BURST_SIZE));
95         assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MSDU_LIFETIME));
96         assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MSDU_DELIVERY_INFO));
97 
98         assertEquals(TEST_MAX_MSDU_SIZE_OCTETS, qosCharacteristics.getMaxMsduSizeOctets());
99         assertEquals(TEST_SERVICE_START_TIME_MICROS,
100                 qosCharacteristics.getServiceStartTimeMicros());
101         assertEquals(TEST_SERVICE_START_TIME_LINK_ID,
102                 qosCharacteristics.getServiceStartTimeLinkId());
103         assertEquals(TEST_MEAN_DATA_RATE_KBPS, qosCharacteristics.getMeanDataRateKbps());
104         assertEquals(TEST_BURST_SIZE_OCTETS, qosCharacteristics.getBurstSizeOctets());
105         assertEquals(TEST_MSDU_LIFETIME_MILLIS, qosCharacteristics.getMsduLifetimeMillis());
106         assertEquals(TEST_DELIVERY_RATIO, qosCharacteristics.getDeliveryRatio());
107         assertEquals(TEST_COUNT_EXPONENT, qosCharacteristics.getCountExponent());
108     }
109 
110     /**
111      * Test that the builder works correctly when provided valid values.
112      */
113     @Test
testBuilderValid()114     public void testBuilderValid() {
115         QosCharacteristics qosCharacteristics = getDefaultQosCharacteristics();
116         validateDefaultFields(qosCharacteristics);
117     }
118 
119     /**
120      * Test that an exception is thrown if any of the mandatory fields are assigned an
121      * invalid value.
122      */
123     @Test
testMandatoryFieldsInvalid()124     public void testMandatoryFieldsInvalid() {
125         // All mandatory fields must be positive.
126         assertThrows(IllegalArgumentException.class, () ->
127                 new QosCharacteristics.Builder(
128                         0, TEST_MAX_SERVICE_INTERVAL_MICROS,
129                         TEST_MIN_DATA_RATE_KBPS, TEST_DELAY_BOUND_MICROS).build());
130         assertThrows(IllegalArgumentException.class, () ->
131                 new QosCharacteristics.Builder(
132                         TEST_MIN_SERVICE_INTERVAL_MICROS, 0,
133                         TEST_MIN_DATA_RATE_KBPS, TEST_DELAY_BOUND_MICROS).build());
134         assertThrows(IllegalArgumentException.class, () ->
135                 new QosCharacteristics.Builder(
136                         TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
137                         0, TEST_DELAY_BOUND_MICROS).build());
138         assertThrows(IllegalArgumentException.class, () ->
139                 new QosCharacteristics.Builder(
140                         TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
141                         TEST_MIN_DATA_RATE_KBPS, 0).build());
142 
143         // Min service interval must be less than or equal to the max service interval.
144         assertThrows(IllegalArgumentException.class, () ->
145                 new QosCharacteristics.Builder(
146                         5000 /* minServiceInterval */, 3000 /* maxServiceInterval */,
147                         TEST_MIN_DATA_RATE_KBPS, 0).build());
148     }
149 
150     /**
151      * Test that an exception is thrown if any optional values that expect a positive value
152      * are assigned a zero value.
153      */
154     @Test
testOptionalFieldsInvalid_zeroValue()155     public void testOptionalFieldsInvalid_zeroValue() {
156         assertThrows(IllegalArgumentException.class, () ->
157                 getDefaultBuilder().setMaxMsduSizeOctets(0).build());
158         assertThrows(IllegalArgumentException.class, () ->
159                 getDefaultBuilder().setMeanDataRateKbps(0).build());
160         assertThrows(IllegalArgumentException.class, () ->
161                 getDefaultBuilder().setBurstSizeOctets(0).build());
162         assertThrows(IllegalArgumentException.class, () ->
163                 getDefaultBuilder().setMsduLifetimeMillis(0).build());
164     }
165 
166     /**
167      * Test that an exception is thrown if any optional values that expect a <32-bit value are
168      * assigned a value that exceeds the expected bit size.
169      */
170     @Test
testOptionalFieldsInvalid_exceedUpperBound()171     public void testOptionalFieldsInvalid_exceedUpperBound() {
172         // Expects 16-bit value
173         assertThrows(IllegalArgumentException.class, () ->
174                 getDefaultBuilder().setMaxMsduSizeOctets(0x1FFFF).build());
175 
176         // Expects 16-bit value
177         assertThrows(IllegalArgumentException.class, () ->
178                 getDefaultBuilder().setMsduLifetimeMillis(0x1FFFF).build());
179 
180         // Expects 4-bit link ID
181         assertThrows(IllegalArgumentException.class, () ->
182                 getDefaultBuilder()
183                         .setServiceStartTimeInfo(TEST_SERVICE_START_TIME_MICROS, 0x1F).build());
184     }
185 
186     /**
187      * Test that an exception is thrown if any additional constraints on the optional fields
188      * are broken.
189      */
190     @Test
testOptionalFieldsInvalid_additionalConstraints()191     public void testOptionalFieldsInvalid_additionalConstraints() {
192         // MSDU lifetime should be >= the delay bound
193         int delayBoundUs = 30_000;  // 30 ms
194         int msduLifetimeMs = 20;
195         assertThrows(IllegalArgumentException.class, () ->
196                 new QosCharacteristics.Builder(
197                         TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
198                         TEST_MIN_DATA_RATE_KBPS, delayBoundUs)
199                         .setMsduLifetimeMillis(msduLifetimeMs)
200                         .build());
201 
202         // MSDU delivery ratio should be a valid enum
203         assertThrows(IllegalArgumentException.class, () ->
204                 getDefaultBuilder()
205                         .setMsduDeliveryInfo(DELIVERY_RATIO_95 - 1, TEST_COUNT_EXPONENT)
206                         .build());
207         assertThrows(IllegalArgumentException.class, () ->
208                 getDefaultBuilder()
209                         .setMsduDeliveryInfo(DELIVERY_RATIO_99_9999 + 1, TEST_COUNT_EXPONENT)
210                         .build());
211 
212         // MSDU count exponent should be between 0 and 15 (inclusive)
213         assertThrows(IllegalArgumentException.class, () ->
214                 getDefaultBuilder()
215                         .setMsduDeliveryInfo(TEST_DELIVERY_RATIO, -1)
216                         .build());
217         assertThrows(IllegalArgumentException.class, () ->
218                 getDefaultBuilder()
219                         .setMsduDeliveryInfo(TEST_DELIVERY_RATIO, 16)
220                         .build());
221     }
222 
223     /**
224      * Test that an exception is thrown if the caller attempts to get an optional field
225      * that was not assigned a value.
226      */
227     @Test
testOptionalFields_unsetException()228     public void testOptionalFields_unsetException() {
229         assertThrows(IllegalStateException.class, () ->
230                 getDefaultBuilder().build().getMaxMsduSizeOctets());
231         assertThrows(IllegalStateException.class, () ->
232                 getDefaultBuilder().build().getServiceStartTimeMicros());
233         assertThrows(IllegalStateException.class, () ->
234                 getDefaultBuilder().build().getServiceStartTimeLinkId());
235         assertThrows(IllegalStateException.class, () ->
236                 getDefaultBuilder().build().getMeanDataRateKbps());
237         assertThrows(IllegalStateException.class, () ->
238                 getDefaultBuilder().build().getBurstSizeOctets());
239         assertThrows(IllegalStateException.class, () ->
240                 getDefaultBuilder().build().getMsduLifetimeMillis());
241         assertThrows(IllegalStateException.class, () ->
242                 getDefaultBuilder().build().getDeliveryRatio());
243         assertThrows(IllegalStateException.class, () ->
244                 getDefaultBuilder().build().getCountExponent());
245     }
246 
247     /**
248      * Tests that the parceling logic can properly read and write from a Parcel.
249      */
250     @Test
testParcelReadWrite()251     public void testParcelReadWrite() {
252         QosCharacteristics qosCharacteristics = getDefaultQosCharacteristics();
253         Parcel parcel = Parcel.obtain();
254         qosCharacteristics.writeToParcel(parcel, 0);
255         parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
256         QosCharacteristics unparceledQosCharacteristics =
257                 QosCharacteristics.CREATOR.createFromParcel(parcel);
258         validateDefaultFields(unparceledQosCharacteristics);
259     }
260 
261     /**
262      * Tests that the overridden equality and hashCode operators properly compare the same object.
263      */
264     @Test
testSameObjectComparison()265     public void testSameObjectComparison() {
266         QosCharacteristics qosCharacteristics1 = getDefaultQosCharacteristics();
267         QosCharacteristics qosCharacteristics2 = getDefaultQosCharacteristics();
268         assertTrue(qosCharacteristics1.equals(qosCharacteristics2));
269         assertEquals(qosCharacteristics1.hashCode(), qosCharacteristics2.hashCode());
270     }
271 
272     /**
273      * Tests that the overridden equality and hashCode operators properly compare different objects.
274      */
275     @Test
testDifferentObjectComparison()276     public void testDifferentObjectComparison() {
277         QosCharacteristics qosCharacteristics1 = getDefaultQosCharacteristics();
278         QosCharacteristics qosCharacteristics2 = getDefaultBuilder().build();
279         assertFalse(qosCharacteristics1.equals(qosCharacteristics2));
280         assertNotEquals(qosCharacteristics1.hashCode(), qosCharacteristics2.hashCode());
281     }
282 }
283