From fd4a967604904a1fcbbef710dfef7e618fce3daa Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Fri, 22 May 2020 16:27:28 +0000 Subject: [PATCH 1/4] Deflaky test for DnsResolverTest It's possible that private DNS setting is not in the state we expected when we tried to enable strict mode during tests. The problem here is that there are 2 setting Uris(mode and specifier) relating to strict mode, each of them might trigger private DNS setting changing evnet in ConnectivityService. Previously, we tried to enable strict mode with first set private DNS mode and then private DNS specifier. This may result in 2 consecutive private DNS changes events with very short intervals, which caused conflicts between DnsResolver / NetworkMonitor and lead to flaky tests. So 0. Use opportunistic as default mode if no default mode existed. 1. Change the order (mode and specifier) for enabling strict mode. 2. Change private DNS mode only when needed. (If original mode is "hostname", then we only need to set specifier) Bug: 153624005 Bug: 151122313 Bug: 150952393 Test: atest DnsResolverTest --rerun-until-failure 100 Test: forrest (git_master, cts/networking/gce-all) Test: forrest (git_rvc-dev, atest CtsNetTestCases) Test: forrest (git_rvc-dev, mts/dnsresolver/device-all) Merged-In: I224a6493c87cebaf0bf954c2644e2945ccd50db1 Change-Id: Ib61ad7bd510341366ebbbb72aa451e5809ee3e9d (cherry picked from commit 7561b1499c1b8da0334b32c0452d49113d9e4806) --- .../src/android/net/cts/DnsResolverTest.java | 35 ++--------- .../android/net/cts/MultinetworkApiTest.java | 23 ++----- .../android/net/cts/util/CtsNetUtils.java | 62 +++++++++++++++++-- 3 files changed, 66 insertions(+), 54 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 1cc49f900a..28753ffc41 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -86,7 +86,6 @@ public class DnsResolverTest extends AndroidTestCase { static final int CANCEL_RETRY_TIMES = 5; static final int QUERY_TIMES = 10; static final int NXDOMAIN = 3; - static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000; private ContentResolver mCR; private ConnectivityManager mCM; @@ -107,32 +106,15 @@ public class DnsResolverTest extends AndroidTestCase { mExecutorInline = (Runnable r) -> r.run(); mCR = getContext().getContentResolver(); mCtsNetUtils = new CtsNetUtils(getContext()); - storePrivateDnsSetting(); + mCtsNetUtils.storePrivateDnsSetting(); } @Override protected void tearDown() throws Exception { - restorePrivateDnsSetting(); + mCtsNetUtils.restorePrivateDnsSetting(); super.tearDown(); } - private void storePrivateDnsSetting() { - // Store private DNS setting - mOldMode = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_MODE); - mOldDnsSpecifier = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER); - } - - private void restorePrivateDnsSetting() throws InterruptedException { - // restore private DNS setting - Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldMode); - if ("hostname".equals(mOldMode)) { - Settings.Global.putString( - mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, mOldDnsSpecifier); - mCtsNetUtils.awaitPrivateDnsSetting("restorePrivateDnsSetting timeout", - mCM.getActiveNetwork(), mOldDnsSpecifier, PRIVATE_DNS_SETTING_TIMEOUT_MS, true); - } - } - private static String byteArrayToHexString(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; ++i) { @@ -416,16 +398,13 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "RawQuery " + TEST_NX_DOMAIN + " with private DNS"; // Enable private DNS strict mode and set server to dns.google before doing NxDomain test. // b/144521720 - Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname"); - Settings.Global.putString(mCR, - Settings.Global.PRIVATE_DNS_SPECIFIER, GOOGLE_PRIVATE_DNS_SERVER); + mCtsNetUtils.setPrivateDnsStrictMode(GOOGLE_PRIVATE_DNS_SERVER); for (Network network : getTestableNetworks()) { final Network networkForPrivateDns = (network != null) ? network : mCM.getActiveNetwork(); assertNotNull("Can't find network to await private DNS on", networkForPrivateDns); mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout", - networkForPrivateDns, GOOGLE_PRIVATE_DNS_SERVER, - PRIVATE_DNS_SETTING_TIMEOUT_MS, true); + networkForPrivateDns, GOOGLE_PRIVATE_DNS_SERVER, true); final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, TEST_NX_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, executor, null, callback); @@ -688,9 +667,7 @@ public class DnsResolverTest extends AndroidTestCase { final Network[] testNetworks = getTestableNetworks(); // Set an invalid private DNS server - Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname"); - Settings.Global.putString(mCR, - Settings.Global.PRIVATE_DNS_SPECIFIER, INVALID_PRIVATE_DNS_SERVER); + mCtsNetUtils.setPrivateDnsStrictMode(INVALID_PRIVATE_DNS_SERVER); final String msg = "Test PrivateDnsBypass " + TEST_DOMAIN; for (Network network : testNetworks) { // This test cannot be ran with null network because we need to explicitly pass a @@ -699,7 +676,7 @@ public class DnsResolverTest extends AndroidTestCase { // wait for private DNS setting propagating mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout", - network, INVALID_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS, false); + network, INVALID_PRIVATE_DNS_SERVER, false); final CountDownLatch latch = new CountDownLatch(1); final DnsResolver.Callback> errorCallback = diff --git a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java index f123187d86..985e313a92 100644 --- a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java +++ b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java @@ -41,7 +41,6 @@ public class MultinetworkApiTest extends AndroidTestCase { private static final String TAG = "MultinetworkNativeApiTest"; static final String GOOGLE_PRIVATE_DNS_SERVER = "dns.google"; - static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 2_000; /** * @return 0 on success @@ -69,7 +68,7 @@ public class MultinetworkApiTest extends AndroidTestCase { mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); mCR = getContext().getContentResolver(); mCtsNetUtils = new CtsNetUtils(getContext()); - storePrivateDnsSetting(); + mCtsNetUtils.storePrivateDnsSetting(); } @Override @@ -77,18 +76,6 @@ public class MultinetworkApiTest extends AndroidTestCase { super.tearDown(); } - private void storePrivateDnsSetting() { - // Store private DNS setting - mOldMode = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_MODE); - mOldDnsSpecifier = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER); - } - - private void restorePrivateDnsSetting() { - // restore private DNS setting - Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldMode); - Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, mOldDnsSpecifier); - } - private Network[] getTestableNetworks() { final ArrayList testableNetworks = new ArrayList(); for (Network network : mCM.getAllNetworks()) { @@ -239,17 +226,15 @@ public class MultinetworkApiTest extends AndroidTestCase { // Enable private DNS strict mode and set server to dns.google before doing NxDomain test. // b/144521720 try { - Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname"); - Settings.Global.putString(mCR, - Settings.Global.PRIVATE_DNS_SPECIFIER, GOOGLE_PRIVATE_DNS_SERVER); + mCtsNetUtils.setPrivateDnsStrictMode(GOOGLE_PRIVATE_DNS_SERVER); for (Network network : getTestableNetworks()) { // Wait for private DNS setting to propagate. mCtsNetUtils.awaitPrivateDnsSetting("NxDomain test wait private DNS setting timeout", - network, GOOGLE_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS, true); + network, GOOGLE_PRIVATE_DNS_SERVER, true); runResNnxDomainCheck(network.getNetworkHandle()); } } finally { - restorePrivateDnsSetting(); + mCtsNetUtils.restorePrivateDnsSetting(); } } } diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java index 824146fedf..f39b184914 100644 --- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java +++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java @@ -17,6 +17,7 @@ package android.net.cts.util; import static android.Manifest.permission.NETWORK_SETTINGS; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -28,6 +29,7 @@ import static org.junit.Assert.fail; import android.annotation.NonNull; import android.content.BroadcastReceiver; import android.content.Context; +import android.content.ContentResolver; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; @@ -39,6 +41,7 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.NetworkRequest; import android.net.wifi.WifiManager; +import android.provider.Settings; import android.system.Os; import android.system.OsConstants; import android.util.Log; @@ -59,6 +62,7 @@ public final class CtsNetUtils { private static final int SOCKET_TIMEOUT_MS = 2000; private static final int PRIVATE_DNS_PROBE_MS = 1_000; + public static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000; public static final int HTTP_PORT = 80; public static final String TEST_HOST = "connectivitycheck.gstatic.com"; public static final String HTTP_REQUEST = @@ -69,15 +73,19 @@ public final class CtsNetUtils { public static final String NETWORK_CALLBACK_ACTION = "ConnectivityManagerTest.NetworkCallbackAction"; - private Context mContext; - private ConnectivityManager mCm; - private WifiManager mWifiManager; + private final Context mContext; + private final ConnectivityManager mCm; + private final ContentResolver mCR; + private final WifiManager mWifiManager; private TestNetworkCallback mCellNetworkCallback; + private String mOldPrivateDnsMode; + private String mOldPrivateDnsSpecifier; public CtsNetUtils(Context context) { mContext = context; mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mCR = context.getContentResolver(); } // Toggle WiFi twice, leaving it in the state it started in @@ -249,9 +257,51 @@ public final class CtsNetUtils { return s; } + public void storePrivateDnsSetting() { + // Store private DNS setting + mOldPrivateDnsMode = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_MODE); + mOldPrivateDnsSpecifier = Settings.Global.getString(mCR, + Settings.Global.PRIVATE_DNS_SPECIFIER); + // It's possible that there is no private DNS default value in Settings. + // Give it a proper default mode which is opportunistic mode. + if (mOldPrivateDnsMode == null) { + mOldPrivateDnsSpecifier = ""; + mOldPrivateDnsMode = PRIVATE_DNS_MODE_OPPORTUNISTIC; + Settings.Global.putString(mCR, + Settings.Global.PRIVATE_DNS_SPECIFIER, mOldPrivateDnsSpecifier); + Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldPrivateDnsMode); + } + } + + public void restorePrivateDnsSetting() throws InterruptedException { + if (mOldPrivateDnsMode == null || mOldPrivateDnsSpecifier == null) { + return; + } + // restore private DNS setting + if ("hostname".equals(mOldPrivateDnsMode)) { + setPrivateDnsStrictMode(mOldPrivateDnsSpecifier); + awaitPrivateDnsSetting("restorePrivateDnsSetting timeout", + mCm.getActiveNetwork(), + mOldPrivateDnsSpecifier, true); + } else { + Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldPrivateDnsMode); + } + } + + public void setPrivateDnsStrictMode(String server) { + // To reduce flake rate, set PRIVATE_DNS_SPECIFIER before PRIVATE_DNS_MODE. This ensures + // that if the previous private DNS mode was not "hostname", the system only sees one + // EVENT_PRIVATE_DNS_SETTINGS_CHANGED event instead of two. + Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, server); + final String mode = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_MODE); + // If current private DNS mode is "hostname", we only need to set PRIVATE_DNS_SPECIFIER. + if (!"hostname".equals(mode)) { + Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname"); + } + } + public void awaitPrivateDnsSetting(@NonNull String msg, @NonNull Network network, - @NonNull String server, int timeoutMs, - boolean requiresValidatedServers) throws InterruptedException { + @NonNull String server, boolean requiresValidatedServers) throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); NetworkCallback callback = new NetworkCallback() { @@ -266,7 +316,7 @@ public final class CtsNetUtils { } }; mCm.registerNetworkCallback(request, callback); - assertTrue(msg, latch.await(timeoutMs, TimeUnit.MILLISECONDS)); + assertTrue(msg, latch.await(PRIVATE_DNS_SETTING_TIMEOUT_MS, TimeUnit.MILLISECONDS)); mCm.unregisterNetworkCallback(callback); // Wait some time for NetworkMonitor's private DNS probe to complete. If we do not do // this, then the test could complete before the NetworkMonitor private DNS probe From 9604af354406406dd4df72c77c676cced4f14f63 Mon Sep 17 00:00:00 2001 From: Automerger Merge Worker Date: Fri, 22 May 2020 00:27:02 +0000 Subject: [PATCH 2/4] Exit test if device does not support IPsec tunnel Bug: 155926216 Test: CtsIkeTestCases Change-Id: I4e426b8f3509e56e7e2e7532e216533ad8bfbc2f Merged-In: I4e426b8f3509e56e7e2e7532e216533ad8bfbc2f (cherry picked from commit eb70555351725a608afac0fb9f94a327e9236729) --- .../android/net/ipsec/ike/cts/IkeSessionPskTest.java | 12 +++++++++--- .../net/ipsec/ike/cts/IkeSessionTestBase.java | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java index ed67dd1bd7..336d12dad1 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java @@ -122,7 +122,9 @@ public class IkeSessionPskTest extends IkeSessionTestBase { } @Test - public void testIkeSessionSetupAndManageChildSas() throws Exception { + public void testIkeSessionSetupAndChildSessionSetupWithTunnelMode() throws Exception { + if (!hasTunnelsFeature()) return; + // Open IKE Session IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); int expectedMsgId = 0; @@ -210,7 +212,9 @@ public class IkeSessionPskTest extends IkeSessionTestBase { } @Test - public void testIkeSessionKill() throws Exception { + public void testIkeSessionKillWithTunnelMode() throws Exception { + if (!hasTunnelsFeature()) return; + // Open IKE Session IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); int expectedMsgId = 0; @@ -254,5 +258,7 @@ public class IkeSessionPskTest extends IkeSessionTestBase { assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData()); } - // TODO(b/148689509): Verify rekey process and handling IKE_AUTH failure + // TODO(b/155821007): Verify rekey process and handling IKE_AUTH failure + + // TODO(b/155821007): Test creating transport mode Child SA } diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java index deba8fd985..1c1ffc922f 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java @@ -20,6 +20,7 @@ import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; import android.annotation.NonNull; import android.app.AppOpsManager; import android.content.Context; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.InetAddresses; import android.net.IpSecTransform; @@ -368,6 +369,11 @@ abstract class IkeSessionTestBase extends IkeTestBase { } } + /** Package private method to check if device has IPsec tunnels feature */ + static boolean hasTunnelsFeature() { + return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); + } + // TODO(b/148689509): Verify IKE Session setup using EAP and digital-signature-based auth // TODO(b/148689509): Verify hostname based creation From f580c71a43e72ea4b97858db83e2f93711dca3f1 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Fri, 22 May 2020 03:24:20 +0000 Subject: [PATCH 3/4] Cleanup of IkeSessionPskTest - Add java doc in IkeSessionTestBase about the necessity to use different addresses and Networks in each test - Use ArrayTrackRecord in Test Session Callback to retrieve the latest result. - Verify that IpSecTransform pair is created and deleted Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ib747c8cdfe1827e8df2aa7544e28e98a177d3d1c Merged-In: Ib747c8cdfe1827e8df2aa7544e28e98a177d3d1c (cherry picked from commit f729d7a112e83e04c008b0bbeed333238482d3e9) --- .../net/ipsec/ike/cts/IkeSessionPskTest.java | 51 +++++++++++-------- .../net/ipsec/ike/cts/IkeSessionTestBase.java | 19 ++++--- .../net/ipsec/ike/cts/IkeTunUtils.java | 4 +- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java index 336d12dad1..fb93398b26 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java @@ -99,19 +99,17 @@ public class IkeSessionPskTest extends IkeSessionTestBase { .addInternalAddressRequest(AF_INET6) .build(); - private IkeSessionParams createIkeSessionParams(InetAddress mRemoteAddress) { - return new IkeSessionParams.Builder(sContext) - .setNetwork(mTunNetwork) - .setServerHostname(mRemoteAddress.getHostAddress()) - .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher()) - .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher()) - .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME)) - .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME)) - .setAuthPsk(IKE_PSK) - .build(); - } - - private IkeSession openIkeSession(IkeSessionParams ikeParams) { + private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) { + IkeSessionParams ikeParams = + new IkeSessionParams.Builder(sContext) + .setNetwork(mTunNetwork) + .setServerHostname(remoteAddress.getHostAddress()) + .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher()) + .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher()) + .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME)) + .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME)) + .setAuthPsk(IKE_PSK) + .build(); return new IkeSession( sContext, ikeParams, @@ -126,7 +124,7 @@ public class IkeSessionPskTest extends IkeSessionTestBase { if (!hasTunnelsFeature()) return; // Open IKE Session - IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); int expectedMsgId = 0; mTunUtils.awaitReqAndInjectResp( IKE_INIT_SPI, @@ -167,6 +165,9 @@ public class IkeSessionPskTest extends IkeSessionTestBase { assertTrue(firstChildConfig.getInternalDnsServers().isEmpty()); assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty()); + assertNotNull(mFirstChildSessionCallback.awaitNextCreatedIpSecTransform()); + assertNotNull(mFirstChildSessionCallback.awaitNextCreatedIpSecTransform()); + // Open additional Child Session TestChildSessionCallback additionalChildCb = new TestChildSessionCallback(); ikeSession.openChildSession(CHILD_PARAMS, additionalChildCb); @@ -183,9 +184,12 @@ public class IkeSessionPskTest extends IkeSessionTestBase { Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors()); assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors()); assertTrue(additionalChildConfig.getInternalAddresses().isEmpty()); - assertTrue(firstChildConfig.getInternalSubnets().isEmpty()); - assertTrue(firstChildConfig.getInternalDnsServers().isEmpty()); - assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty()); + assertTrue(additionalChildConfig.getInternalSubnets().isEmpty()); + assertTrue(additionalChildConfig.getInternalDnsServers().isEmpty()); + assertTrue(additionalChildConfig.getInternalDhcpServers().isEmpty()); + + assertNotNull(additionalChildCb.awaitNextCreatedIpSecTransform()); + assertNotNull(additionalChildCb.awaitNextCreatedIpSecTransform()); // Close additional Child Session ikeSession.closeChildSession(additionalChildCb); @@ -195,6 +199,8 @@ public class IkeSessionPskTest extends IkeSessionTestBase { true /* expectedUseEncap */, hexStringToByteArray(SUCCESS_DELETE_CHILD_RESP)); + assertNotNull(additionalChildCb.awaitNextDeletedIpSecTransform()); + assertNotNull(additionalChildCb.awaitNextDeletedIpSecTransform()); additionalChildCb.awaitOnClosed(); // Close IKE Session @@ -205,10 +211,12 @@ public class IkeSessionPskTest extends IkeSessionTestBase { true /* expectedUseEncap */, hexStringToByteArray(SUCCESS_DELETE_IKE_RESP)); + assertNotNull(mFirstChildSessionCallback.awaitNextDeletedIpSecTransform()); + assertNotNull(mFirstChildSessionCallback.awaitNextDeletedIpSecTransform()); mFirstChildSessionCallback.awaitOnClosed(); mIkeSessionCallback.awaitOnClosed(); - // TODO: verify IpSecTransform pair is created and deleted + // TODO: verify created and deleted IpSecTransform pair and their directions } @Test @@ -216,7 +224,7 @@ public class IkeSessionPskTest extends IkeSessionTestBase { if (!hasTunnelsFeature()) return; // Open IKE Session - IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); int expectedMsgId = 0; mTunUtils.awaitReqAndInjectResp( IKE_INIT_SPI, @@ -231,7 +239,6 @@ public class IkeSessionPskTest extends IkeSessionTestBase { hexStringToByteArray(SUCCESS_IKE_AUTH_RESP)); ikeSession.kill(); - mFirstChildSessionCallback.awaitOnClosed(); mIkeSessionCallback.awaitOnClosed(); } @@ -242,7 +249,7 @@ public class IkeSessionPskTest extends IkeSessionTestBase { "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E"; // Open IKE Session - IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); int expectedMsgId = 0; mTunUtils.awaitReqAndInjectResp( IKE_INIT_SPI, @@ -250,6 +257,8 @@ public class IkeSessionPskTest extends IkeSessionTestBase { false /* expectedUseEncap */, hexStringToByteArray(ikeInitFailRespHex)); + mFirstChildSessionCallback.awaitOnClosed(); + IkeException exception = mIkeSessionCallback.awaitOnClosedException(); assertNotNull(exception); assertTrue(exception instanceof IkeProtocolException); diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java index 1c1ffc922f..279d088b3c 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java @@ -40,7 +40,6 @@ import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.platform.test.annotations.AppModeFull; -import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -66,6 +65,13 @@ import java.util.concurrent.TimeUnit; * *

Subclasses MUST explicitly call #setUpTestNetwork and #tearDownTestNetwork to be able to use * the test network + * + *

All IKE Sessions running in test mode will generate SPIs deterministically. That is to say + * each IKE Session will always generate the same IKE INIT SPI and test vectors are generated based + * on this deterministic IKE SPI. Each test will use different local and remote addresses to avoid + * the case that the next test try to allocate the same SPI before the previous test has released + * it, since SPI resources are not released in testing thread. Similarly, each test MUST use + * different Network instances to avoid sharing the same IkeSocket and hitting IKE SPI collision. */ @RunWith(AndroidJUnit4.class) @AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") @@ -117,7 +123,7 @@ abstract class IkeSessionTestBase extends IkeTestBase { InstrumentationRegistry.getInstrumentation() .getUiAutomation() .adoptShellPermissionIdentity(); - sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + sTNM = sContext.getSystemService(TestNetworkManager.class); // Under normal circumstances, the MANAGE_IPSEC_TUNNELS appop would be auto-granted, and // a standard permission is insufficient. So we shell out the appop, to give us the @@ -150,10 +156,6 @@ abstract class IkeSessionTestBase extends IkeTestBase { @After public void tearDown() throws Exception { tearDownTestNetwork(); - - resetNextAvailableAddress(NEXT_AVAILABLE_IP4_ADDR_LOCAL, INITIAL_AVAILABLE_IP4_ADDR_LOCAL); - resetNextAvailableAddress( - NEXT_AVAILABLE_IP4_ADDR_REMOTE, INITIAL_AVAILABLE_IP4_ADDR_REMOTE); } void setUpTestNetwork(InetAddress localAddr) throws Exception { @@ -186,9 +188,8 @@ abstract class IkeSessionTestBase extends IkeTestBase { pkg, // Package name opName, // Appop (allow ? "allow" : "deny")); // Action - Log.d("IKE", "CTS setAppOp cmd " + cmd); - String result = SystemUtil.runShellCommand(cmd); + SystemUtil.runShellCommand(cmd); } } @@ -230,6 +231,7 @@ abstract class IkeSessionTestBase extends IkeTestBase { } } + /** Testing callback that allows caller to block current thread until a method get called */ static class TestIkeSessionCallback implements IkeSessionCallback { private CompletableFuture mFutureIkeConfig = new CompletableFuture<>(); @@ -283,6 +285,7 @@ abstract class IkeSessionTestBase extends IkeTestBase { } } + /** Testing callback that allows caller to block current thread until a method get called */ static class TestChildSessionCallback implements ChildSessionCallback { private CompletableFuture mFutureChildConfig = new CompletableFuture<>(); diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java index 5a8258d57b..f52b88ba3a 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java @@ -121,7 +121,9 @@ public class IkeTunUtils extends TunUtils { + " and message ID " + expectedMsgId); } - return null; + + throw new IllegalStateException( + "Hit an impossible case where fail() didn't throw an exception"); } private static boolean isIke( From e5c451c1dbf2c2fc33a20901080a6c8a0c7dce90 Mon Sep 17 00:00:00 2001 From: evitayan Date: Thu, 21 May 2020 14:28:42 -0700 Subject: [PATCH 4/4] Apply MainlineTestModuleController to IKE CTS Only run the tests when com.google.android.ipsec is installed on device. This CL follows aosp/11427976 as an example. Bug: 150497352 Test: m mts && mts-tradefed run mts-ipsec Change-Id: I5992c54f9c0b9f1aa9752a207660f9f6e97ccace --- tests/cts/net/ipsec/AndroidTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/net/ipsec/AndroidTest.xml b/tests/cts/net/ipsec/AndroidTest.xml index 09e5c93cf8..cd5c118dd6 100644 --- a/tests/cts/net/ipsec/AndroidTest.xml +++ b/tests/cts/net/ipsec/AndroidTest.xml @@ -27,4 +27,7 @@