1/* 2 * 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 com.android.server.wifi.hotspot2; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertFalse; 21import static org.junit.Assert.assertTrue; 22import static org.mockito.Mockito.anyLong; 23import static org.mockito.Mockito.anyObject; 24import static org.mockito.Mockito.never; 25import static org.mockito.Mockito.reset; 26import static org.mockito.Mockito.verify; 27import static org.mockito.Mockito.when; 28import static org.mockito.MockitoAnnotations.initMocks; 29 30import android.test.suitebuilder.annotation.SmallTest; 31 32import com.android.server.wifi.Clock; 33import com.android.server.wifi.hotspot2.anqp.Constants; 34 35import org.junit.Before; 36import org.junit.Test; 37import org.mockito.Mock; 38 39import java.util.Arrays; 40import java.util.List; 41 42/** 43 * Unit tests for {@link com.android.server.wifi.hotspot2.ANQPRequestManager}. 44 */ 45@SmallTest 46public class ANQPRequestManagerTest { 47 private static final long TEST_BSSID = 0x123456L; 48 private static final ANQPNetworkKey TEST_ANQP_KEY = 49 new ANQPNetworkKey("TestSSID", TEST_BSSID, 0, 0); 50 51 private static final List<Constants.ANQPElementType> R1_ANQP_WITHOUT_RC = Arrays.asList( 52 Constants.ANQPElementType.ANQPVenueName, 53 Constants.ANQPElementType.ANQPIPAddrAvailability, 54 Constants.ANQPElementType.ANQPNAIRealm, 55 Constants.ANQPElementType.ANQP3GPPNetwork, 56 Constants.ANQPElementType.ANQPDomName); 57 58 private static final List<Constants.ANQPElementType> R1_ANQP_WITH_RC = Arrays.asList( 59 Constants.ANQPElementType.ANQPVenueName, 60 Constants.ANQPElementType.ANQPIPAddrAvailability, 61 Constants.ANQPElementType.ANQPNAIRealm, 62 Constants.ANQPElementType.ANQP3GPPNetwork, 63 Constants.ANQPElementType.ANQPDomName, 64 Constants.ANQPElementType.ANQPRoamingConsortium); 65 66 private static final List<Constants.ANQPElementType> R1R2_ANQP_WITHOUT_RC = Arrays.asList( 67 Constants.ANQPElementType.ANQPVenueName, 68 Constants.ANQPElementType.ANQPIPAddrAvailability, 69 Constants.ANQPElementType.ANQPNAIRealm, 70 Constants.ANQPElementType.ANQP3GPPNetwork, 71 Constants.ANQPElementType.ANQPDomName, 72 Constants.ANQPElementType.HSFriendlyName, 73 Constants.ANQPElementType.HSWANMetrics, 74 Constants.ANQPElementType.HSConnCapability, 75 Constants.ANQPElementType.HSOSUProviders); 76 77 private static final List<Constants.ANQPElementType> R1R2_ANQP_WITH_RC = Arrays.asList( 78 Constants.ANQPElementType.ANQPVenueName, 79 Constants.ANQPElementType.ANQPIPAddrAvailability, 80 Constants.ANQPElementType.ANQPNAIRealm, 81 Constants.ANQPElementType.ANQP3GPPNetwork, 82 Constants.ANQPElementType.ANQPDomName, 83 Constants.ANQPElementType.ANQPRoamingConsortium, 84 Constants.ANQPElementType.HSFriendlyName, 85 Constants.ANQPElementType.HSWANMetrics, 86 Constants.ANQPElementType.HSConnCapability, 87 Constants.ANQPElementType.HSOSUProviders); 88 89 @Mock PasspointEventHandler mHandler; 90 @Mock Clock mClock; 91 ANQPRequestManager mManager; 92 93 /** 94 * Test setup. 95 */ 96 @Before 97 public void setUp() throws Exception { 98 initMocks(this); 99 mManager = new ANQPRequestManager(mHandler, mClock); 100 } 101 102 /** 103 * Verify that the expected set of ANQP elements are being requested when the targeted AP 104 * doesn't provide roaming consortium OIs and doesn't support Hotspot 2.0 Release 2 ANQP 105 * elements, based on the IEs in the scan result . 106 * 107 * @throws Exception 108 */ 109 @Test 110 public void requestR1ANQPElementsWithoutRC() throws Exception { 111 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 112 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 113 } 114 115 /** 116 * Verify that the expected set of ANQP elements are being requested when the targeted AP 117 * does provide roaming consortium OIs and doesn't support Hotspot 2.0 Release ANQP elements, 118 * based on the IEs in the scan result. 119 * 120 * @throws Exception 121 */ 122 @Test 123 public void requestR1ANQPElementsWithRC() throws Exception { 124 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITH_RC)).thenReturn(true); 125 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, true, false)); 126 } 127 128 /** 129 * Verify that the expected set of ANQP elements are being requested when the targeted AP 130 * doesn't provide roaming consortium OIs and does support Hotspot 2.0 Release ANQP elements, 131 * based on the IEs in the scan result. 132 * 133 * @throws Exception 134 */ 135 @Test 136 public void requestR1R2ANQPElementsWithoutRC() throws Exception { 137 when(mHandler.requestANQP(TEST_BSSID, R1R2_ANQP_WITHOUT_RC)).thenReturn(true); 138 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, true)); 139 } 140 141 /** 142 * Verify that the expected set of ANQP elements are being requested when the targeted AP 143 * does provide roaming consortium OIs and support Hotspot 2.0 Release ANQP elements, 144 * based on the IEs in the scan result. 145 * 146 * @throws Exception 147 */ 148 @Test 149 public void requestR1R2ANQPElementsWithRC() throws Exception { 150 when(mHandler.requestANQP(TEST_BSSID, R1R2_ANQP_WITH_RC)).thenReturn(true); 151 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, true, true)); 152 } 153 154 /** 155 * Verify that attempt to request ANQP elements from an AP will fail when there is a request 156 * already pending. The request will succeed when the hold off time is up. 157 * 158 * @throws Exception 159 */ 160 @Test 161 public void requestANQPElementsWithPendingRequest() throws Exception { 162 // Send the initial request. 163 long startTime = 0; 164 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 165 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); 166 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 167 reset(mHandler); 168 169 // Attempt another request will fail while one is still pending and hold off time is not up 170 // yet. 171 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); 172 assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 173 verify(mHandler, never()).requestANQP(anyLong(), anyObject()); 174 reset(mHandler); 175 176 // Attempt other request will succeed after the hold off time is up. 177 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 178 when(mClock.getElapsedSinceBootMillis()) 179 .thenReturn(startTime + ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS); 180 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 181 } 182 183 /** 184 * Verify that an immediate attempt to request ANQP elements from an AP will succeed when 185 * the previous request is failed on sending. 186 * 187 * @throws Exception 188 */ 189 @Test 190 public void requestANQPElementsAfterRequestSendFailure() throws Exception { 191 // Initial request failed to send. 192 long startTime = 0; 193 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(false); 194 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); 195 assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 196 reset(mHandler); 197 198 // Verify that new request is not being held off after previous send failure. 199 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 200 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); 201 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 202 } 203 204 /** 205 * Verify that an immediate attempt to request ANQP elements from an AP will succeed when 206 * the previous request is completed with success. 207 * 208 * @throws Exception 209 */ 210 @Test 211 public void requestANQPElementsAfterRequestSucceeded() throws Exception { 212 // Send the initial request. 213 long startTime = 0; 214 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 215 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); 216 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 217 reset(mHandler); 218 219 // Request completed with success. Verify that the key associated with the request 220 // is returned. 221 assertEquals(TEST_ANQP_KEY, mManager.onRequestCompleted(TEST_BSSID, true)); 222 223 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 224 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); 225 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 226 } 227 228 /** 229 * Verify that an immediate attempt to request ANQP elements from an AP will fail when 230 * the previous request is completed with failure. The request will succeed after the 231 * hold off time is up. 232 * 233 * @throws Exception 234 */ 235 @Test 236 public void requestANQPElementsAfterRequestFailed() throws Exception { 237 // Send the initial request. 238 long startTime = 0; 239 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 240 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); 241 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 242 reset(mHandler); 243 244 // Request completed with failure. Verify that the key associated with the request 245 // is returned 246 assertEquals(TEST_ANQP_KEY, mManager.onRequestCompleted(TEST_BSSID, false)); 247 248 // Attempt another request will fail since the hold off time is not up yet. 249 when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); 250 assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 251 verify(mHandler, never()).requestANQP(anyLong(), anyObject()); 252 253 // Attempt another request will succeed after the hold off time is up. 254 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 255 when(mClock.getElapsedSinceBootMillis()) 256 .thenReturn(startTime + ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS); 257 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 258 } 259 260 /** 261 * Verify the hold off time for each unanswered query, and that it will stay the same after 262 * reaching the max hold off count {@link ANQPRequestManager#MAX_HOLDOFF_COUNT}. 263 * 264 * @throws Exception 265 */ 266 @Test 267 public void requestANQPElementsWithMaxRetries() throws Exception { 268 long currentTime = 0; 269 270 // Initial request. 271 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 272 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); 273 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 274 reset(mHandler); 275 276 // Sending the request with the hold off time based on the current hold off count. 277 for (int i = 0; i <= ANQPRequestManager.MAX_HOLDOFF_COUNT; i++) { 278 long currentHoldOffTime = ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS * (1 << i); 279 currentTime += (currentHoldOffTime - 1); 280 281 // Request will fail before the hold off time is up. 282 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); 283 assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 284 verify(mHandler, never()).requestANQP(anyLong(), anyObject()); 285 286 // Request will succeed when the hold off time is up. 287 currentTime += 1; 288 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 289 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); 290 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 291 reset(mHandler); 292 } 293 294 // Verify that the hold off time is max out at the maximum hold off count. 295 currentTime += (ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS 296 * (1 << ANQPRequestManager.MAX_HOLDOFF_COUNT) - 1); 297 298 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); 299 assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 300 verify(mHandler, never()).requestANQP(anyLong(), anyObject()); 301 302 currentTime += 1; 303 when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); 304 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); 305 assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); 306 reset(mHandler); 307 } 308} 309