diff options
author | Peter Qiu <zqiu@google.com> | 2016-12-19 13:12:13 -0800 |
---|---|---|
committer | Peter Qiu <zqiu@google.com> | 2017-01-07 19:06:28 -0800 |
commit | 33c46cd7132df4ce72eee0ed2783e1a1e15bc007 (patch) | |
tree | 5a40249488635e92ec337d4d4345e7b65829d2f8 /tests | |
parent | 87c6f1b149804685e46c18d2ad11262f611c9255 (diff) |
hotspot2: add ANQPRequestManager for managing ANQP requests
The main objective is to hold off ANQP requests to an AP
after the previous request is unanwered or failed.
This can eaisly be expanded in the future to throttle ANQP requests
further by taking into consideration of the current connection
status and other criteria, to reduce the impact of ANQP
requests on the network performance and the power consumption.
Bug: 33746564
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: I906508f72832a9e461be6b2db2ceacb997765bb8
Diffstat (limited to 'tests')
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java | 304 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java | 69 |
2 files changed, 373 insertions, 0 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java new file mode 100644 index 000000000..08b37deb9 --- /dev/null +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2016 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.hotspot2; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.anyObject; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.server.wifi.Clock; +import com.android.server.wifi.ScanDetail; +import com.android.server.wifi.hotspot2.anqp.Constants; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import java.util.Arrays; +import java.util.List; + +/** + * Unit tests for {@link com.android.server.wifi.hotspot2.ANQPRequestManager}. + */ +@SmallTest +public class ANQPRequestManagerTest { + private static final long TEST_BSSID = 0x123456L; + private static final ScanDetail TEST_SCAN_DETAIL = mock(ScanDetail.class); + + private static final List<Constants.ANQPElementType> R1_ANQP_WITHOUT_RC = Arrays.asList( + Constants.ANQPElementType.ANQPVenueName, + Constants.ANQPElementType.ANQPIPAddrAvailability, + Constants.ANQPElementType.ANQPNAIRealm, + Constants.ANQPElementType.ANQP3GPPNetwork, + Constants.ANQPElementType.ANQPDomName); + + private static final List<Constants.ANQPElementType> R1_ANQP_WITH_RC = Arrays.asList( + Constants.ANQPElementType.ANQPVenueName, + Constants.ANQPElementType.ANQPIPAddrAvailability, + Constants.ANQPElementType.ANQPNAIRealm, + Constants.ANQPElementType.ANQP3GPPNetwork, + Constants.ANQPElementType.ANQPDomName, + Constants.ANQPElementType.ANQPRoamingConsortium); + + private static final List<Constants.ANQPElementType> R1R2_ANQP_WITHOUT_RC = Arrays.asList( + Constants.ANQPElementType.ANQPVenueName, + Constants.ANQPElementType.ANQPIPAddrAvailability, + Constants.ANQPElementType.ANQPNAIRealm, + Constants.ANQPElementType.ANQP3GPPNetwork, + Constants.ANQPElementType.ANQPDomName, + Constants.ANQPElementType.HSFriendlyName, + Constants.ANQPElementType.HSWANMetrics, + Constants.ANQPElementType.HSConnCapability); + + private static final List<Constants.ANQPElementType> R1R2_ANQP_WITH_RC = Arrays.asList( + Constants.ANQPElementType.ANQPVenueName, + Constants.ANQPElementType.ANQPIPAddrAvailability, + Constants.ANQPElementType.ANQPNAIRealm, + Constants.ANQPElementType.ANQP3GPPNetwork, + Constants.ANQPElementType.ANQPDomName, + Constants.ANQPElementType.ANQPRoamingConsortium, + Constants.ANQPElementType.HSFriendlyName, + Constants.ANQPElementType.HSWANMetrics, + Constants.ANQPElementType.HSConnCapability); + + @Mock PasspointEventHandler mHandler; + @Mock Clock mClock; + ANQPRequestManager mManager; + + /** + * Test setup. + */ + @Before + public void setUp() throws Exception { + initMocks(this); + mManager = new ANQPRequestManager(mHandler, mClock); + } + + /** + * Verify that the expected set of ANQP elements are being requested when the targeted AP + * doesn't provide roaming consortium OIs and doesn't support Hotspot 2.0 Release 2 ANQP + * elements, based on the IEs in the scan result . + * + * @throws Exception + */ + @Test + public void requestR1ANQPElementsWithoutRC() throws Exception { + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + } + + /** + * Verify that the expected set of ANQP elements are being requested when the targeted AP + * does provide roaming consortium OIs and doesn't support Hotspot 2.0 Release ANQP elements, + * based on the IEs in the scan result. + * + * @throws Exception + */ + @Test + public void requestR1ANQPElementsWithRC() throws Exception { + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITH_RC)).thenReturn(true); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, true, false)); + } + + /** + * Verify that the expected set of ANQP elements are being requested when the targeted AP + * doesn't provide roaming consortium OIs and does support Hotspot 2.0 Release ANQP elements, + * based on the IEs in the scan result. + * + * @throws Exception + */ + @Test + public void requestR1R2ANQPElementsWithoutRC() throws Exception { + when(mHandler.requestANQP(TEST_BSSID, R1R2_ANQP_WITHOUT_RC)).thenReturn(true); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, true)); + } + + /** + * Verify that the expected set of ANQP elements are being requested when the targeted AP + * does provide roaming consortium OIs and support Hotspot 2.0 Release ANQP elements, + * based on the IEs in the scan result. + * + * @throws Exception + */ + @Test + public void requestR1R2ANQPElementsWithRC() throws Exception { + when(mHandler.requestANQP(TEST_BSSID, R1R2_ANQP_WITH_RC)).thenReturn(true); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, true, true)); + } + + /** + * Verify that attempt to request ANQP elements from an AP will fail when there is a request + * already pending. The request will succeed when the hold off time is up. + * + * @throws Exception + */ + @Test + public void requestANQPElementsWithPendingRequest() throws Exception { + // Send the initial request. + long startTime = 0; + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + + // Attempt another request will fail while one is still pending and hold off time is not up + // yet. + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + verify(mHandler, never()).requestANQP(anyLong(), anyObject()); + reset(mHandler); + + // Attempt other request will succeed after the hold off time is up. + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()) + .thenReturn(startTime + ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + } + + /** + * Verify that an immediate attempt to request ANQP elements from an AP will succeed when + * the previous request is failed on sending. + * + * @throws Exception + */ + @Test + public void requestANQPElementsAfterRequestSendFailure() throws Exception { + // Initial request failed to send. + long startTime = 0; + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(false); + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + + // Verify that new request is not being held off after previous send failure. + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + } + + /** + * Verify that an immediate attempt to request ANQP elements from an AP will succeed when + * the previous request is completed with success. + * + * @throws Exception + */ + @Test + public void requestANQPElementsAfterRequestSucceeded() throws Exception { + // Send the initial request. + long startTime = 0; + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + + // Request completed with success. + mManager.onRequestCompleted(TEST_BSSID, true); + + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + } + + /** + * Verify that an immediate attempt to request ANQP elements from an AP will fail when + * the previous request is completed with failure. The request will succeed after the + * hold off time is up. + * + * @throws Exception + */ + @Test + public void requestANQPElementsAfterRequestFailed() throws Exception { + // Send the initial request. + long startTime = 0; + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + + // Request completed with failure. + mManager.onRequestCompleted(TEST_BSSID, false); + + // Attempt another request will fail since the hold off time is not up yet. + when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + verify(mHandler, never()).requestANQP(anyLong(), anyObject()); + + // Attempt another request will succeed after the hold off time is up. + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()) + .thenReturn(startTime + ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + } + + /** + * Verify the hold off time for each unanswered query, and that it will stay the same after + * reaching the max hold off count {@link ANQPRequestManager#MAX_HOLDOFF_COUNT}. + * + * @throws Exception + */ + @Test + public void requestANQPElementsWithMaxRetries() throws Exception { + long currentTime = 0; + + // Initial request. + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + + // Sending the request with the hold off time based on the current hold off count. + for (int i = 0; i <= ANQPRequestManager.MAX_HOLDOFF_COUNT; i++) { + long currentHoldOffTime = ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS * (1 << i); + currentTime += (currentHoldOffTime - 1); + + // Request will fail before the hold off time is up. + when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + verify(mHandler, never()).requestANQP(anyLong(), anyObject()); + + // Request will succeed when the hold off time is up. + currentTime += 1; + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + } + + // Verify that the hold off time is max out at the maximum hold off count. + currentTime += (ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS + * (1 << ANQPRequestManager.MAX_HOLDOFF_COUNT) - 1); + + when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + verify(mHandler, never()).requestANQP(anyLong(), anyObject()); + + currentTime += 1; + when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); + when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + reset(mHandler); + } +} diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java index 59dfa3b58..74bb10e84 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java @@ -25,10 +25,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.anyMap; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -50,6 +52,9 @@ import com.android.server.wifi.SIMAccessor; import com.android.server.wifi.ScanDetail; import com.android.server.wifi.WifiKeyStore; import com.android.server.wifi.WifiNative; +import com.android.server.wifi.hotspot2.anqp.ANQPElement; +import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType; +import com.android.server.wifi.hotspot2.anqp.DomainNameElement; import org.junit.Before; import org.junit.Test; @@ -57,7 +62,10 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointManager}. @@ -85,6 +93,7 @@ public class PasspointManagerTest { @Mock PasspointObjectFactory mObjectFactory; @Mock PasspointEventHandler.Callbacks mCallbacks; @Mock AnqpCache mAnqpCache; + @Mock ANQPRequestManager mAnqpRequestManager; PasspointManager mManager; /** Sets up test. */ @@ -92,6 +101,8 @@ public class PasspointManagerTest { public void setUp() throws Exception { initMocks(this); when(mObjectFactory.makeAnqpCache(mClock)).thenReturn(mAnqpCache); + when(mObjectFactory.makeANQPRequestManager(any(PasspointEventHandler.class), eq(mClock))) + .thenReturn(mAnqpRequestManager); mManager = new PasspointManager(mContext, mWifiNative, mWifiKeyStore, mClock, mSimAccessor, mObjectFactory); ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks = @@ -192,6 +203,61 @@ public class PasspointManagerTest { } /** + * Verify that the ANQP elements will be added to the ANQP cache on receiving a successful + * response. + * + * @throws Exception + */ + @Test + public void anqpResponseSuccess() throws Exception { + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); + + ScanDetail scanDetail = createMockScanDetail(); + ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, + TEST_ANQP_DOMAIN_ID); + when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(scanDetail); + mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); + verify(mAnqpCache).addEntry(anqpKey, anqpElementMap); + verify(scanDetail).propagateANQPInfo(anqpElementMap); + } + + /** + * Verify that no ANQP elements will be added to the ANQP cache on receiving a successful + * response for a request that's not sent by us. + * + * @throws Exception + */ + @Test + public void anqpResponseSuccessWithUnknownRequest() throws Exception { + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); + + when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(null); + mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); + verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap()); + } + + /** + * Verify that no ANQP elements will be added to the ANQP cache on receiving a failure response. + * + * @throws Exception + */ + @Test + public void anqpResponseFailure() throws Exception { + ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, + TEST_ANQP_DOMAIN_ID); + + ScanDetail scanDetail = createMockScanDetail(); + when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(scanDetail); + mCallbacks.onANQPResponse(TEST_BSSID, null); + verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap()); + + } + + /** * Validate the broadcast intent when icon file retrieval succeeded. * * @throws Exception @@ -449,6 +515,9 @@ public class PasspointManagerTest { when(mAnqpCache.getEntry(anqpKey)).thenReturn(null); List<Pair<PasspointProvider, PasspointMatch>> result = mManager.matchProvider(createMockScanDetail()); + // Verify that a request for ANQP elements is initiated. + verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID), any(ScanDetail.class), + anyBoolean(), anyBoolean()); assertTrue(result.isEmpty()); } |