diff options
Diffstat (limited to 'tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java')
-rw-r--r-- | tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java | 248 |
1 files changed, 234 insertions, 14 deletions
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java index 5107943c3528..441a4ae6d9b6 100644 --- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java +++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java @@ -17,9 +17,12 @@ package com.android.server.vcn.routeselection; import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY; +import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY; import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_POLL_IPSEC_STATE_INTERVAL_SECONDS_KEY; -import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.PACKET_LOSS_UNAVALAIBLE; +import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR; +import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.MIN_VALID_EXPECTED_RX_PACKET_NUM; +import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.getMaxSeqNumIncreasePerSecond; import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; import static org.junit.Assert.assertEquals; @@ -34,6 +37,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; 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; @@ -43,6 +47,7 @@ import android.net.IpSecTransformState; import android.os.OutcomeReceiver; import android.os.PowerManager; +import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculationResult; import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculator; import com.android.server.vcn.routeselection.NetworkMetricMonitor.IpSecTransformWrapper; import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback; @@ -64,6 +69,7 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { private static final int REPLAY_BITMAP_LEN_BYTE = 512; private static final int REPLAY_BITMAP_LEN_BIT = REPLAY_BITMAP_LEN_BYTE * 8; private static final int IPSEC_PACKET_LOSS_PERCENT_THRESHOLD = 5; + private static final int MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED = -1; private static final long POLL_IPSEC_STATE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(30L); @Mock private IpSecTransformWrapper mIpSecTransform; @@ -90,6 +96,9 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY), anyInt())) .thenReturn(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD); + when(mCarrierConfig.getInt( + eq(VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY), anyInt())) + .thenReturn(MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED); when(mDependencies.getPacketLossCalculator()).thenReturn(mPacketLossCalculator); @@ -111,6 +120,20 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { .build(); } + private static IpSecTransformState newNextTransformState( + IpSecTransformState before, + long timeDiffMillis, + long rxSeqNoDiff, + long packtCountDiff, + int packetInWin) { + return new IpSecTransformState.Builder() + .setTimestampMillis(before.getTimestampMillis() + timeDiffMillis) + .setRxHighestSequenceNumber(before.getRxHighestSequenceNumber() + rxSeqNoDiff) + .setPacketCount(before.getPacketCount() + packtCountDiff) + .setReplayBitmap(newReplayBitmap(packetInWin)) + .build(); + } + private static byte[] newReplayBitmap(int receivedPktCnt) { final BitSet bitSet = new BitSet(REPLAY_BITMAP_LEN_BIT); for (int i = 0; i < receivedPktCnt; i++) { @@ -164,7 +187,7 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { // Verify the first polled state is stored assertEquals(mTransformStateInitial, mIpSecPacketLossDetector.getLastTransformState()); verify(mPacketLossCalculator, never()) - .getPacketLossRatePercentage(any(), any(), anyString()); + .getPacketLossRatePercentage(any(), any(), anyInt(), anyString()); // Verify next poll is scheduled assertNull(mTestLooper.nextMessage()); @@ -277,7 +300,7 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { xfrmStateReceiver.onResult(newTransformState(1, 1, newReplayBitmap(1))); verify(mPacketLossCalculator, never()) - .getPacketLossRatePercentage(any(), any(), anyString()); + .getPacketLossRatePercentage(any(), any(), anyInt(), anyString()); } @Test @@ -288,17 +311,19 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { xfrmStateReceiver.onError(new RuntimeException("Test")); verify(mPacketLossCalculator, never()) - .getPacketLossRatePercentage(any(), any(), anyString()); + .getPacketLossRatePercentage(any(), any(), anyInt(), anyString()); } private void checkHandleLossRate( - int mockPacketLossRate, boolean isLastStateExpectedToUpdate, boolean isCallbackExpected) + PacketLossCalculationResult mockPacketLossRate, + boolean isLastStateExpectedToUpdate, + boolean isCallbackExpected) throws Exception { final OutcomeReceiver<IpSecTransformState, RuntimeException> xfrmStateReceiver = startMonitorAndCaptureStateReceiver(); doReturn(mockPacketLossRate) .when(mPacketLossCalculator) - .getPacketLossRatePercentage(any(), any(), anyString()); + .getPacketLossRatePercentage(any(), any(), anyInt(), anyString()); // Mock receiving two states with mTransformStateInitial and an arbitrary transformNew final IpSecTransformState transformNew = newTransformState(1, 1, newReplayBitmap(1)); @@ -308,7 +333,10 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { // Verifications verify(mPacketLossCalculator) .getPacketLossRatePercentage( - eq(mTransformStateInitial), eq(transformNew), anyString()); + eq(mTransformStateInitial), + eq(transformNew), + eq(MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED), + anyString()); if (isLastStateExpectedToUpdate) { assertEquals(transformNew, mIpSecPacketLossDetector.getLastTransformState()); @@ -326,30 +354,53 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { @Test public void testHandleLossRate_validationPass() throws Exception { checkHandleLossRate( - 2, true /* isLastStateExpectedToUpdate */, true /* isCallbackExpected */); + PacketLossCalculationResult.valid(2), + true /* isLastStateExpectedToUpdate */, + true /* isCallbackExpected */); } @Test public void testHandleLossRate_validationFail() throws Exception { checkHandleLossRate( - 22, true /* isLastStateExpectedToUpdate */, true /* isCallbackExpected */); + PacketLossCalculationResult.valid(22), + true /* isLastStateExpectedToUpdate */, + true /* isCallbackExpected */); verify(mConnectivityManager).reportNetworkConnectivity(mNetwork, false); } @Test public void testHandleLossRate_resultUnavalaible() throws Exception { checkHandleLossRate( - PACKET_LOSS_UNAVALAIBLE, + PacketLossCalculationResult.invalid(), false /* isLastStateExpectedToUpdate */, false /* isCallbackExpected */); } + @Test + public void testHandleLossRate_unusualSeqNumLeap_highLossRate() throws Exception { + checkHandleLossRate( + PacketLossCalculationResult.unusualSeqNumLeap(22), + true /* isLastStateExpectedToUpdate */, + false /* isCallbackExpected */); + } + + @Test + public void testHandleLossRate_unusualSeqNumLeap_lowLossRate() throws Exception { + checkHandleLossRate( + PacketLossCalculationResult.unusualSeqNumLeap(2), + true /* isLastStateExpectedToUpdate */, + true /* isCallbackExpected */); + } + private void checkGetPacketLossRate( - IpSecTransformState oldState, IpSecTransformState newState, int expectedLossRate) + IpSecTransformState oldState, + IpSecTransformState newState, + PacketLossCalculationResult expectedLossRate) throws Exception { assertEquals( expectedLossRate, - mPacketLossCalculator.getPacketLossRatePercentage(oldState, newState, TAG)); + mPacketLossCalculator.getPacketLossRatePercentage( + oldState, newState, MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED, TAG)); } private void checkGetPacketLossRate( @@ -361,14 +412,45 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { throws Exception { final IpSecTransformState newState = newTransformState(rxSeqNo, packetCount, newReplayBitmap(packetInWin)); + checkGetPacketLossRate( + oldState, newState, PacketLossCalculationResult.valid(expectedDataLossRate)); + } + + private void checkGetPacketLossRate( + IpSecTransformState oldState, + int rxSeqNo, + int packetCount, + int packetInWin, + PacketLossCalculationResult expectedDataLossRate) + throws Exception { + final IpSecTransformState newState = + newTransformState(rxSeqNo, packetCount, newReplayBitmap(packetInWin)); checkGetPacketLossRate(oldState, newState, expectedDataLossRate); } @Test public void testGetPacketLossRate_replayWindowUnchanged() throws Exception { checkGetPacketLossRate( - mTransformStateInitial, mTransformStateInitial, PACKET_LOSS_UNAVALAIBLE); - checkGetPacketLossRate(mTransformStateInitial, 3000, 2000, 2000, PACKET_LOSS_UNAVALAIBLE); + mTransformStateInitial, + mTransformStateInitial, + PacketLossCalculationResult.invalid()); + checkGetPacketLossRate( + mTransformStateInitial, 3000, 2000, 2000, PacketLossCalculationResult.invalid()); + } + + @Test + public void testGetPacketLossRate_expectedPacketNumTooFew() throws Exception { + final int oldRxNo = 4096; + final int oldPktCnt = 4096; + final int pktCntDiff = MIN_VALID_EXPECTED_RX_PACKET_NUM - 1; + final byte[] bitmapReceiveAll = newReplayBitmap(4096); + + final IpSecTransformState oldState = + newTransformState(oldRxNo, oldPktCnt, bitmapReceiveAll); + final IpSecTransformState newState = + newTransformState(oldRxNo + pktCntDiff, oldPktCnt + pktCntDiff, bitmapReceiveAll); + + checkGetPacketLossRate(oldState, newState, PacketLossCalculationResult.invalid()); } @Test @@ -417,4 +499,142 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { checkGetPacketLossRate(oldState, 20000, 14000, 4096, 19); checkGetPacketLossRate(oldState, 20000, 14000, 3000, 10); } + + private void checkGetPktLossRate_unusualSeqNumLeap( + int maxSeqNumIncreasePerSecond, + int timeDiffMillis, + int rxSeqNoDiff, + PacketLossCalculationResult expected) + throws Exception { + final IpSecTransformState oldState = mTransformStateInitial; + final IpSecTransformState newState = + newNextTransformState( + oldState, + timeDiffMillis, + rxSeqNoDiff, + 1 /* packtCountDiff */, + 1 /* packetInWin */); + + assertEquals( + expected, + mPacketLossCalculator.getPacketLossRatePercentage( + oldState, newState, maxSeqNumIncreasePerSecond, TAG)); + } + + @Test + public void testGetPktLossRate_unusualSeqNumLeap() throws Exception { + checkGetPktLossRate_unusualSeqNumLeap( + 10000 /* maxSeqNumIncreasePerSecond */, + (int) TimeUnit.SECONDS.toMillis(2L), + 30000 /* rxSeqNoDiff */, + PacketLossCalculationResult.unusualSeqNumLeap(100)); + } + + @Test + public void testGetPktLossRate_unusualSeqNumLeap_smallSeqNumDiff() throws Exception { + checkGetPktLossRate_unusualSeqNumLeap( + 10000 /* maxSeqNumIncreasePerSecond */, + (int) TimeUnit.SECONDS.toMillis(2L), + 5000 /* rxSeqNoDiff */, + PacketLossCalculationResult.valid(100)); + } + + // Verify the polling event is scheduled with expected delays + private void verifyPollEventDelayAndScheduleNext(long expectedDelayMs) { + if (expectedDelayMs > 0) { + mTestLooper.dispatchAll(); + verify(mIpSecTransform, never()).requestIpSecTransformState(any(), any()); + mTestLooper.moveTimeForward(expectedDelayMs); + } + + mTestLooper.dispatchAll(); + verify(mIpSecTransform).requestIpSecTransformState(any(), any()); + reset(mIpSecTransform); + } + + @Test + public void testOnLinkPropertiesOrCapabilitiesChange() throws Exception { + // Start the monitor; verify the 1st poll is scheduled without delay + startMonitorAndCaptureStateReceiver(); + verifyPollEventDelayAndScheduleNext(0 /* expectedDelayMs */); + + // Verify the 2nd poll is rescheduled without delay + mIpSecPacketLossDetector.onLinkPropertiesOrCapabilitiesChanged(); + verifyPollEventDelayAndScheduleNext(0 /* expectedDelayMs */); + + // Verify the 3rd poll is scheduled with configured delay + verifyPollEventDelayAndScheduleNext(POLL_IPSEC_STATE_INTERVAL_MS); + } + + @Test + public void testGetMaxSeqNumIncreasePerSecond() throws Exception { + final int seqNumLeapNegative = 500_000; + when(mCarrierConfig.getInt( + eq(VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY), anyInt())) + .thenReturn(seqNumLeapNegative); + assertEquals(seqNumLeapNegative, getMaxSeqNumIncreasePerSecond(mCarrierConfig)); + } + + @Test + public void testGetMaxSeqNumIncreasePerSecond_negativeValue() throws Exception { + final int seqNumLeapNegative = -10; + when(mCarrierConfig.getInt( + eq(VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY), anyInt())) + .thenReturn(seqNumLeapNegative); + assertEquals( + MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED, + getMaxSeqNumIncreasePerSecond(mCarrierConfig)); + } + + private IpSecPacketLossDetector newDetectorAndSetTransform(int threshold) throws Exception { + when(mCarrierConfig.getInt( + eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY), + anyInt())) + .thenReturn(threshold); + + final IpSecPacketLossDetector detector = + new IpSecPacketLossDetector( + mVcnContext, + mNetwork, + mCarrierConfig, + mMetricMonitorCallback, + mDependencies); + + detector.setIsSelectedUnderlyingNetwork(true /* setIsSelected */); + detector.setInboundTransformInternal(mIpSecTransform); + + return detector; + } + + @Test + public void testDisableAndEnableDetectorWithCarrierConfig() throws Exception { + final IpSecPacketLossDetector detector = + newDetectorAndSetTransform(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR); + + assertFalse(detector.isStarted()); + + when(mCarrierConfig.getInt( + eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY), + anyInt())) + .thenReturn(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD); + detector.setCarrierConfig(mCarrierConfig); + + assertTrue(detector.isStarted()); + } + + @Test + public void testEnableAndDisableDetectorWithCarrierConfig() throws Exception { + final IpSecPacketLossDetector detector = + newDetectorAndSetTransform(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD); + + assertTrue(detector.isStarted()); + + when(mCarrierConfig.getInt( + eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY), + anyInt())) + .thenReturn(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR); + detector.setCarrierConfig(mCarrierConfig); + + assertFalse(detector.isStarted()); + } } |