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