diff --git a/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java b/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java new file mode 100644 index 0000000000..1335eb8011 --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2018 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.security.cts; + +import com.android.tradefed.build.IBuildInfo; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.DeviceTestCase; +import com.android.tradefed.testtype.IBuildReceiver; +import com.android.tradefed.testtype.IDeviceTest; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.lang.Integer; +import java.lang.String; +import java.util.stream.Collectors; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.zip.GZIPInputStream; + +/** + * Host-side tests for values in /proc/net. + * + * These tests analyze /proc/net to verify that certain networking properties are correct. + */ +public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDeviceTest { + private static final String SPI_TIMEOUT_SYSCTL = "/proc/sys/net/core/xfrm_acq_expires"; + private static final int MIN_ACQ_EXPIRES = 3600; + // Global sysctls. Must be present and set to 1. + private static final String[] GLOBAL_SYSCTLS = { + "/proc/sys/net/ipv4/fwmark_reflect", + "/proc/sys/net/ipv6/fwmark_reflect", + "/proc/sys/net/ipv4/tcp_fwmark_accept", + }; + + // Per-interface IPv6 autoconf sysctls. + private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf"; + private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table"; + + // Expected values for MIN|MAX_PLEN. + private static final String ACCEPT_RA_RT_INFO_MIN_PLEN_STRING = "accept_ra_rt_info_min_plen"; + private static final int ACCEPT_RA_RT_INFO_MIN_PLEN_VALUE = 48; + private static final String ACCEPT_RA_RT_INFO_MAX_PLEN_STRING = "accept_ra_rt_info_max_plen"; + private static final int ACCEPT_RA_RT_INFO_MAX_PLEN_VALUE = 64; + // Expected values for RFC 7559 router soliciations. + // Maximum number of router solicitations to send. -1 means no limit. + private static final int IPV6_WIFI_ROUTER_SOLICITATIONS = -1; + private ITestDevice mDevice; + private IBuildInfo mBuild; + + /** + * {@inheritDoc} + */ + @Override + public void setBuild(IBuildInfo build) { + mBuild = build; + } + + /** + * {@inheritDoc} + */ + @Override + public void setDevice(ITestDevice device) { + super.setDevice(device); + mDevice = device; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + protected void assertLess(String sysctl, int a, int b) { + assertTrue("value of " + sysctl + ": expected < " + b + " but was: " + a, a < b); + } + + protected void assertAtLeast(String sysctl, int a, int b) { + assertTrue("value of " + sysctl + ": expected >= " + b + " but was: " + a, a >= b); + } + + public int readIntFromPath(String path) throws Exception { + String mode = mDevice.executeAdbCommand("shell", "stat", "-c", "%a", path).trim(); + String user = mDevice.executeAdbCommand("shell", "stat", "-c", "%u", path).trim(); + String group = mDevice.executeAdbCommand("shell", "stat", "-c", "%g", path).trim(); + assertEquals(mode, "644"); + assertEquals(user, "0"); + assertEquals(group, "0"); + return Integer.parseInt(mDevice.executeAdbCommand("shell", "cat", path).trim()); + } + + /** + * Checks that SPI default timeouts are overridden, and set to a reasonable length of time + */ + public void testMinAcqExpires() throws Exception { + int value = readIntFromPath(SPI_TIMEOUT_SYSCTL); + assertAtLeast(SPI_TIMEOUT_SYSCTL, value, MIN_ACQ_EXPIRES); + } + + /** + * Checks that the sysctls for multinetwork kernel features are present and + * enabled. The necessary kernel commits are: + * + * Mainline Linux: + * e110861 net: add a sysctl to reflect the fwmark on replies + * 1b3c61d net: Use fwmark reflection in PMTU discovery. + * 84f39b0 net: support marking accepting TCP sockets + * + * Common Android tree (e.g., 3.10): + * a03f539 net: ipv6: autoconf routes into per-device tables + */ + public void testProcSysctls() throws Exception { + for (String sysctl : GLOBAL_SYSCTLS) { + int value = readIntFromPath(sysctl); + assertEquals(sysctl, 1, value); + } + + String interfaceDirs[] = mDevice.executeAdbCommand("shell", "ls", "-1", + IPV6_SYSCTL_DIR).split("\n"); + for (String interfaceDir : interfaceDirs) { + if (interfaceDir.equals("all") || interfaceDir.equals("lo")) { + continue; + } + String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + AUTOCONF_SYSCTL; + int value = readIntFromPath(path); + assertLess(path, value, 0); + } + } + + /** Verify that accept_ra_rt_info_{min,max}_plen exists and is set to the expected value */ + public void testAcceptRaRtInfoMinMaxPlen() throws Exception { + String interfaceDirs[] = mDevice.executeAdbCommand("shell", "ls", "-1", + IPV6_SYSCTL_DIR).split("\n"); + for (String interfaceDir : interfaceDirs) { + if (interfaceDir.equals("all") || interfaceDir.equals("lo")) { + continue; + } + String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "accept_ra_rt_info_min_plen"; + int value = readIntFromPath(path); + assertEquals(path, value, ACCEPT_RA_RT_INFO_MIN_PLEN_VALUE); + path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "accept_ra_rt_info_max_plen"; + value = readIntFromPath(path); + assertEquals(path, value, ACCEPT_RA_RT_INFO_MAX_PLEN_VALUE); + } + } + + /** + * Verify that router_solicitations exists and is set to the expected value + * and verify that router_solicitation_max_interval exists and is in an acceptable interval. + */ + public void testRouterSolicitations() throws Exception { + String interfaceDirs[] = mDevice.executeAdbCommand("shell", "ls", "-1", + IPV6_SYSCTL_DIR).split("\n"); + for (String interfaceDir : interfaceDirs) { + if (interfaceDir.equals("all") || interfaceDir.equals("lo")) { + continue; + } + String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitations"; + int value = readIntFromPath(path); + assertEquals(IPV6_WIFI_ROUTER_SOLICITATIONS, value); + path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitation_max_interval"; + int interval = readIntFromPath(path); + final int lowerBoundSec = 15 * 60; + final int upperBoundSec = 60 * 60; + assertTrue(lowerBoundSec <= interval); + assertTrue(interval <= upperBoundSec); + } + } +} diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 441bee3e5c..6e4f34ecf7 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -107,17 +107,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { "Host: " + TEST_HOST + "\r\n" + "Connection: keep-alive\r\n\r\n"; - // Base path for IPv6 sysctls - private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf"; - - // Expected values for MIN|MAX_PLEN. - private static final int IPV6_WIFI_ACCEPT_RA_RT_INFO_MIN_PLEN = 48; - private static final int IPV6_WIFI_ACCEPT_RA_RT_INFO_MAX_PLEN = 64; - - // Expected values for RFC 7559 router soliciations. - // Maximum number of router solicitations to send. -1 means no limit. - private static final int IPV6_WIFI_ROUTER_SOLICITATIONS = -1; - // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. private static final String NETWORK_CALLBACK_ACTION = "ConnectivityManagerTest.NetworkCallbackAction"; @@ -908,60 +897,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { } catch (SecurityException expected) {} } - private Scanner makeWifiSysctlScanner(String key) throws FileNotFoundException { - Network network = ensureWifiConnected(); - String iface = mCm.getLinkProperties(network).getInterfaceName(); - String path = IPV6_SYSCTL_DIR + "/" + iface + "/" + key; - return new Scanner(new File(path)); - } - - /** Verify that accept_ra_rt_info_min_plen exists and is set to the expected value */ - public void testAcceptRaRtInfoMinPlen() throws Exception { - if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { - Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi"); - return; - } - Scanner s = makeWifiSysctlScanner("accept_ra_rt_info_min_plen"); - assertEquals(IPV6_WIFI_ACCEPT_RA_RT_INFO_MIN_PLEN, s.nextInt()); - } - - /** Verify that accept_ra_rt_info_max_plen exists and is set to the expected value */ - public void testAcceptRaRtInfoMaxPlen() throws Exception { - if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { - Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi"); - return; - } - Scanner s = makeWifiSysctlScanner("accept_ra_rt_info_max_plen"); - assertEquals(IPV6_WIFI_ACCEPT_RA_RT_INFO_MAX_PLEN, s.nextInt()); - } - - /** Verify that router_solicitations exists and is set to the expected value */ - public void testRouterSolicitations() throws Exception { - if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { - Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi"); - return; - } - Scanner s = makeWifiSysctlScanner("router_solicitations"); - assertEquals(IPV6_WIFI_ROUTER_SOLICITATIONS, s.nextInt()); - } - - /** Verify that router_solicitation_max_interval exists and is in an acceptable interval */ - public void testRouterSolicitationMaxInterval() throws Exception { - if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { - Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi"); - return; - } - Scanner s = makeWifiSysctlScanner("router_solicitation_max_interval"); - int interval = s.nextInt(); - // Verify we're in the interval [15 minutes, 60 minutes]. Lower values may adversely - // impact battery life and higher values can decrease the probability of detecting - // network changes. - final int lowerBoundSec = 15 * 60; - final int upperBoundSec = 60 * 60; - assertTrue(lowerBoundSec <= interval); - assertTrue(interval <= upperBoundSec); - } - // Returns "true", "false" or "none" private String getWifiMeteredStatus(String ssid) throws Exception { // Interestingly giving the SSID as an argument to list wifi-networks diff --git a/tests/cts/net/src/android/net/cts/IpSecSysctlTest.java b/tests/cts/net/src/android/net/cts/IpSecSysctlTest.java deleted file mode 100644 index b362282c89..0000000000 --- a/tests/cts/net/src/android/net/cts/IpSecSysctlTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2018 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.cts; - -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.system.StructStat; -import android.test.AndroidTestCase; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.IOException; - -/** - * Tests for multinetwork sysctl functionality. - */ -public class IpSecSysctlTest extends SysctlBaseTest { - - // SPI expiration sysctls. Must be present and set greater than 1h. - private static final String SPI_TIMEOUT_SYSCTL = "/proc/sys/net/core/xfrm_acq_expires"; - private static final int MIN_ACQ_EXPIRES = 3600; - - /** - * Checks that SPI default timeouts are overridden, and set to a reasonable length of time - */ - public void testProcFiles() throws ErrnoException, IOException, NumberFormatException { - int value = getIntValue(SPI_TIMEOUT_SYSCTL); - assertAtLeast(SPI_TIMEOUT_SYSCTL, value, MIN_ACQ_EXPIRES); - } -} diff --git a/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java b/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java deleted file mode 100644 index 1d0c111fd6..0000000000 --- a/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2014 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.cts; - -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.system.StructStat; -import android.test.AndroidTestCase; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.IOException; - -/** - * Tests for multinetwork sysctl functionality. - */ -public class MultinetworkSysctlTest extends SysctlBaseTest { - - // Global sysctls. Must be present and set to 1. - private static final String[] GLOBAL_SYSCTLS = { - "/proc/sys/net/ipv4/fwmark_reflect", - "/proc/sys/net/ipv6/fwmark_reflect", - "/proc/sys/net/ipv4/tcp_fwmark_accept", - }; - - // Per-interface IPv6 autoconf sysctls. - private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf"; - private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table"; - - /** - * Checks that the sysctls for multinetwork kernel features are present and - * enabled. The necessary kernel commits are: - * - * Mainline Linux: - * e110861 net: add a sysctl to reflect the fwmark on replies - * 1b3c61d net: Use fwmark reflection in PMTU discovery. - * 84f39b0 net: support marking accepting TCP sockets - * - * Common Android tree (e.g., 3.10): - * a03f539 net: ipv6: autoconf routes into per-device tables - */ - public void testProcFiles() throws ErrnoException, IOException, NumberFormatException { - for (String sysctl : GLOBAL_SYSCTLS) { - int value = getIntValue(sysctl); - assertEquals(sysctl, 1, value); - } - - File[] interfaceDirs = new File(IPV6_SYSCTL_DIR).listFiles(); - for (File interfaceDir : interfaceDirs) { - if (interfaceDir.getName().equals("all") || interfaceDir.getName().equals("lo")) { - continue; - } - String sysctl = new File(interfaceDir, AUTOCONF_SYSCTL).getAbsolutePath(); - int value = getIntValue(sysctl); - assertLess(sysctl, value, 0); - } - } -} diff --git a/tests/cts/net/src/android/net/cts/SysctlBaseTest.java b/tests/cts/net/src/android/net/cts/SysctlBaseTest.java deleted file mode 100644 index a5966d48d3..0000000000 --- a/tests/cts/net/src/android/net/cts/SysctlBaseTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2018 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.cts; - -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.system.StructStat; -import android.test.AndroidTestCase; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.IOException; - -/** - * Tests for multinetwork sysctl functionality. - */ -public class SysctlBaseTest extends AndroidTestCase { - - // Expected mode, UID, and GID of sysctl files. - private static final int SYSCTL_MODE = 0100644; - private static final int SYSCTL_UID = 0; - private static final int SYSCTL_GID = 0; - - private void checkSysctlPermissions(String fileName) throws ErrnoException { - StructStat stat = Os.stat(fileName); - assertEquals("mode of " + fileName + ":", SYSCTL_MODE, stat.st_mode); - assertEquals("UID of " + fileName + ":", SYSCTL_UID, stat.st_uid); - assertEquals("GID of " + fileName + ":", SYSCTL_GID, stat.st_gid); - } - - protected void assertLess(String sysctl, int a, int b) { - assertTrue("value of " + sysctl + ": expected < " + b + " but was: " + a, a < b); - } - - protected void assertAtLeast(String sysctl, int a, int b) { - assertTrue("value of " + sysctl + ": expected >= " + b + " but was: " + a, a >= b); - } - - private String readFile(String fileName) throws ErrnoException, IOException { - byte[] buf = new byte[1024]; - FileDescriptor fd = Os.open(fileName, 0, OsConstants.O_RDONLY); - int bytesRead = Os.read(fd, buf, 0, buf.length); - assertLess("length of " + fileName + ":", bytesRead, buf.length); - return new String(buf); - } - - /* - * Checks permissions and retrieves the sysctl's value. Retrieval of value should always use - * this method - */ - protected int getIntValue(String filename) throws ErrnoException, IOException { - checkSysctlPermissions(filename); - return Integer.parseInt(readFile(filename).trim()); - } -}