From 60cf847709fd2c853882a804c7d2e8206cc90371 Mon Sep 17 00:00:00 2001 From: Glen Kuhne Date: Tue, 20 Sep 2016 16:09:46 -0700 Subject: WiFi Metrics: Add RSSI delta metric (poll v scan) Created a new metric that logs the difference in RSSI values between a ScanResult and the first RSSI poll received after attempting to connect to the AP in that ScanResult. RSSI poll must come within 3 seconds of framework's connections attempt, and is not counted if the connection attempt fails. The value logged is: delta = poll.rssi - scanResult.rssi While I was here: Updated wifi.proto to match downstream placeholder metrics. Test: Added unit tests Bug: 31239324 Merged-In: Ice3768df3e8b5c05ff74e7d75e205748403430dc Change-Id: Ice3768df3e8b5c05ff74e7d75e205748403430dc --- .../com/android/server/wifi/WifiMetricsTest.java | 199 ++++++++++++++++++++- 1 file changed, 197 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index 407fac3af..5cf0654ad 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -659,6 +659,203 @@ public class WifiMetricsTest { 2, mDeserializedWifiMetrics.connectionEvent.length); } + private static final int NUM_REPEATED_DELTAS = 7; + private static final int REPEATED_DELTA = 0; + private static final int SINGLE_GOOD_DELTA = 1; + private static final int SINGLE_TIMEOUT_DELTA = 2; + private static final int NUM_REPEATED_BOUND_DELTAS = 2; + private static final int MAX_DELTA_LEVEL = 127; + private static final int MIN_DELTA_LEVEL = -127; + private static final int ARBITRARY_DELTA_LEVEL = 20; + + /** + * Sunny day RSSI delta logging scenario. + * Logs one rssi delta value multiple times + * Logs a different delta value a single time + */ + @Test + public void testRssiDeltasSuccessfulLogging() throws Exception { + // Generate some repeated deltas + for (int i = 0; i < NUM_REPEATED_DELTAS; i++) { + generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS); + } + // Generate a single delta + generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_GOOD_DELTA, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS); + dumpProtoAndDeserialize(); + assertEquals(2, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + // Check the repeated deltas + assertEquals(NUM_REPEATED_DELTAS, mDeserializedWifiMetrics.rssiPollDeltaCount[0].count); + assertEquals(REPEATED_DELTA, mDeserializedWifiMetrics.rssiPollDeltaCount[0].rssi); + // Check the single delta + assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[1].count); + assertEquals(SINGLE_GOOD_DELTA, mDeserializedWifiMetrics.rssiPollDeltaCount[1].rssi); + } + + /** + * Tests that Rssi Delta events whose scanResult and Rssi Poll come too far apart, timeout, + * and are not logged. + */ + @Test + public void testRssiDeltasTimeout() throws Exception { + // Create timed out rssi deltas + generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1); + generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_TIMEOUT_DELTA, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1); + dumpProtoAndDeserialize(); + assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + } + + /** + * Tests the exact inclusive boundaries of RSSI delta logging. + */ + @Test + public void testRssiDeltaSuccessfulLoggingExactBounds() throws Exception { + generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS); + generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS); + dumpProtoAndDeserialize(); + assertEquals(2, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + assertEquals(MIN_DELTA_LEVEL, mDeserializedWifiMetrics.rssiPollDeltaCount[0].rssi); + assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[0].count); + assertEquals(MAX_DELTA_LEVEL, mDeserializedWifiMetrics.rssiPollDeltaCount[1].rssi); + assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[1].count); + } + + /** + * Tests the exact exclusive boundaries of RSSI delta logging. + * This test ensures that too much data is not generated. + */ + @Test + public void testRssiDeltaOutOfBounds() throws Exception { + generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL + 1, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS); + generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL - 1, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS); + dumpProtoAndDeserialize(); + assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + } + + /** + * This test ensures no rssi Delta is logged after an unsuccessful ConnectionEvent + */ + @Test + public void testUnsuccesfulConnectionEventRssiDeltaIsNotLogged() throws Exception { + generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS, + false, // successfulConnectionEvent + true, // completeConnectionEvent + true, // useValidScanResult + true // dontDeserializeBeforePoll + ); + + dumpProtoAndDeserialize(); + assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + } + + /** + * This test ensures rssi Deltas can be logged during a ConnectionEvent + */ + @Test + public void testIncompleteConnectionEventRssiDeltaIsLogged() throws Exception { + generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS, + true, // successfulConnectionEvent + false, // completeConnectionEvent + true, // useValidScanResult + true // dontDeserializeBeforePoll + ); + dumpProtoAndDeserialize(); + assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + assertEquals(ARBITRARY_DELTA_LEVEL, mDeserializedWifiMetrics.rssiPollDeltaCount[0].rssi); + assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[0].count); + } + + /** + * This test ensures that no delta is logged for a null ScanResult Candidate + */ + @Test + public void testRssiDeltaNotLoggedForNullCandidateScanResult() throws Exception { + generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS, + true, // successfulConnectionEvent + true, // completeConnectionEvent + false, // useValidScanResult + true // dontDeserializeBeforePoll + ); + dumpProtoAndDeserialize(); + assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + } + + /** + * This test ensures that Rssi Deltas are not logged over a 'clear()' call (Metrics Serialized) + */ + @Test + public void testMetricsSerializedDuringRssiDeltaEventLogsNothing() throws Exception { + generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL, + WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS, + true, // successfulConnectionEvent + true, // completeConnectionEvent + true, // useValidScanResult + false // dontDeserializeBeforePoll + ); + dumpProtoAndDeserialize(); + assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length); + } + + /** + * Generate an RSSI delta event by creating a connection event and an RSSI poll within + * 'interArrivalTime' milliseconds of each other. + * Event will not be logged if interArrivalTime > mWifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + * successfulConnectionEvent, completeConnectionEvent, useValidScanResult and + * dontDeserializeBeforePoll + * each create an anomalous condition when set to false. + */ + private void generateRssiDelta(int scanRssi, int rssiDelta, + long interArrivalTime, boolean successfulConnectionEvent, + boolean completeConnectionEvent, boolean useValidScanResult, + boolean dontDeserializeBeforePoll) throws Exception { + when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0); + ScanResult scanResult = null; + if (useValidScanResult) { + scanResult = mock(ScanResult.class); + scanResult.level = scanRssi; + } + WifiConfiguration config = mock(WifiConfiguration.class); + WifiConfiguration.NetworkSelectionStatus networkSelectionStat = + mock(WifiConfiguration.NetworkSelectionStatus.class); + when(networkSelectionStat.getCandidate()).thenReturn(scanResult); + when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat); + mWifiMetrics.startConnectionEvent(config, "TestNetwork", + WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE); + if (completeConnectionEvent) { + if (successfulConnectionEvent) { + mWifiMetrics.endConnectionEvent( + WifiMetrics.ConnectionEvent.FAILURE_NONE, + WifiMetricsProto.ConnectionEvent.HLF_NONE); + } else { + mWifiMetrics.endConnectionEvent( + WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE, + WifiMetricsProto.ConnectionEvent.HLF_NONE); + } + } + when(mClock.getElapsedSinceBootMillis()).thenReturn(interArrivalTime); + if (!dontDeserializeBeforePoll) { + dumpProtoAndDeserialize(); + } + mWifiMetrics.incrementRssiPollRssiCount(scanRssi + rssiDelta); + } + /** + * Generate an RSSI delta event, with all extra conditions set to true. + */ + private void generateRssiDelta(int scanRssi, int rssiDelta, + long interArrivalTime) throws Exception { + generateRssiDelta(scanRssi, rssiDelta, interArrivalTime, true, true, true, true); + } + private void assertStringContains( String actualString, String expectedSubstring) { assertTrue("Expected text not found in: " + actualString, @@ -674,5 +871,3 @@ public class WifiMetricsTest { return stream.toString(); } } - - -- cgit v1.2.3