diff options
Diffstat (limited to 'tests')
12 files changed, 466 insertions, 93 deletions
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt index 77e9f12c7152..bcc907285e35 100644 --- a/tests/net/common/java/android/net/NetworkProviderTest.kt +++ b/tests/net/common/java/android/net/NetworkProviderTest.kt @@ -29,6 +29,7 @@ import androidx.test.InstrumentationRegistry import com.android.net.module.util.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo import com.android.testutils.DevSdkIgnoreRunner +import com.android.testutils.isDevSdkInRange import org.junit.After import org.junit.Before import org.junit.Test @@ -173,10 +174,12 @@ class NetworkProviderTest { @Test fun testDeclareNetworkRequestUnfulfillable() { val mockContext = mock(Context::class.java) - val provider = createNetworkProvider(mockContext) - // ConnectivityManager not required at creation time - verifyNoMoreInteractions(mockContext) doReturn(mCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE) + val provider = createNetworkProvider(mockContext) + // ConnectivityManager not required at creation time after R + if (!isDevSdkInRange(0, Build.VERSION_CODES.R)) { + verifyNoMoreInteractions(mockContext) + } mCm.registerNetworkProvider(provider) diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java index ada5494efd60..076e41d33a8d 100644 --- a/tests/net/java/android/net/Ikev2VpnProfileTest.java +++ b/tests/net/java/android/net/Ikev2VpnProfileTest.java @@ -29,6 +29,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.net.VpnProfile; +import com.android.net.module.util.ProxyUtils; import com.android.org.bouncycastle.x509.X509V1CertificateGenerator; import org.junit.Before; @@ -67,7 +68,8 @@ public class Ikev2VpnProfileTest { return "fooPackage"; } }; - private final ProxyInfo mProxy = new ProxyInfo(SERVER_ADDR_STRING, -1, EXCL_LIST); + private final ProxyInfo mProxy = ProxyInfo.buildDirectProxy( + SERVER_ADDR_STRING, -1, ProxyUtils.exclusionStringAsList(EXCL_LIST)); private X509Certificate mUserCert; private X509Certificate mServerRootCa; diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java index 91c9a2a38036..6de31f6b4be1 100644 --- a/tests/net/java/android/net/MacAddressTest.java +++ b/tests/net/java/android/net/MacAddressTest.java @@ -22,11 +22,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.net.util.MacAddressUtils; - import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.net.module.util.MacAddressUtils; + import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java index 3158cc8637e4..7748288aeb05 100644 --- a/tests/net/java/android/net/NetworkUtilsTest.java +++ b/tests/net/java/android/net/NetworkUtilsTest.java @@ -16,24 +16,10 @@ package android.net; -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.AF_UNIX; -import static android.system.OsConstants.EPERM; -import static android.system.OsConstants.SOCK_DGRAM; -import static android.system.OsConstants.SOCK_STREAM; - import static junit.framework.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.system.ErrnoException; -import android.system.Os; - import androidx.test.runner.AndroidJUnit4; -import libcore.io.IoUtils; - import org.junit.Test; import org.junit.runner.RunWith; @@ -139,50 +125,4 @@ public class NetworkUtilsTest { assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536), NetworkUtils.routedIPv6AddressCount(set)); } - - private static void expectSocketSuccess(String msg, int domain, int type) { - try { - IoUtils.closeQuietly(Os.socket(domain, type, 0)); - } catch (ErrnoException e) { - fail(msg + e.getMessage()); - } - } - - private static void expectSocketPemissionError(String msg, int domain, int type) { - try { - IoUtils.closeQuietly(Os.socket(domain, type, 0)); - fail(msg); - } catch (ErrnoException e) { - assertEquals(msg, e.errno, EPERM); - } - } - - private static void expectHasNetworking() { - expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", - AF_UNIX, SOCK_STREAM); - expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException", - AF_INET, SOCK_DGRAM); - expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException", - AF_INET6, SOCK_DGRAM); - } - - private static void expectNoNetworking() { - expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", - AF_UNIX, SOCK_STREAM); - expectSocketPemissionError( - "Creating a AF_INET socket should have thrown ErrnoException(EPERM)", - AF_INET, SOCK_DGRAM); - expectSocketPemissionError( - "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)", - AF_INET6, SOCK_DGRAM); - } - - @Test - public void testSetAllowNetworkingForProcess() { - expectHasNetworking(); - NetworkUtils.setAllowNetworkingForProcess(false); - expectNoNetworking(); - NetworkUtils.setAllowNetworkingForProcess(true); - expectHasNetworking(); - } } diff --git a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java new file mode 100644 index 000000000000..3cfecd552967 --- /dev/null +++ b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015 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.internal.net; + +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; +import static android.system.OsConstants.AF_UNIX; +import static android.system.OsConstants.EPERM; +import static android.system.OsConstants.SOCK_DGRAM; +import static android.system.OsConstants.SOCK_STREAM; + +import static junit.framework.Assert.assertEquals; + +import static org.junit.Assert.fail; + +import android.system.ErrnoException; +import android.system.Os; + +import androidx.test.runner.AndroidJUnit4; + +import libcore.io.IoUtils; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@androidx.test.filters.SmallTest +public class NetworkUtilsInternalTest { + + private static void expectSocketSuccess(String msg, int domain, int type) { + try { + IoUtils.closeQuietly(Os.socket(domain, type, 0)); + } catch (ErrnoException e) { + fail(msg + e.getMessage()); + } + } + + private static void expectSocketPemissionError(String msg, int domain, int type) { + try { + IoUtils.closeQuietly(Os.socket(domain, type, 0)); + fail(msg); + } catch (ErrnoException e) { + assertEquals(msg, e.errno, EPERM); + } + } + + private static void expectHasNetworking() { + expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", + AF_UNIX, SOCK_STREAM); + expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException", + AF_INET, SOCK_DGRAM); + expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException", + AF_INET6, SOCK_DGRAM); + } + + private static void expectNoNetworking() { + expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", + AF_UNIX, SOCK_STREAM); + expectSocketPemissionError( + "Creating a AF_INET socket should have thrown ErrnoException(EPERM)", + AF_INET, SOCK_DGRAM); + expectSocketPemissionError( + "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)", + AF_INET6, SOCK_DGRAM); + } + + @Test + public void testSetAllowNetworkingForProcess() { + expectHasNetworking(); + NetworkUtilsInternal.setAllowNetworkingForProcess(false); + expectNoNetworking(); + NetworkUtilsInternal.setAllowNetworkingForProcess(true); + expectHasNetworking(); + } +} diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a68044a985be..a613e5e332fc 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -4742,11 +4742,9 @@ public class ConnectivityServiceTest { @Test public void testNetworkCallbackMaximum() { - // We can only have 99 callbacks, because MultipathPolicyTracker is - // already one of them. - final int MAX_REQUESTS = 99; + final int MAX_REQUESTS = 100; final int CALLBACKS = 89; - final int INTENTS = 10; + final int INTENTS = 11; assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS); NetworkRequest networkRequest = new NetworkRequest.Builder().build(); diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/tests/net/java/com/android/server/NetworkManagementServiceTest.java index ea763d2e931e..13516d75a50d 100644 --- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java +++ b/tests/net/java/com/android/server/NetworkManagementServiceTest.java @@ -68,11 +68,12 @@ import java.util.function.BiFunction; @SmallTest public class NetworkManagementServiceTest { private NetworkManagementService mNMService; - @Mock private Context mContext; @Mock private IBatteryStats.Stub mBatteryStatsService; @Mock private INetd.Stub mNetdService; + private static final int TEST_UID = 111; + @NonNull @Captor private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor; @@ -165,14 +166,14 @@ public class NetworkManagementServiceTest { /** * Interface class activity. */ - unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, 0); - expectSoon(observer).interfaceClassDataActivityChanged("1", true, 1234); + unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, TEST_UID); + expectSoon(observer).interfaceClassDataActivityChanged(1, true, 1234, TEST_UID); - unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, 0); - expectSoon(observer).interfaceClassDataActivityChanged("9", false, 5678); + unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, TEST_UID); + expectSoon(observer).interfaceClassDataActivityChanged(9, false, 5678, TEST_UID); - unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, 0); - expectSoon(observer).interfaceClassDataActivityChanged("9", false, 4321); + unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, TEST_UID); + expectSoon(observer).interfaceClassDataActivityChanged(9, false, 4321, TEST_UID); /** * IP address changes. @@ -222,8 +223,6 @@ public class NetworkManagementServiceTest { assertFalse(mNMService.isFirewallEnabled()); } - private static final int TEST_UID = 111; - @Test public void testNetworkRestrictedDefault() { assertFalse(mNMService.isNetworkRestricted(TEST_UID)); @@ -235,23 +234,23 @@ public class NetworkManagementServiceTest { doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean()); // Restrict usage of mobile data in background - mNMService.setUidMeteredNetworkDenylist(TEST_UID, true); + mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true); assertTrue("Should be true since mobile data usage is restricted", mNMService.isNetworkRestricted(TEST_UID)); mNMService.setDataSaverModeEnabled(true); verify(mNetdService).bandwidthEnableDataSaver(true); - mNMService.setUidMeteredNetworkDenylist(TEST_UID, false); + mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false); assertTrue("Should be true since data saver is on and the uid is not allowlisted", mNMService.isNetworkRestricted(TEST_UID)); - mNMService.setUidMeteredNetworkAllowlist(TEST_UID, true); + mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true); assertFalse("Should be false since data saver is on and the uid is allowlisted", mNMService.isNetworkRestricted(TEST_UID)); // remove uid from allowlist and turn datasaver off again - mNMService.setUidMeteredNetworkAllowlist(TEST_UID, false); + mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false); mNMService.setDataSaverModeEnabled(false); verify(mNetdService).bandwidthEnableDataSaver(false); assertFalse("Network should not be restricted when data saver is off", diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java index fb0cfc0d50ba..89146f945e1f 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java @@ -23,11 +23,11 @@ import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkTemplate.buildTemplateMobileAll; -import static android.net.NetworkUtils.multiplySafeByRational; import static android.os.Process.myUid; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; +import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational; import static com.android.testutils.MiscAsserts.assertThrows; import static org.junit.Assert.assertArrayEquals; diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index cd9406cf3481..c7836297df75 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -23,6 +23,7 @@ import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIMAX; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; +import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.INTERFACES_ALL; @@ -917,7 +918,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testMetered() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState(true /* isMetered */)}; + NetworkState[] states = + new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1146,7 +1148,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testStatsProviderUpdateStats() throws Exception { // Pretend that network comes online. expectDefaultSettings(); - final NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)}; + final NetworkState[] states = + new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1206,7 +1209,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testStatsProviderSetAlert() throws Exception { // Pretend that network comes online. expectDefaultSettings(); - NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)}; + NetworkState[] states = + new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); // Register custom provider and retrieve callback. @@ -1319,6 +1323,47 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertUidTotal(templateAll, UID_RED, 22L + 35L, 26L + 29L, 19L + 7L, 5L + 11L, 1); } + @Test + public void testOperationCount_nonDefault_traffic() throws Exception { + // Pretend mobile network comes online, but wifi is the default network. + expectDefaultSettings(); + NetworkState[] states = new NetworkState[]{ + buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)}; + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); + + // Create some traffic on mobile network. + incrementCurrentTime(HOUR_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 2L, 1L, 3L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_YES, 1L, 3L, 2L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 5L, 4L, 1L, 4L, 0L)); + // Increment operation count, which must have a specific tag. + mService.incrementOperationCount(UID_RED, 0xF00D, 2); + forcePollAndWaitForIdle(); + + // Verify mobile summary is not changed by the operation count. + final NetworkTemplate templateMobile = + buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL); + final NetworkStats statsMobile = mSession.getSummaryForAllUid( + templateMobile, Long.MIN_VALUE, Long.MAX_VALUE, true); + assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, + DEFAULT_NETWORK_ALL, 3L, 4L, 5L, 5L, 0); + assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL, + DEFAULT_NETWORK_ALL, 5L, 4L, 1L, 4L, 0); + + // Verify the operation count is blamed onto the default network. + // TODO: Blame onto the default network is not very reasonable. Consider blame onto the + // network that generates the traffic. + final NetworkTemplate templateWifi = buildTemplateWifiWildcard(); + final NetworkStats statsWifi = mSession.getSummaryForAllUid( + templateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); + assertValues(statsWifi, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL, + DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 2); + } + private static File getBaseDir(File statsDir) { File baseDir = new File(statsDir, "netstats"); baseDir.mkdirs(); @@ -1446,14 +1491,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { } private static NetworkState buildWifiState() { - return buildWifiState(false); + return buildWifiState(false, TEST_IFACE); } - private static NetworkState buildWifiState(boolean isMetered) { + private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) { final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); info.setDetailedState(DetailedState.CONNECTED, null, null); final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(TEST_IFACE); + prop.setInterfaceName(iface); final NetworkCapabilities capabilities = new NetworkCapabilities(); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); diff --git a/tests/vcn/java/android/net/vcn/VcnConfigTest.java b/tests/vcn/java/android/net/vcn/VcnConfigTest.java new file mode 100644 index 000000000000..77944deb26f1 --- /dev/null +++ b/tests/vcn/java/android/net/vcn/VcnConfigTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 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 android.net.vcn; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Collections; +import java.util.Set; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VcnConfigTest { + private static final Set<VcnGatewayConnectionConfig> GATEWAY_CONNECTION_CONFIGS = + Collections.singleton(VcnGatewayConnectionConfigTest.buildTestConfig()); + + // Public visibility for VcnManagementServiceTest + public static VcnConfig buildTestConfig() { + VcnConfig.Builder builder = new VcnConfig.Builder(); + + for (VcnGatewayConnectionConfig gatewayConnectionConfig : GATEWAY_CONNECTION_CONFIGS) { + builder.addGatewayConnectionConfig(gatewayConnectionConfig); + } + + return builder.build(); + } + + @Test + public void testBuilderRequiresGatewayConnectionConfig() { + try { + new VcnConfig.Builder().build(); + fail("Expected exception due to no VcnGatewayConnectionConfigs provided"); + } catch (IllegalArgumentException e) { + } + } + + @Test + public void testBuilderAndGetters() { + final VcnConfig config = buildTestConfig(); + + assertEquals(GATEWAY_CONNECTION_CONFIGS, config.getGatewayConnectionConfigs()); + } + + @Test + public void testPersistableBundle() { + final VcnConfig config = buildTestConfig(); + + assertEquals(config, new VcnConfig(config.toPersistableBundle())); + } + + @Test + public void testParceling() { + final VcnConfig config = buildTestConfig(); + + Parcel parcel = Parcel.obtain(); + config.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + assertEquals(config, VcnConfig.CREATOR.createFromParcel(parcel)); + } +} diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java new file mode 100644 index 000000000000..e98b6ef2b3a6 --- /dev/null +++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2020 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 android.net.vcn; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import android.net.NetworkCapabilities; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VcnGatewayConnectionConfigTest { + private static final int[] EXPOSED_CAPS = + new int[] { + NetworkCapabilities.NET_CAPABILITY_INTERNET, NetworkCapabilities.NET_CAPABILITY_MMS + }; + private static final int[] UNDERLYING_CAPS = new int[] {NetworkCapabilities.NET_CAPABILITY_DUN}; + private static final long[] RETRY_INTERVALS_MS = + new long[] { + TimeUnit.SECONDS.toMillis(5), + TimeUnit.SECONDS.toMillis(30), + TimeUnit.MINUTES.toMillis(1), + TimeUnit.MINUTES.toMillis(5), + TimeUnit.MINUTES.toMillis(15), + TimeUnit.MINUTES.toMillis(30) + }; + private static final int MAX_MTU = 1360; + + // Package protected for use in VcnConfigTest + static VcnGatewayConnectionConfig buildTestConfig() { + final VcnGatewayConnectionConfig.Builder builder = + new VcnGatewayConnectionConfig.Builder() + .setRetryInterval(RETRY_INTERVALS_MS) + .setMaxMtu(MAX_MTU); + + for (int caps : EXPOSED_CAPS) { + builder.addExposedCapability(caps); + } + + for (int caps : UNDERLYING_CAPS) { + builder.addRequiredUnderlyingCapability(caps); + } + + return builder.build(); + } + + @Test + public void testBuilderRequiresNonEmptyExposedCaps() { + try { + new VcnGatewayConnectionConfig.Builder() + .addRequiredUnderlyingCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + + fail("Expected exception due to invalid exposed capabilities"); + } catch (IllegalArgumentException e) { + } + } + + @Test + public void testBuilderRequiresNonEmptyUnderlyingCaps() { + try { + new VcnGatewayConnectionConfig.Builder() + .addExposedCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + + fail("Expected exception due to invalid required underlying capabilities"); + } catch (IllegalArgumentException e) { + } + } + + @Test + public void testBuilderRequiresNonNullRetryInterval() { + try { + new VcnGatewayConnectionConfig.Builder().setRetryInterval(null); + fail("Expected exception due to invalid retryIntervalMs"); + } catch (IllegalArgumentException e) { + } + } + + @Test + public void testBuilderRequiresNonEmptyRetryInterval() { + try { + new VcnGatewayConnectionConfig.Builder().setRetryInterval(new long[0]); + fail("Expected exception due to invalid retryIntervalMs"); + } catch (IllegalArgumentException e) { + } + } + + @Test + public void testBuilderRequiresValidMtu() { + try { + new VcnGatewayConnectionConfig.Builder() + .setMaxMtu(VcnGatewayConnectionConfig.MIN_MTU_V6 - 1); + fail("Expected exception due to invalid mtu"); + } catch (IllegalArgumentException e) { + } + } + + @Test + public void testBuilderAndGetters() { + final VcnGatewayConnectionConfig config = buildTestConfig(); + + for (int cap : EXPOSED_CAPS) { + config.hasExposedCapability(cap); + } + for (int cap : UNDERLYING_CAPS) { + config.requiresUnderlyingCapability(cap); + } + + assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMs()); + assertEquals(MAX_MTU, config.getMaxMtu()); + } + + @Test + public void testPersistableBundle() { + final VcnGatewayConnectionConfig config = buildTestConfig(); + + assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle())); + } +} diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 633cf64bc274..1cc953239fed 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -16,6 +16,9 @@ package com.android.server; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; @@ -26,7 +29,9 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.net.ConnectivityManager; import android.net.vcn.VcnConfig; +import android.net.vcn.VcnConfigTest; import android.os.ParcelUuid; +import android.os.PersistableBundle; import android.os.Process; import android.os.UserHandle; import android.os.test.TestLooper; @@ -37,10 +42,14 @@ import android.telephony.TelephonyManager; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.vcn.util.PersistableBundleUtils; + import org.junit.Test; import org.junit.runner.RunWith; +import java.io.FileNotFoundException; import java.util.Collections; +import java.util.Map; import java.util.UUID; /** Tests for {@link VcnManagementService}. */ @@ -48,6 +57,11 @@ import java.util.UUID; @SmallTest public class VcnManagementServiceTest { private static final ParcelUuid TEST_UUID_1 = new ParcelUuid(new UUID(0, 0)); + private static final ParcelUuid TEST_UUID_2 = new ParcelUuid(new UUID(1, 1)); + private static final VcnConfig TEST_VCN_CONFIG = VcnConfigTest.buildTestConfig(); + private static final Map<ParcelUuid, VcnConfig> TEST_VCN_CONFIG_MAP = + Collections.unmodifiableMap(Collections.singletonMap(TEST_UUID_1, TEST_VCN_CONFIG)); + private static final SubscriptionInfo TEST_SUBSCRIPTION_INFO = new SubscriptionInfo( 1 /* id */, @@ -79,6 +93,8 @@ public class VcnManagementServiceTest { private final TelephonyManager mTelMgr = mock(TelephonyManager.class); private final SubscriptionManager mSubMgr = mock(SubscriptionManager.class); private final VcnManagementService mVcnMgmtSvc; + private final PersistableBundleUtils.LockingReadWriteHelper mConfigReadWriteHelper = + mock(PersistableBundleUtils.LockingReadWriteHelper.class); public VcnManagementServiceTest() throws Exception { setupSystemService(mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); @@ -88,6 +104,16 @@ public class VcnManagementServiceTest { doReturn(mTestLooper.getLooper()).when(mMockDeps).getLooper(); doReturn(Process.FIRST_APPLICATION_UID).when(mMockDeps).getBinderCallingUid(); + doReturn(mConfigReadWriteHelper) + .when(mMockDeps) + .newPersistableBundleLockingReadWriteHelper(any()); + + final PersistableBundle bundle = + PersistableBundleUtils.fromMap( + TEST_VCN_CONFIG_MAP, + PersistableBundleUtils::fromParcelUuid, + VcnConfig::toPersistableBundle); + doReturn(bundle).when(mConfigReadWriteHelper).readFromDisk(); setupMockedCarrierPrivilege(true); mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps); @@ -116,11 +142,41 @@ public class VcnManagementServiceTest { } @Test + public void testNonSystemServerRealConfigFileAccessPermission() throws Exception { + // Attempt to build a real instance of the dependencies, and verify we cannot write to the + // file. + VcnManagementService.Dependencies deps = new VcnManagementService.Dependencies(); + PersistableBundleUtils.LockingReadWriteHelper configReadWriteHelper = + deps.newPersistableBundleLockingReadWriteHelper( + VcnManagementService.VCN_CONFIG_FILE); + + // Even tests should not be able to read/write configs from disk; SELinux policies restrict + // it to only the system server. + // Reading config should always return null since the file "does not exist", and writing + // should throw an IOException. + assertNull(configReadWriteHelper.readFromDisk()); + + try { + configReadWriteHelper.writeToDisk(new PersistableBundle()); + fail("Expected IOException due to SELinux policy"); + } catch (FileNotFoundException expected) { + } + } + + @Test + public void testLoadVcnConfigsOnStartup() throws Exception { + mTestLooper.dispatchAll(); + + assertEquals(TEST_VCN_CONFIG_MAP, mVcnMgmtSvc.getConfigs()); + verify(mConfigReadWriteHelper).readFromDisk(); + } + + @Test public void testSetVcnConfigRequiresNonSystemServer() throws Exception { doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid(); try { - mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, new VcnConfig.Builder().build()); + mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, VcnConfigTest.buildTestConfig()); fail("Expected IllegalStateException exception for system server"); } catch (IllegalStateException expected) { } @@ -133,7 +189,7 @@ public class VcnManagementServiceTest { .getBinderCallingUid(); try { - mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, new VcnConfig.Builder().build()); + mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, VcnConfigTest.buildTestConfig()); fail("Expected security exception for non system user"); } catch (SecurityException expected) { } @@ -144,13 +200,21 @@ public class VcnManagementServiceTest { setupMockedCarrierPrivilege(false); try { - mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, new VcnConfig.Builder().build()); + mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, VcnConfigTest.buildTestConfig()); fail("Expected security exception for missing carrier privileges"); } catch (SecurityException expected) { } } @Test + public void testSetVcnConfig() throws Exception { + // Use a different UUID to simulate a new VCN config. + mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG); + assertEquals(TEST_VCN_CONFIG, mVcnMgmtSvc.getConfigs().get(TEST_UUID_2)); + verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class)); + } + + @Test public void testClearVcnConfigRequiresNonSystemServer() throws Exception { doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid(); @@ -184,4 +248,11 @@ public class VcnManagementServiceTest { } catch (SecurityException expected) { } } + + @Test + public void testClearVcnConfig() throws Exception { + mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1); + assertTrue(mVcnMgmtSvc.getConfigs().isEmpty()); + verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class)); + } } |